Merge branch 'pybind:master' into master

This commit is contained in:
Steve R. Sun 2024-07-31 09:08:18 +08:00 committed by GitHub
commit 64c871ef4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 45 additions and 91 deletions

View File

@ -311,11 +311,6 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
clang: clang:
- 3.6
- 3.7
- 3.9
- 7
- 9
- dev - dev
std: std:
- 11 - 11
@ -324,8 +319,6 @@ jobs:
include: include:
- clang: 5 - clang: 5
std: 14 std: 14
- clang: 10
std: 17
- clang: 11 - clang: 11
std: 20 std: 20
- clang: 12 - clang: 12
@ -503,10 +496,6 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- { gcc: 7, std: 11 }
- { gcc: 7, std: 17 }
- { gcc: 8, std: 14 }
- { gcc: 8, std: 17 }
- { gcc: 9, std: 20 } - { gcc: 9, std: 20 }
- { gcc: 10, std: 17 } - { gcc: 10, std: 17 }
- { gcc: 10, std: 20 } - { gcc: 10, std: 20 }
@ -727,9 +716,9 @@ jobs:
# This tests an "install" with the CMake tools # This tests an "install" with the CMake tools
install-classic: install-classic:
name: "🐍 3.7 • Debian • x86 • Install" name: "🐍 3.9 • Debian • x86 • Install"
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: i386/debian:buster container: i386/debian:bullseye
steps: steps:
- uses: actions/checkout@v1 # v1 is required to run inside docker - uses: actions/checkout@v1 # v1 is required to run inside docker
@ -809,7 +798,6 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
python: python:
- '3.7'
- '3.8' - '3.8'
- '3.9' - '3.9'
- '3.10' - '3.10'
@ -827,8 +815,6 @@ jobs:
args: -DCMAKE_CXX_STANDARD=20 args: -DCMAKE_CXX_STANDARD=20
- python: '3.8' - python: '3.8'
args: -DCMAKE_CXX_STANDARD=17 args: -DCMAKE_CXX_STANDARD=17
- python: '3.7'
args: -DCMAKE_CXX_STANDARD=14
name: "🐍 ${{ matrix.python }} • MSVC 2019 • x86 ${{ matrix.args }}" name: "🐍 ${{ matrix.python }} • MSVC 2019 • x86 ${{ matrix.args }}"

View File

