From 1634f060f720b44fd37fd2cb86dc1db842fa6d63 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 10 May 2024 17:00:41 -0400 Subject: [PATCH 1/5] ci: add Python 3.13 Signed-off-by: Henry Schreiner --- .github/workflows/ci.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b481112f01..cf0d28b35e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,9 +34,8 @@ jobs: python: - '3.6' - '3.9' - - '3.10' - - '3.11' - '3.12' + - '3.13' - 'pypy-3.8' - 'pypy-3.9' - 'pypy-3.10' @@ -64,6 +63,15 @@ jobs: # Inject a couple Windows 2019 runs - runs-on: windows-2019 python: '3.9' + # Fill in a few macOS ARM + - runs-on: macos-14 + python: '3.9' + - runs-on: macos-14 + python: '3.12' + # Extra ubuntu latest job + - runs-on: ubuntu-latest + python: '3.11' + name: "🐍 ${{ matrix.python }} • ${{ matrix.runs-on }} • x64 ${{ matrix.args }}" runs-on: ${{ matrix.runs-on }} @@ -75,6 +83,7 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} + allow-prereleases: true - name: Setup Boost (Linux) # Can't use boost + define _ From fe8a3ce3d133f69582e8244b737456ff57559e55 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 23 May 2024 01:57:53 -0400 Subject: [PATCH 2/5] tests: run the gc for 3.13+ Signed-off-by: Henry Schreiner --- tests/test_factory_constructors.py | 4 ++++ tests/test_virtual_functions.py | 3 +++ 2 files changed, 7 insertions(+) diff --git a/tests/test_factory_constructors.py b/tests/test_factory_constructors.py index a9004cbf67..d10aecce1f 100644 --- a/tests/test_factory_constructors.py +++ b/tests/test_factory_constructors.py @@ -1,3 +1,4 @@ +import gc import re import pytest @@ -209,6 +210,7 @@ def get(self): assert ConstructorStats.detail_reg_inst() == n_inst + 3 assert [i.alive() for i in cstats] == [3, 3] del x, y, z + gc.collect() assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst @@ -288,9 +290,11 @@ def get(self): assert ConstructorStats.detail_reg_inst() == n_inst + 13 del a1, a2, b1, d1, e1, e2 + gc.collect() assert [i.alive() for i in cstats] == [7, 4] assert ConstructorStats.detail_reg_inst() == n_inst + 7 del b2, c1, c2, d2, f1, f2, g1 + gc.collect() assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst diff --git a/tests/test_virtual_functions.py b/tests/test_virtual_functions.py index c17af7df58..b1ac323e2e 100644 --- a/tests/test_virtual_functions.py +++ b/tests/test_virtual_functions.py @@ -1,3 +1,5 @@ +import gc + import pytest import env # noqa: F401 @@ -81,6 +83,7 @@ def get_string2(self): cstats = ConstructorStats.get(m.ExampleVirt) assert cstats.alive() == 3 del ex12, ex12p, ex12p2 + gc.collect() # Python 3.13 incremental gc needs this assert cstats.alive() == 0 assert cstats.values() == ["10", "11", "17"] assert cstats.copy_constructions == 0 From 3736792682e3d201afa80f99326edc9b4cee556d Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 23 May 2024 02:30:14 -0400 Subject: [PATCH 3/5] Revert "tests: run the gc for 3.13+" This reverts commit fe8a3ce3d133f69582e8244b737456ff57559e55. --- tests/test_factory_constructors.py | 4 ---- tests/test_virtual_functions.py | 3 --- 2 files changed, 7 deletions(-) diff --git a/tests/test_factory_constructors.py b/tests/test_factory_constructors.py index d10aecce1f..a9004cbf67 100644 --- a/tests/test_factory_constructors.py +++ b/tests/test_factory_constructors.py @@ -1,4 +1,3 @@ -import gc import re import pytest @@ -210,7 +209,6 @@ def get(self): assert ConstructorStats.detail_reg_inst() == n_inst + 3 assert [i.alive() for i in cstats] == [3, 3] del x, y, z - gc.collect() assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst @@ -290,11 +288,9 @@ def get(self): assert ConstructorStats.detail_reg_inst() == n_inst + 13 del a1, a2, b1, d1, e1, e2 - gc.collect() assert [i.alive() for i in cstats] == [7, 4] assert ConstructorStats.detail_reg_inst() == n_inst + 7 del b2, c1, c2, d2, f1, f2, g1 - gc.collect() assert [i.alive() for i in cstats] == [0, 0] assert ConstructorStats.detail_reg_inst() == n_inst diff --git a/tests/test_virtual_functions.py b/tests/test_virtual_functions.py index b1ac323e2e..c17af7df58 100644 --- a/tests/test_virtual_functions.py +++ b/tests/test_virtual_functions.py @@ -1,5 +1,3 @@ -import gc - import pytest import env # noqa: F401 @@ -83,7 +81,6 @@ def get_string2(self): cstats = ConstructorStats.get(m.ExampleVirt) assert cstats.alive() == 3 del ex12, ex12p, ex12p2 - gc.collect() # Python 3.13 incremental gc needs this assert cstats.alive() == 0 assert cstats.values() == ["10", "11", "17"] assert cstats.copy_constructions == 0 From 6851255e38d4dd0ed9c646ccbb8ae642ca1aa751 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 23 May 2024 02:31:02 -0400 Subject: [PATCH 4/5] ci: drop macos ARM for now, need pin updates Signed-off-by: Henry Schreiner --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf0d28b35e..eb6ee3bad6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,11 +63,6 @@ jobs: # Inject a couple Windows 2019 runs - runs-on: windows-2019 python: '3.9' - # Fill in a few macOS ARM - - runs-on: macos-14 - python: '3.9' - - runs-on: macos-14 - python: '3.12' # Extra ubuntu latest job - runs-on: ubuntu-latest python: '3.11' From 540bef2d2c9fb54fa7c1474ee1af959ce90f2b32 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 23 May 2024 16:36:01 -0400 Subject: [PATCH 5/5] fix: use Python 3.13 API if on 3.13 Signed-off-by: Henry Schreiner --- include/pybind11/pybind11.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 429d2138d1..1b890615e4 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1344,8 +1344,14 @@ using module = module_; /// Return a dictionary representing the global variables in the current execution frame, /// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded). inline dict globals() { +#if PY_VERSION_HEX >= 0x030d0000 + PyObject *p = PyEval_GetFrameGlobals(); + return p ? reinterpret_steal(p) + : reinterpret_borrow(module_::import("__main__").attr("__dict__").ptr()); +#else PyObject *p = PyEval_GetGlobals(); return reinterpret_borrow(p ? p : module_::import("__main__").attr("__dict__").ptr()); +#endif } template ()>> @@ -2770,7 +2776,12 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char * PyCodeObject *f_code = PyFrame_GetCode(frame); // f_code is guaranteed to not be NULL if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) { +# if PY_VERSION_HEX >= 0x030d0000 + PyObject *locals = PyEval_GetFrameLocals(); +# else PyObject *locals = PyEval_GetLocals(); + Py_INCREF(locals); +# endif if (locals != nullptr) { # if PY_VERSION_HEX >= 0x030b0000 PyObject *co_varnames = PyCode_GetVarnames(f_code); @@ -2780,6 +2791,7 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char * PyObject *self_arg = PyTuple_GET_ITEM(co_varnames, 0); Py_DECREF(co_varnames); PyObject *self_caller = dict_getitem(locals, self_arg); + Py_DECREF(locals); if (self_caller == self.ptr()) { Py_DECREF(f_code); Py_DECREF(frame);