Skip to content

Commit 6b3b697

Browse files
committed
Merge branch 'master' into sh_merge_master
2 parents f4bc71f + 35ff42b commit 6b3b697

20 files changed

+429
-74
lines changed

.github/workflows/ci.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,35 @@ jobs:
197197
pytest tests/extra_setuptools
198198
if: "!(matrix.runs-on == 'windows-2022')"
199199

200+
manylinux:
201+
name: Manylinux on 🐍 3.13t • GIL
202+
runs-on: ubuntu-latest
203+
timeout-minutes: 40
204+
container: quay.io/pypa/musllinux_1_2_x86_64:latest
205+
steps:
206+
- uses: actions/checkout@v4
207+
with:
208+
fetch-depth: 0
209+
210+
- name: Prepare venv
211+
run: python3.13t -m venv .venv
212+
213+
- name: Install Python deps
214+
run: .venv/bin/pip install -r tests/requirements.txt
215+
216+
- name: Configure C++11
217+
run: >
218+
cmake -S. -Bbuild
219+
-DPYBIND11_WERROR=ON
220+
-DDOWNLOAD_CATCH=ON
221+
-DDOWNLOAD_EIGEN=ON
222+
-DPython_ROOT_DIR=.venv
223+
224+
- name: Build C++11
225+
run: cmake --build build -j2
226+
227+
- name: Python tests C++11
228+
run: cmake --build build --target pytest -j2
200229

201230
deadsnakes:
202231
strategy:

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ repos:
3232

3333
# Ruff, the Python auto-correcting linter/formatter written in Rust
3434
- repo: https://github.com/astral-sh/ruff-pre-commit
35-
rev: v0.4.5
35+
rev: v0.4.7
3636
hooks:
3737
- id: ruff
3838
args: ["--fix", "--show-fixes"]

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ option(PYBIND11_NUMPY_1_ONLY
116116
set(PYBIND11_INTERNALS_VERSION
117117
""
118118
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
119+
option(PYBIND11_USE_CROSSCOMPILING "Respect CMAKE_CROSSCOMPILING" OFF)
119120

120121
if(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
121122
add_compile_definitions(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
@@ -306,6 +307,7 @@ if(PYBIND11_INSTALL)
306307
tools/pybind11Common.cmake
307308
tools/pybind11Tools.cmake
308309
tools/pybind11NewTools.cmake
310+
tools/pybind11GuessPythonExtSuffix.cmake
309311
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
310312

311313
if(NOT PYBIND11_EXPORT_NAME)

include/pybind11/detail/class.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,11 @@ inline void clear_patients(PyObject *self) {
388388
auto *instance = reinterpret_cast<detail::instance *>(self);
389389
auto &internals = get_internals();
390390
auto pos = internals.patients.find(self);
391-
assert(pos != internals.patients.end());
391+
392+
if (pos == internals.patients.end()) {
393+
pybind11_fail("FATAL: Internal consistency check failed: Invalid clear_patients() call.");
394+
}
395+
392396
// Clearing the patients can cause more Python code to run, which
393397
// can invalidate the iterator. Extract the vector of patients
394398
// from the unordered_map first.

include/pybind11/pybind11.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3040,7 +3040,7 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char *
30403040
PyObject *locals = PyEval_GetFrameLocals();
30413041
# else
30423042
PyObject *locals = PyEval_GetLocals();
3043-
Py_INCREF(locals);
3043+
Py_XINCREF(locals);
30443044
# endif
30453045
if (locals != nullptr) {
30463046
# if PY_VERSION_HEX >= 0x030b0000

include/pybind11/pytypes.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,15 @@ class object_api : public pyobject_tag {
183183
str_attr_accessor doc() const;
184184

185185
/// Return the object's current reference count
186-
int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
186+
ssize_t ref_count() const {
187+
#ifdef PYPY_VERSION
188+
// PyPy uses the top few bits for REFCNT_FROM_PYPY & REFCNT_FROM_PYPY_LIGHT
189+
// Following pybind11 2.12.1 and older behavior and removing this part
190+
return static_cast<ssize_t>(static_cast<int>(Py_REFCNT(derived().ptr())));
191+
#else
192+
return Py_REFCNT(derived().ptr());
193+
#endif
194+
}
187195

188196
// TODO PYBIND11_DEPRECATED(
189197
// "Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()")
@@ -2175,6 +2183,11 @@ class list : public object {
21752183
throw error_already_set();
21762184
}
21772185
}
2186+
void clear() /* py-non-const */ {
2187+
if (PyList_SetSlice(m_ptr, 0, PyList_Size(m_ptr), nullptr) == -1) {
2188+
throw error_already_set();
2189+
}
2190+
}
21782191
};
21792192

21802193
class args : public tuple {

tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ if(Boost_FOUND)
358358
add_library(Boost::headers IMPORTED INTERFACE)
359359
if(TARGET Boost::boost)
360360
# Classic FindBoost
361-
set_property(TARGET Boost::boost PROPERTY INTERFACE_LINK_LIBRARIES Boost::boost)
361+
set_property(TARGET Boost::headers PROPERTY INTERFACE_LINK_LIBRARIES Boost::boost)
362362
else()
363363
# Very old FindBoost, or newer Boost than CMake in older CMakes
364364
set_property(TARGET Boost::headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES

tests/extra_python_package/test_files.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"share/cmake/pybind11/pybind11Common.cmake",
8181
"share/cmake/pybind11/pybind11Config.cmake",
8282
"share/cmake/pybind11/pybind11ConfigVersion.cmake",
83+
"share/cmake/pybind11/pybind11GuessPythonExtSuffix.cmake",
8384
"share/cmake/pybind11/pybind11NewTools.cmake",
8485
"share/cmake/pybind11/pybind11Targets.cmake",
8586
"share/cmake/pybind11/pybind11Tools.cmake",

tests/pybind11_tests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ PYBIND11_MODULE(pybind11_tests, m) {
8989
#endif
9090
m.attr("cpp_std") = cpp_std();
9191
m.attr("PYBIND11_INTERNALS_ID") = PYBIND11_INTERNALS_ID;
92+
// Free threaded Python uses UINT32_MAX for immortal objects.
93+
m.attr("PYBIND11_REFCNT_IMMORTAL") = UINT32_MAX;
9294
m.attr("PYBIND11_SIMPLE_GIL_MANAGEMENT") =
9395
#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
9496
true;

tests/test_class.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44

55
import env
6-
from pybind11_tests import ConstructorStats, UserType
6+
from pybind11_tests import PYBIND11_REFCNT_IMMORTAL, ConstructorStats, UserType
77
from pybind11_tests import class_ as m
88

99

@@ -377,7 +377,9 @@ class PyDog(m.Dog):
377377
refcount_3 = getrefcount(cls)
378378

379379
assert refcount_1 == refcount_3
380-
assert refcount_2 > refcount_1
380+
assert (refcount_2 > refcount_1) or (
381+
refcount_2 == refcount_1 == PYBIND11_REFCNT_IMMORTAL
382+
)
381383

382384

383385
def test_reentrant_implicit_conversion_failure(msg):

0 commit comments

Comments
 (0)