@ -39,22 +39,22 @@ jobs:
- runs-on: macos-13 - runs-on: macos-13
arch: x64 arch: x64
cmake: "3.7" cmake: "3.8"
- runs-on: windows-2019 - runs-on: windows-2019
arch: x64 # x86 compilers seem to be missing on 2019 image arch: x64 # x86 compilers seem to be missing on 2019 image
cmake: "3.18" cmake: "3.18"
name: 🐍 3.7 • CMake ${{ matrix.cmake }} • ${{ matrix.runs-on }} name: 🐍 3.8 • CMake ${{ matrix.cmake }} • ${{ matrix.runs-on }}
runs-on: ${{ matrix.runs-on }} runs-on: ${{ matrix.runs-on }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Setup Python 3.7 - name: Setup Python 3.8
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: 3.7 python-version: 3.8
architecture: ${{ matrix.arch }} architecture: ${{ matrix.arch }}
- name: Prepare env - name: Prepare env

View File

@ -34,7 +34,7 @@ dependency.
Think of this library as a tiny self-contained version of Boost.Python Think of this library as a tiny self-contained version of Boost.Python
with everything stripped away that isn't relevant for binding with everything stripped away that isn't relevant for binding
generation. Without comments, the core header files only require ~4K generation. Without comments, the core header files only require ~4K
lines of code and depend on Python (3.7+, or PyPy) and the C++ lines of code and depend on Python (3.8+, or PyPy) and the C++
standard library. This compact implementation was possible thanks to standard library. This compact implementation was possible thanks to
some C++11 language features (specifically: tuples, lambda functions and some C++11 language features (specifically: tuples, lambda functions and
variadic templates). Since its creation, this library has grown beyond variadic templates). Since its creation, this library has grown beyond
@ -79,7 +79,7 @@ Goodies
In addition to the core functionality, pybind11 provides some extra In addition to the core functionality, pybind11 provides some extra
goodies: goodies:
- Python 3.7+, and PyPy3 7.3 are supported with an implementation-agnostic - Python 3.8+, and PyPy3 7.3 are supported with an implementation-agnostic
interface (pybind11 2.9 was the last version to support Python 2 and 3.5). interface (pybind11 2.9 was the last version to support Python 2 and 3.5).
- It is possible to bind C++11 lambda functions with captured - It is possible to bind C++11 lambda functions with captured

View File

@ -826,8 +826,7 @@ An instance can now be pickled as follows:
always use the latest available version. Beware: failure to follow these always use the latest available version. Beware: failure to follow these
instructions will cause important pybind11 memory allocation routines to be instructions will cause important pybind11 memory allocation routines to be
skipped during unpickling, which will likely lead to memory corruption skipped during unpickling, which will likely lead to memory corruption
and/or segmentation faults. Python defaults to version 3 (Python 3-3.7) and and/or segmentation faults.
version 4 for Python 3.8+.
.. seealso:: .. seealso::

View File

@ -368,8 +368,7 @@ Should they throw or fail to catch any exceptions in their call graph,
the C++ runtime calls ``std::terminate()`` to abort immediately. the C++ runtime calls ``std::terminate()`` to abort immediately.
Similarly, Python exceptions raised in a class's ``__del__`` method do not Similarly, Python exceptions raised in a class's ``__del__`` method do not
propagate, but are logged by Python as an unraisable error. In Python 3.8+, a propagate, but ``sys.unraisablehook()`` `is triggered
`system hook is triggered
<https://docs.python.org/3/library/sys.html#sys.unraisablehook>`_ <https://docs.python.org/3/library/sys.html#sys.unraisablehook>`_
and an auditing event is logged. and an auditing event is logged.

View File

@ -426,7 +426,7 @@ with ``PYTHON_EXECUTABLE``. For example:
.. code-block:: bash .. code-block:: bash
cmake -DPYBIND11_PYTHON_VERSION=3.7 .. cmake -DPYBIND11_PYTHON_VERSION=3.8 ..
# Another method: # Another method:
cmake -DPYTHON_EXECUTABLE=/path/to/python .. cmake -DPYTHON_EXECUTABLE=/path/to/python ..
@ -493,7 +493,7 @@ existing targets instead:
cmake_minimum_required(VERSION 3.15...3.22) cmake_minimum_required(VERSION 3.15...3.22)
project(example LANGUAGES CXX) project(example LANGUAGES CXX)
find_package(Python 3.7 COMPONENTS Interpreter Development REQUIRED) find_package(Python 3.8 COMPONENTS Interpreter Development REQUIRED)
find_package(pybind11 CONFIG REQUIRED) find_package(pybind11 CONFIG REQUIRED)
# or add_subdirectory(pybind11) # or add_subdirectory(pybind11)

View File

@ -158,7 +158,7 @@ public:
} else { } else {
handle src_or_index = src; handle src_or_index = src;
// PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls. // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION) #if defined(PYPY_VERSION)
object index; object index;
if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr())
index = reinterpret_steal<object>(PyNumber_Index(src.ptr())); index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));
@ -1503,7 +1503,7 @@ struct kw_only {};
/// \ingroup annotations /// \ingroup annotations
/// Annotation indicating that all previous arguments are positional-only; the is the equivalent of /// Annotation indicating that all previous arguments are positional-only; the is the equivalent of
/// an unnamed '/' argument (in Python 3.8) /// an unnamed '/' argument
struct pos_only {}; struct pos_only {};
template <typename T> template <typename T>

View File

