Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
bfe55ed
Fix race condition with py::make_key_iterator in free threading
colesbury Jan 21, 2026
fa03953
style: pre-commit fixes
pre-commit-ci[bot] Jan 21, 2026
33fb4a6
Bump internals version
XuehaiPan Jan 22, 2026
a4a6a1e
Prevent internals destruction before all pybind11 types are destroyed
XuehaiPan Jan 22, 2026
6d8fa8a
Merge remote-tracking branch 'upstream/master' into fix-segfault
XuehaiPan Jan 22, 2026
1d49006
Use Py_XINCREF and Py_XDECREF
XuehaiPan Jan 22, 2026
70c2ffc
Use PyCriticalSection_BeginMutex instead of recursive mutex
colesbury Jan 22, 2026
8690dd7
style: pre-commit fixes
pre-commit-ci[bot] Jan 22, 2026
b147430
Hold GIL before decref
XuehaiPan Jan 22, 2026
05576f1
Use weakrefs
XuehaiPan Jan 22, 2026
740f693
Remove unused code
XuehaiPan Jan 22, 2026
d9227ce
Move code location
XuehaiPan Jan 22, 2026
7c5d505
Move code location
XuehaiPan Jan 22, 2026
436d812
Move code location
XuehaiPan Jan 22, 2026
ce9ca7f
Try add tests
XuehaiPan Jan 24, 2026
fed1749
Fix PYTHONPATH
XuehaiPan Jan 24, 2026
a407438
Fix PYTHONPATH
XuehaiPan Jan 24, 2026
3df427c
Skip tests for subprocess
XuehaiPan Jan 24, 2026
72c2e0a
Revert to leak internals
XuehaiPan Jan 24, 2026
c5ec1cf
Revert to leak internals
XuehaiPan Jan 24, 2026
8f25a25
Revert "Revert to leak internals"
XuehaiPan Jan 24, 2026
be01d1e
Make pycritical_section non-copyable and non-movable
rwgk Jan 24, 2026
61e032e
Drop Python 3.13t support from CI
rwgk Jan 24, 2026
29840ce
Add Python 3.13 (default) replacement jobs for removed 3.13t jobs
rwgk Jan 24, 2026
97e12d2
Revert internals version bump
XuehaiPan Jan 25, 2026
cdefbf3
Reapply to leak internals
XuehaiPan Jan 25, 2026
6ed2830
Add re-entrancy detection for internals creation
XuehaiPan Jan 25, 2026
2c83462
Fix C++11/C++14 support
XuehaiPan Jan 25, 2026
6922d7d
Add lock under multiple interpreters
XuehaiPan Jan 25, 2026
d61f17c
Try fix tests
XuehaiPan Jan 25, 2026
26e7509
Try fix tests
XuehaiPan Jan 25, 2026
6820ead
Try fix tests
XuehaiPan Jan 25, 2026
15bcbf8
Update comments and assertion messages
XuehaiPan Jan 25, 2026
b0d350e
Update comments and assertion messages
XuehaiPan Jan 25, 2026
33ffa8e
Update comments
XuehaiPan Jan 26, 2026
708ca55
Update lock scope
XuehaiPan Jan 26, 2026
85dc7e6
Use original pointer type for Windows
XuehaiPan Jan 26, 2026
404457e
Change hard error to warning
XuehaiPan Jan 26, 2026
51a70ab
Update lock scope
XuehaiPan Jan 26, 2026
5f96327
Update lock scope to resolve deadlock
XuehaiPan Jan 26, 2026
40731b7
Remove scope release of GIL
XuehaiPan Jan 26, 2026
aa1767c
Update comments
XuehaiPan Jan 26, 2026
91189c9
ci: run in free-threading mode a bit more on 3.14
henryiii Jan 26, 2026
dea5660
Lock pp on reset
XuehaiPan Jan 26, 2026
691241a
Mark content created after assignment
XuehaiPan Jan 26, 2026
552f8b0
Update comments
XuehaiPan Jan 26, 2026
79a80d2
Simplify implementation
XuehaiPan Jan 27, 2026
56926f6
Update lock scope when delete unique_ptr
XuehaiPan Jan 27, 2026
603b25a
Merge branch 'master' into iterator-nogil-threadsafety
rwgk Jan 29, 2026
dc8e35c
Merge branch 'master' into colesbury→iterator-nogil-threadsafety
rwgk Feb 1, 2026
f3197de
Revert "ci: run in free-threading mode a bit more on 3.14"
rwgk Feb 1, 2026
6f3014a
Merge branch 'master' into fix-segfault
XuehaiPan Feb 1, 2026
145be65
Merge branch 'colesbury→iterator-nogil-threadsafety' into recombined_…
rwgk Feb 2, 2026
364994f
ci: run in free-threading mode a bit more on 3.14
henryiii Jan 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ jobs:
python-version: '3.12'
cmake-args: -DPYBIND11_TEST_SMART_HOLDER=ON -DPYBIND11_SIMPLE_GIL_MANAGEMENT=ON
- runs-on: ubuntu-latest
python-version: '3.13t'
python-version: '3.14t'
cmake-args: -DCMAKE_CXX_STANDARD=20 -DPYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION=ON
- runs-on: ubuntu-latest
python-version: '3.14'
Expand All @@ -102,12 +102,12 @@ jobs:
- runs-on: macos-15-intel
python-version: '3.11'
cmake-args: -DPYBIND11_TEST_SMART_HOLDER=ON
- runs-on: macos-15-intel
python-version: '3.13'
cmake-args: -DCMAKE_CXX_STANDARD=11
- runs-on: macos-latest
python-version: '3.12'
cmake-args: -DCMAKE_CXX_STANDARD=17 -DPYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION=ON
- runs-on: macos-15-intel
python-version: '3.13t'
cmake-args: -DCMAKE_CXX_STANDARD=11
- runs-on: macos-latest
python-version: '3.14t'
cmake-args: -DCMAKE_CXX_STANDARD=20
Expand Down Expand Up @@ -138,9 +138,6 @@ jobs:
- runs-on: windows-2022
python-version: '3.13'
cmake-args: -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebugDLL
- runs-on: windows-latest
python-version: '3.13t'
cmake-args: -DCMAKE_CXX_STANDARD=17
- runs-on: windows-latest
python-version: '3.14'
cmake-args: -DCMAKE_CXX_STANDARD=20
Expand Down Expand Up @@ -240,7 +237,7 @@ jobs:


