From 061c617707015883b95e11068ffe97fb73d501ec Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Feb 2022 21:35:43 -0500 Subject: [PATCH 1/7] [pre-commit.ci] pre-commit autoupdate (#3765) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/Lucas-C/pre-commit-hooks: v1.1.12 → v1.1.13](https://github.com/Lucas-C/pre-commit-hooks/compare/v1.1.12...v1.1.13) - [github.com/hadialqattan/pycln: v1.2.0 → v1.2.4](https://github.com/hadialqattan/pycln/compare/v1.2.0...v1.2.4) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 052420549..e9a0e03f2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -59,7 +59,7 @@ repos: # Changes tabs to spaces - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: "v1.1.12" + rev: "v1.1.13" hooks: - id: remove-tabs @@ -71,7 +71,7 @@ repos: # Autoremoves unused imports - repo: https://github.com/hadialqattan/pycln - rev: "v1.2.0" + rev: "v1.2.4" hooks: - id: pycln From 5f9b090a915fbaa5904c6bd4a24f888f2ff55db7 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 1 Mar 2022 12:42:52 -0500 Subject: [PATCH 2/7] ci: fix PyPy (#3768) * chore: minor fixes for newer PyPys * ci: fix issue with PyPy --- .github/workflows/ci.yml | 4 ++-- include/pybind11/detail/class.h | 14 +++++++------- include/pybind11/pybind11.h | 2 +- noxfile.py | 9 ++++----- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e138550aa..179caa9e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,8 +30,8 @@ jobs: - '3.6' - '3.9' - '3.10' - - 'pypy-3.7-v7.3.7' - - 'pypy-3.8-v7.3.7' + - 'pypy-3.7' + - 'pypy-3.8' # Items in here will either be added to the build matrix (if not # present), or add new keys to an existing matrix element if all the diff --git a/include/pybind11/detail/class.h b/include/pybind11/detail/class.h index ebdc07271..e52ec1d3e 100644 --- a/include/pybind11/detail/class.h +++ b/include/pybind11/detail/class.h @@ -101,14 +101,14 @@ inline PyTypeObject *make_static_property_type() { inline PyTypeObject *make_static_property_type() { auto d = dict(); PyObject *result = PyRun_String(R"(\ - class pybind11_static_property(property): - def __get__(self, obj, cls): - return property.__get__(self, cls, cls) +class pybind11_static_property(property): + def __get__(self, obj, cls): + return property.__get__(self, cls, cls) - def __set__(self, obj, value): - cls = obj if isinstance(obj, type) else type(obj) - property.__set__(self, cls, value) - )", + def __set__(self, obj, value): + cls = obj if isinstance(obj, type) else type(obj) + property.__set__(self, cls, value) +)", Py_file_input, d.ptr(), d.ptr()); diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 22b629f40..1ec6c17c6 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -334,7 +334,7 @@ protected: const std::type_info *const *types, size_t args) { // Do NOT receive `unique_rec` by value. If this function fails to move out the unique_ptr, - // we do not want this to destuct the pointer. `initialize` (the caller) still relies on + // we do not want this to destruct the pointer. `initialize` (the caller) still relies on // the pointee being alive after this call. Only move out if a `capsule` is going to keep // it alive. auto *rec = unique_rec.get(); diff --git a/noxfile.py b/noxfile.py index 50b7e4ee0..341d964e9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -2,6 +2,7 @@ import os import nox +nox.needs_version = ">=2022.1.7" nox.options.sessions = ["lint", "tests", "tests_packaging"] PYTHON_VERISONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy3.7", "pypy3.8"] @@ -29,14 +30,12 @@ def tests(session: nox.Session) -> None: session.install("-r", "tests/requirements.txt") session.run( "cmake", - "-S", - ".", - "-B", - tmpdir, + "-S.", + f"-B{tmpdir}", "-DPYBIND11_WERROR=ON", "-DDOWNLOAD_CATCH=ON", "-DDOWNLOAD_EIGEN=ON", - *session.posargs + *session.posargs, ) session.run("cmake", "--build", tmpdir) session.run("cmake", "--build", tmpdir, "--config=Release", "--target", "check") From 465b2e0bd8e25445b8892abfd422457ea275d713 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 1 Mar 2022 10:47:10 -0800 Subject: [PATCH 3/7] Use sysconfig in Python >= 3.10 (#3764) * Use sysconfig in Python >= 3.10 Rely on sysconfig for installation paths for Python >= 3.10. distutils has been deprecated and will be removed. Fixes: #3677 * Explicitly select the posix_prefix scheme for platinclude on Debian Debian's default scheme is posix_local, for installing locally-built packages to /usr/local/. We want to find the Python headers in /usr/, so search posix_prefix. --- tools/FindPythonLibsNew.cmake | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tools/FindPythonLibsNew.cmake b/tools/FindPythonLibsNew.cmake index 7aeffa441..6ad5fe157 100644 --- a/tools/FindPythonLibsNew.cmake +++ b/tools/FindPythonLibsNew.cmake @@ -112,11 +112,24 @@ endif() # VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows. execute_process( COMMAND - "${PYTHON_EXECUTABLE}" "-c" "from distutils import sysconfig as s;import sys;import struct; + "${PYTHON_EXECUTABLE}" "-c" " +import sys;import struct; +import sysconfig as s +USE_SYSCONFIG = sys.version_info >= (3, 10) +if not USE_SYSCONFIG: + from distutils import sysconfig as ds print('.'.join(str(v) for v in sys.version_info)); print(sys.prefix); -print(s.get_python_inc(plat_specific=True)); -print(s.get_python_lib(plat_specific=True)); +if USE_SYSCONFIG: + scheme = s.get_default_scheme() + if scheme == 'posix_local': + # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ + scheme = 'posix_prefix' + print(s.get_path('platinclude', scheme)) + print(s.get_path('platlib')) +else: + print(ds.get_python_inc(plat_specific=True)); + print(ds.get_python_lib(plat_specific=True)); print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO')); print(hasattr(sys, 'gettotalrefcount')+0); print(struct.calcsize('@P')); From 42a8e3125348d4e706e46eb410befc1422d42b3f Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Wed, 2 Mar 2022 13:17:52 -0500 Subject: [PATCH 4/7] Improve Python 3.11 support (#3694) * Test out Python 3.11 migration * Clean up a bit * Remove todo * Test workaround * Fix potential bug uncovered in 3.11 * Try to fix it more * last ditch fix * Revert. Tp-traverse isn't the problem * Test workaround * Try this hack * Revert MRO changes * Use f_back properly * Qualify auto * Update include/pybind11/pybind11.h * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Simplify code slightly * Ensure co_varnames decref if dict_getitem throws * Eager decref f_code Co-authored-by: Henry Schreiner Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- include/pybind11/detail/type_caster_base.h | 12 ++++++++++-- include/pybind11/pybind11.h | 12 ++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index ff7d7cf8c..a4154136a 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -502,9 +502,10 @@ PYBIND11_NOINLINE std::string error_string() { } PyFrameObject *frame = trace->tb_frame; + Py_XINCREF(frame); errorString += "\n\nAt:\n"; while (frame) { -# if PY_VERSION_HEX >= 0x03090000 +# if PY_VERSION_HEX >= 0x030900B1 PyCodeObject *f_code = PyFrame_GetCode(frame); # else PyCodeObject *f_code = frame->f_code; @@ -514,8 +515,15 @@ PYBIND11_NOINLINE std::string error_string() { errorString += " " + handle(f_code->co_filename).cast() + "(" + std::to_string(lineno) + "): " + handle(f_code->co_name).cast() + "\n"; - frame = frame->f_back; Py_DECREF(f_code); +# if PY_VERSION_HEX >= 0x030900B1 + auto *b_frame = PyFrame_GetBack(frame); +# else + auto *b_frame = frame->f_back; + Py_XINCREF(b_frame); +# endif + Py_DECREF(frame); + frame = b_frame; } } #endif diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 1ec6c17c6..4f6b2cdf4 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -2636,9 +2636,7 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char * /* Don't call dispatch code if invoked from overridden function. Unfortunately this doesn't work on PyPy. */ -#if !defined(PYPY_VERSION) && PY_VERSION_HEX < 0x030B0000 - // TODO: Remove PyPy workaround for Python 3.11. - // Current API fails on 3.11 since co_varnames can be null. +#if !defined(PYPY_VERSION) # if PY_VERSION_HEX >= 0x03090000 PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get()); if (frame != nullptr) { @@ -2646,9 +2644,11 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char * // f_code is guaranteed to not be NULL if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) { PyObject *locals = PyEval_GetLocals(); - if (locals != nullptr && f_code->co_varnames != nullptr) { - PyObject *self_caller - = dict_getitem(locals, PyTuple_GET_ITEM(f_code->co_varnames, 0)); + if (locals != nullptr) { + PyObject *co_varnames = PyObject_GetAttrString((PyObject *) f_code, "co_varnames"); + PyObject *self_arg = PyTuple_GET_ITEM(co_varnames, 0); + Py_DECREF(co_varnames); + PyObject *self_caller = dict_getitem(locals, self_arg); if (self_caller == self.ptr()) { Py_DECREF(f_code); Py_DECREF(frame); From af08a95b5666cc1fcb6fc74254fd676940462947 Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Wed, 2 Mar 2022 14:14:52 -0500 Subject: [PATCH 5/7] fix: potential memory leak in pypy (#3774) --- include/pybind11/pybind11.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 4f6b2cdf4..422d534c1 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -2694,9 +2694,9 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char * d.ptr()); if (result == nullptr) throw error_already_set(); + Py_DECREF(result); if (d["self"].is_none()) return function(); - Py_DECREF(result); #endif return override; From 2dd52544942be4bef80811ef18c8fcf1d3c7e246 Mon Sep 17 00:00:00 2001 From: Aaron Gokaslan Date: Wed, 2 Mar 2022 15:25:43 -0500 Subject: [PATCH 6/7] fix: missing move in eval.h (#3775) --- include/pybind11/eval.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pybind11/eval.h b/include/pybind11/eval.h index c157a0095..bd5f981f5 100644 --- a/include/pybind11/eval.h +++ b/include/pybind11/eval.h @@ -82,7 +82,7 @@ template object eval(const char (&s)[N], object global = globals(), object local = object()) { /* Support raw string literals by removing common leading whitespace */ auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s); - return eval(expr, global, local); + return eval(expr, std::move(global), std::move(local)); } inline void exec(const str &expr, object global = globals(), object local = object()) { @@ -91,7 +91,7 @@ inline void exec(const str &expr, object global = globals(), object local = obje template void exec(const char (&s)[N], object global = globals(), object local = object()) { - eval(s, global, local); + eval(s, std::move(global), std::move(local)); } #if defined(PYPY_VERSION) From d75b353694709add8bc31a931e123f7736929c94 Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Thu, 10 Mar 2022 10:31:16 -0800 Subject: [PATCH 7/7] CI: MSVC Debug Build (#3784) --- .github/workflows/ci.yml | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 179caa9e8..11c93bafc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -755,6 +755,60 @@ jobs: - name: Python tests run: cmake --build build -t pytest + win32-debug: + strategy: + fail-fast: false + matrix: + python: + - 3.8 + - 3.9 + + include: + - python: 3.9 + args: -DCMAKE_CXX_STANDARD=20 + - python: 3.8 + args: -DCMAKE_CXX_STANDARD=17 + + name: "🐍 ${{ matrix.python }} • MSVC 2019 (Debug) • x86 ${{ matrix.args }}" + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v2 + + - name: Setup Python ${{ matrix.python }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + architecture: x86 + + - name: Update CMake + uses: jwlawson/actions-setup-cmake@v1.12 + + - name: Prepare MSVC + uses: ilammy/msvc-dev-cmd@v1.10.0 + with: + arch: x86 + + - name: Prepare env + run: | + python -m pip install -r tests/requirements.txt + + # First build - C++11 mode and inplace + - name: Configure ${{ matrix.args }} + run: > + cmake -S . -B build + -G "Visual Studio 16 2019" -A Win32 + -DCMAKE_BUILD_TYPE=Debug + -DPYBIND11_WERROR=ON + -DDOWNLOAD_CATCH=ON + -DDOWNLOAD_EIGEN=ON + ${{ matrix.args }} + - name: Build C++11 + run: cmake --build build --config Debug -j 2 + + - name: Python tests + run: cmake --build build --config Debug -t pytest + win32-msvc2017: name: "🐍 ${{ matrix.python }} • MSVC 2017 • x64" runs-on: windows-2016