@ -466,19 +466,9 @@ extern "C" inline void pybind11_object_dealloc(PyObject *self) {
type->tp_free(self); type->tp_free(self);
#if PY_VERSION_HEX < 0x03080000
// `type->tp_dealloc != pybind11_object_dealloc` means that we're being called
// as part of a derived type's dealloc, in which case we're not allowed to decref
// the type here. For cross-module compatibility, we shouldn't compare directly
// with `pybind11_object_dealloc`, but with the common one stashed in internals.
auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;
if (type->tp_dealloc == pybind11_object_type->tp_dealloc)
Py_DECREF(type);
#else
// This was not needed before Python 3.8 (Python issue 35810) // This was not needed before Python 3.8 (Python issue 35810)
// https://github.com/pybind/pybind11/issues/1946 // https://github.com/pybind/pybind11/issues/1946
Py_DECREF(type); Py_DECREF(type);
#endif
} }
std::string error_string(); std::string error_string();

View File

@ -272,8 +272,8 @@ PYBIND11_WARNING_DISABLE_MSVC(4505)
#endif #endif
#include <Python.h> #include <Python.h>
#if PY_VERSION_HEX < 0x03070000 #if PY_VERSION_HEX < 0x03080000
# error "PYTHON < 3.7 IS UNSUPPORTED. pybind11 v2.12 was the last to support Python 3.6." # error "PYTHON < 3.8 IS UNSUPPORTED. pybind11 v2.13 was the last to support Python 3.7."
#endif #endif
#include <frameobject.h> #include <frameobject.h>
#include <pythread.h> #include <pythread.h>

View File

@ -447,7 +447,7 @@ inline void translate_local_exception(std::exception_ptr p) {
inline object get_python_state_dict() { inline object get_python_state_dict() {
object state_dict; object state_dict;
#if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION) #if PYBIND11_INTERNALS_VERSION <= 4 || defined(PYPY_VERSION)
state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins()); state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
#else #else
# if PY_VERSION_HEX < 0x03090000 # if PY_VERSION_HEX < 0x03090000

View File

@ -104,23 +104,13 @@ inline void initialize_interpreter_pre_pyconfig(bool init_signal_handlers,
detail::precheck_interpreter(); detail::precheck_interpreter();
Py_InitializeEx(init_signal_handlers ? 1 : 0); Py_InitializeEx(init_signal_handlers ? 1 : 0);
// Before it was special-cased in python 3.8, passing an empty or null argv
// caused a segfault, so we have to reimplement the special case ourselves.
bool special_case = (argv == nullptr || argc <= 0);
const char *const empty_argv[]{"\0"};
const char *const *safe_argv = special_case ? empty_argv : argv;
if (special_case) {
argc = 1;
}
auto argv_size = static_cast<size_t>(argc); auto argv_size = static_cast<size_t>(argc);
// SetArgv* on python 3 takes wchar_t, so we have to convert. // SetArgv* on python 3 takes wchar_t, so we have to convert.
std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]); std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);
std::vector<std::unique_ptr<wchar_t[], detail::wide_char_arg_deleter>> widened_argv_entries; std::vector<std::unique_ptr<wchar_t[], detail::wide_char_arg_deleter>> widened_argv_entries;
widened_argv_entries.reserve(argv_size); widened_argv_entries.reserve(argv_size);
for (size_t ii = 0; ii < argv_size; ++ii) { for (size_t ii = 0; ii < argv_size; ++ii) {
widened_argv_entries.emplace_back(detail::widen_chars(safe_argv[ii])); widened_argv_entries.emplace_back(detail::widen_chars(argv[ii]));
if (!widened_argv_entries.back()) { if (!widened_argv_entries.back()) {
// A null here indicates a character-encoding failure or the python // A null here indicates a character-encoding failure or the python
// interpreter out of memory. Give up. // interpreter out of memory. Give up.

View File

@ -19,7 +19,7 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
inline void ensure_builtins_in_globals(object &global) { inline void ensure_builtins_in_globals(object &global) {
#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000 #if defined(PYPY_VERSION)
// Running exec and eval adds `builtins` module under `__builtins__` key to // Running exec and eval adds `builtins` module under `__builtins__` key to
// globals if not yet present. Python 3.8 made PyRun_String behave // globals if not yet present. Python 3.8 made PyRun_String behave
// similarly. Let's also do that for older versions, for consistency. This // similarly. Let's also do that for older versions, for consistency. This

View File

@ -147,9 +147,7 @@ public:
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer) // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
tstate = PyEval_SaveThread(); tstate = PyEval_SaveThread();
if (disassoc) { if (disassoc) {
// Python >= 3.7 can remove this, it's an int before 3.7 auto key = internals.tstate; // NOLINT(readability-qualified-auto)
// NOLINTNEXTLINE(readability-qualified-auto)
auto key = internals.tstate;
PYBIND11_TLS_DELETE_VALUE(key); PYBIND11_TLS_DELETE_VALUE(key);
} }
} }
@ -173,9 +171,7 @@ public:
PyEval_RestoreThread(tstate); PyEval_RestoreThread(tstate);
} }
if (disassoc) { if (disassoc) {
// Python >= 3.7 can remove this, it's an int before 3.7 auto key = detail::get_internals().tstate; // NOLINT(readability-qualified-auto)
// NOLINTNEXTLINE(readability-qualified-auto)
auto key = detail::get_internals().tstate;
PYBIND11_TLS_REPLACE_VALUE(key, tstate); PYBIND11_TLS_REPLACE_VALUE(key, tstate);
} }
} }