manylinux:
name: Manylinux on 🐍 3.13t • GIL
name: Manylinux on 🐍 3.14t
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
timeout-minutes: 40
Expand All @@ -257,7 +254,7 @@ jobs:
run: uv tool install ninja

- name: Configure via preset
run: cmake --preset venv -DPYBIND11_CREATE_WITH_UV=python3.13t
run: cmake --preset venv -DPYBIND11_CREATE_WITH_UV=python3.14t

- name: Build C++11
run: cmake --build --preset venv
Expand Down
37 changes: 28 additions & 9 deletions docs/advanced/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1381,11 +1381,22 @@ You can do that using ``py::custom_type_setup``:

.. code-block:: cpp

struct OwnsPythonObjects {
py::object value = py::none();
struct ContainerOwnsPythonObjects {
std::vector<py::object> list;

void append(const py::object &obj) { list.emplace_back(obj); }
py::object at(py::ssize_t index) const {
if (index >= size() || index < 0) {
throw py::index_error("Index out of range");
}
return list.at(py::size_t(index));
}
py::ssize_t size() const { return py::ssize_t_cast(list.size()); }
void clear() { list.clear(); }
};
py::class_<OwnsPythonObjects> cls(
m, "OwnsPythonObjects", py::custom_type_setup([](PyHeapTypeObject *heap_type) {

py::class_<ContainerOwnsPythonObjects> cls(
m, "ContainerOwnsPythonObjects", py::custom_type_setup([](PyHeapTypeObject *heap_type) {
auto *type = &heap_type->ht_type;
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
type->tp_traverse = [](PyObject *self_base, visitproc visit, void *arg) {
Expand All @@ -1394,20 +1405,28 @@ You can do that using ``py::custom_type_setup``:
Py_VISIT(Py_TYPE(self_base));
#endif
if (py::detail::is_holder_constructed(self_base)) {
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
Py_VISIT(self.value.ptr());
auto &self = py::cast<ContainerOwnsPythonObjects &>(py::handle(self_base));
for (auto &item : self.list) {
Py_VISIT(item.ptr());
}
}
return 0;
};
type->tp_clear = [](PyObject *self_base) {
if (py::detail::is_holder_constructed(self_base)) {
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
self.value = py::none();
auto &self = py::cast<ContainerOwnsPythonObjects &>(py::handle(self_base));
for (auto &item : self.list) {
Py_CLEAR(item.ptr());
}
self.list.clear();
}
return 0;
};
}));
cls.def(py::init<>());
cls.def_readwrite("value", &OwnsPythonObjects::value);
cls.def("append", &ContainerOwnsPythonObjects::append);
cls.def("at", &ContainerOwnsPythonObjects::at);
cls.def("size", &ContainerOwnsPythonObjects::size);
cls.def("clear", &ContainerOwnsPythonObjects::clear);

.. versionadded:: 2.8
Loading
Loading