View File

@ -2,8 +2,8 @@ from __future__ import annotations
import sys import sys
if sys.version_info < (3, 7): # noqa: UP036 if sys.version_info < (3, 8): # noqa: UP036
msg = "pybind11 does not support Python < 3.7. v2.12 was the last release supporting Python 3.6." msg = "pybind11 does not support Python < 3.8. v2.13 was the last release supporting Python 3.7."
raise ImportError(msg) raise ImportError(msg)

View File

@ -249,7 +249,7 @@ def has_flag(compiler: Any, flag: str) -> bool:
cpp_flag_cache = None cpp_flag_cache = None
@lru_cache() @lru_cache
def auto_cpp_level(compiler: Any) -> str | int: def auto_cpp_level(compiler: Any) -> str | int:
""" """
Return the max supported C++ std level (17, 14, or 11). Returns latest on Windows. Return the max supported C++ std level (17, 14, or 11). Returns latest on Windows.

View File

@ -30,7 +30,7 @@ ignore_missing_imports = true
[tool.pylint] [tool.pylint]
master.py-version = "3.7" master.py-version = "3.8"
reports.output-format = "colorized" reports.output-format = "colorized"
messages_control.disable = [ messages_control.disable = [
"design", "design",
@ -45,7 +45,7 @@ messages_control.disable = [
] ]
[tool.ruff] [tool.ruff]
target-version = "py37" target-version = "py38"
src = ["src"] src = ["src"]
[tool.ruff.lint] [tool.ruff.lint]

View File

@ -14,7 +14,6 @@ classifiers =
Topic :: Utilities Topic :: Utilities
Programming Language :: C++ Programming Language :: C++
Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.10
@ -39,5 +38,5 @@ project_urls =
Chat = https://gitter.im/pybind/Lobby Chat = https://gitter.im/pybind/Lobby
[options] [options]
python_requires = >=3.7 python_requires = >=3.8
zip_safe = False zip_safe = False

View File

@ -1,9 +1,8 @@
--only-binary=:all: --only-binary=:all:
build~=1.0; python_version>="3.7" build~=1.0; python_version>="3.8"
numpy~=1.20.0; python_version=="3.7" and platform_python_implementation=="PyPy"
numpy~=1.23.0; python_version=="3.8" and platform_python_implementation=="PyPy" numpy~=1.23.0; python_version=="3.8" and platform_python_implementation=="PyPy"
numpy~=1.25.0; python_version=="3.9" and platform_python_implementation=='PyPy' numpy~=1.25.0; python_version=="3.9" and platform_python_implementation=='PyPy'
numpy~=1.21.5; platform_python_implementation!="PyPy" and python_version>="3.7" and python_version<"3.10" numpy~=1.21.5; platform_python_implementation!="PyPy" and python_version>="3.8" and python_version<"3.10"
numpy~=1.22.2; platform_python_implementation!="PyPy" and python_version=="3.10" numpy~=1.22.2; platform_python_implementation!="PyPy" and python_version=="3.10"
numpy~=1.26.0; platform_python_implementation!="PyPy" and python_version>="3.11" and python_version<"3.13" numpy~=1.26.0; platform_python_implementation!="PyPy" and python_version>="3.11" and python_version<"3.13"
pytest~=7.0 pytest~=7.0

View File

@ -297,7 +297,7 @@ def test_int_convert():
cant_convert(3.14159) cant_convert(3.14159)
# TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar) # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
# TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7) # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON: if sys.version_info < (3, 10) and env.CPYTHON:
with env.deprecated_call(): with env.deprecated_call():
assert convert(Int()) == 42 assert convert(Int()) == 42
else: else:

View File

@ -103,28 +103,24 @@ def ignore_pytest_unraisable_warning(f):
@pytest.mark.xfail(env.PYPY, reason="Failure on PyPy 3.8 (7.3.7)", strict=False) @pytest.mark.xfail(env.PYPY, reason="Failure on PyPy 3.8 (7.3.7)", strict=False)
@ignore_pytest_unraisable_warning @ignore_pytest_unraisable_warning
def test_python_alreadyset_in_destructor(monkeypatch, capsys): def test_python_alreadyset_in_destructor(monkeypatch, capsys):
hooked = False
triggered = False triggered = False
if hasattr(sys, "unraisablehook"): # Python 3.8+ # Don't take `sys.unraisablehook`, as that's overwritten by pytest
hooked = True default_hook = sys.__unraisablehook__
# Don't take `sys.unraisablehook`, as that's overwritten by pytest
default_hook = sys.__unraisablehook__
def hook(unraisable_hook_args): def hook(unraisable_hook_args):
exc_type, exc_value, exc_tb, err_msg, obj = unraisable_hook_args exc_type, exc_value, exc_tb, err_msg, obj = unraisable_hook_args
if obj == "already_set demo": if obj == "already_set demo":
nonlocal triggered nonlocal triggered
triggered = True triggered = True
default_hook(unraisable_hook_args) default_hook(unraisable_hook_args)
return return
# Use monkeypatch so pytest can apply and remove the patch as appropriate # Use monkeypatch so pytest can apply and remove the patch as appropriate
monkeypatch.setattr(sys, "unraisablehook", hook) monkeypatch.setattr(sys, "unraisablehook", hook)
assert m.python_alreadyset_in_destructor("already_set demo") is True assert m.python_alreadyset_in_destructor("already_set demo") is True
if hooked: assert triggered is True
assert triggered is True
_, captured_stderr = capsys.readouterr() _, captured_stderr = capsys.readouterr()
assert captured_stderr.startswith("Exception ignored in: 'already_set demo'") assert captured_stderr.startswith("Exception ignored in: 'already_set demo'")

View File

@ -92,7 +92,7 @@ endif()
# Use the Python interpreter to find the libs. # Use the Python interpreter to find the libs.
if(NOT PythonLibsNew_FIND_VERSION) if(NOT PythonLibsNew_FIND_VERSION)
set(PythonLibsNew_FIND_VERSION "3.7") set(PythonLibsNew_FIND_VERSION "3.8")
endif() endif()
if(NOT CMAKE_VERSION VERSION_LESS "3.27") if(NOT CMAKE_VERSION VERSION_LESS "3.27")

View File

@ -56,7 +56,7 @@ if(NOT Python_FOUND AND NOT Python3_FOUND)
endif() endif()
find_package( find_package(
Python 3.7 REQUIRED COMPONENTS ${_pybind11_interp_component} ${_pybind11_dev_component} Python 3.8 REQUIRED COMPONENTS ${_pybind11_interp_component} ${_pybind11_dev_component}
${_pybind11_quiet} ${_pybind11_global_keyword}) ${_pybind11_quiet} ${_pybind11_global_keyword})
# If we are in submodule mode, export the Python targets to global targets. # If we are in submodule mode, export the Python targets to global targets.

View File

@ -43,7 +43,7 @@ endif()
# A user can set versions manually too # A user can set versions manually too
set(Python_ADDITIONAL_VERSIONS set(Python_ADDITIONAL_VERSIONS
"3.12;3.11;3.10;3.9;3.8;3.7" "3.12;3.11;3.10;3.9;3.8"
CACHE INTERNAL "") CACHE INTERNAL "")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")