Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f6198fb
[ci skip] fix(tests): make async callback test deterministic (#5986)
rwgk Feb 17, 2026
a896f61
Move tomlkit dependency to dev group (#5990)
yselkowitz Feb 23, 2026
1bf20ea
Re-enable Android tests in CIBW workflow (#6001)
mhsmith Mar 2, 2026
fb14383
chore: some minor CPython API cleanup (#6005)
henryiii Mar 22, 2026
7db5e99
gh-5991: Fix segfault during finalization related to function_record …
itamaro Mar 24, 2026
16ef2e3
Fix memory leak: clear managed dict in pybind11_object_dealloc on Pyt…
yamatveev Mar 24, 2026
463168a
Resolve ambiguous factory spec. with nvcc+GCC (#6011)
n01r Mar 24, 2026
c0cfa96
Fix crash in def_readwrite for non-smart-holder properties of smart-h…
virtuald Mar 24, 2026
3cb5a76
fix: bind noexcept and ref-qualified methods from unregistered base c…
Skylion007 Mar 26, 2026
bb78668
Fix `static_pointer_cast` build failure with virtual inheritance in `…
rwgk Mar 27, 2026
ec875b6
Fix TSS key exhaustion in implicitly_convertible() (gh-5975) (#6020)
rwgk Mar 29, 2026
0184c02
Harden `PYBIND11_MODULE_PYINIT` and `get_internals()` against crashes…
rwgk Mar 29, 2026
b6a616e
fix: strdup `"self"` arg in `def_property_static`, partially revert #…
rwgk Mar 30, 2026
8d621d6
fix: detect virtual inheritance in add_base to prevent pointer offset…
rwgk Mar 30, 2026
c0ea8fc
Fix heap-buffer-overflow in `pythonbuf` with undersized buffers (#6019)
rwgk Mar 30, 2026
64eecc4
chore(deps): bump the actions group with 3 updates (#6000)
dependabot[bot] Mar 1, 2026
d12037c
chore(deps): update pre-commit hooks (#6002)
pre-commit-ci[bot] Mar 22, 2026
54a4615
chore(deps): bump requests from 2.32.4 to 2.33.0 in /docs (#6013)
dependabot[bot] Mar 26, 2026
0f41635
chore(deps): bump pygments from 2.17.2 to 2.20.0 in /docs (#6024)
dependabot[bot] Mar 30, 2026
76efcb3
Bump version from v3.0.2 → v3.0.3
rwgk Mar 30, 2026
c066c76
fix: add missing PYBIND11_ALWAYS_INLINE macro for v3.0.3 backports
rwgk Mar 30, 2026
1b49908
docs: add v3.0.3 ~and v3.1.0~ changelog updates. (#6023)
rwgk Mar 31, 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
4 changes: 2 additions & 2 deletions .github/workflows/nightlies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
nox -s build
nox -s build_global

- uses: actions/upload-artifact@v6
- uses: actions/upload-artifact@v7
with:
name: Packages
path: dist/*
Expand All @@ -44,7 +44,7 @@ jobs:
needs: [build_wheel]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v7
- uses: actions/download-artifact@v8
with:
name: Packages
path: dist
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/pip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ jobs:
run: twine check dist/*

- name: Save standard package
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: standard
path: dist/pybind11-*

- name: Save global package
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: global
path: dist/*global-*
Expand All @@ -100,10 +100,10 @@ jobs:

steps:
# Downloads all to directories matching the artifact names
- uses: actions/download-artifact@v7
- uses: actions/download-artifact@v8

- name: Generate artifact attestation for sdist and wheel
uses: actions/attest-build-provenance@v3
uses: actions/attest-build-provenance@v4
with:
subject-path: "*/pybind11*"

Expand Down
18 changes: 0 additions & 18 deletions .github/workflows/tests-cibw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,6 @@ jobs:
if: contains(matrix.runs-on, 'macos')
run: echo "CIBW_TEST_COMMAND=" >> "$GITHUB_ENV"

# Temporarily disable Android tests on ubuntu-latest due to emulator issues.
# See https://github.com/pybind/pybind11/pull/5914.
- name: "NOTE: Android tests are disabled on ubuntu-latest"
if: contains(matrix.runs-on, 'ubuntu')
run: |
echo "CIBW_TEST_COMMAND=" >> "$GITHUB_ENV"
echo '::warning::Android cibuildwheel tests are disabled on ubuntu-latest (CIBW_TEST_COMMAND is empty). See PR 5914.'

# https://github.blog/changelog/2024-04-02-github-actions-hardware-accelerated-android-virtualization-now-available/
- name: Enable KVM for Android emulator
if: contains(matrix.runs-on, 'ubuntu')
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- run: pipx install patchelf

- uses: pypa/cibuildwheel@v3.3
env:
CIBW_PLATFORM: android
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ repos:

# Clang format the codebase automatically
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: "v21.1.8"
rev: "v22.1.0"
hooks:
- id: clang-format
types_or: [c++, c, cuda]

# Ruff, the Python auto-correcting linter/formatter written in Rust
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.14
rev: v0.15.4
hooks:
- id: ruff-check
args: ["--fix", "--show-fixes"]
Expand Down Expand Up @@ -122,7 +122,7 @@ repos:
# Use mirror because pre-commit autoupdate confuses tags in the upstream repo.
# See https://github.com/crate-ci/typos/issues/390
- repo: https://github.com/adhtruong/mirrors-typos
rev: "v1.42.3"
rev: "v1.44.0"
hooks:
- id: typos
args: []
Expand All @@ -144,14 +144,14 @@ repos:

# PyLint has native support - not always usable, but works for us
- repo: https://github.com/PyCQA/pylint
rev: "v4.0.4"
rev: "v4.0.5"
hooks:
- id: pylint
files: ^pybind11

# Check schemas on some of our YAML files
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.36.1
rev: 0.37.0
hooks:
- id: check-readthedocs
- id: check-github-workflows
Expand Down
56 changes: 56 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,62 @@ Changes will be added here periodically from the "Suggested changelog
entry" block in pull request descriptions.


## Version 3.0.3 (March 31, 2026)

Bug fixes:

- Fixed TSS key exhaustion in `implicitly_convertible()` when many implicit conversions are registered across large module sets.
[#6020](https://github.com/pybind/pybind11/pull/6020)

- Fixed heap-buffer-overflow in `pythonbuf` with undersized buffers by enforcing a minimum buffer size.
[#6019](https://github.com/pybind/pybind11/pull/6019)

- Fixed virtual-inheritance pointer offset crashes when dispatching inherited methods through virtual bases.
[#6017](https://github.com/pybind/pybind11/pull/6017)

- Fixed `free(): invalid pointer` crashes during interpreter shutdown with `py::enum_<>` by duplicating late-added `def_property_static` argument strings.
[#6015](https://github.com/pybind/pybind11/pull/6015)

- Fixed `function_record` heap-type deallocation to call `PyObject_Free()` and decref the type.
[#6010](https://github.com/pybind/pybind11/pull/6010)

- Hardened `PYBIND11_MODULE_PYINIT` and `get_internals()` against module-initialization crashes.
[#6018](https://github.com/pybind/pybind11/pull/6018)

- Fixed `static_pointer_cast` build failure with virtual inheritance in `holder_caster_foreign_helpers.h`.
[#6014](https://github.com/pybind/pybind11/pull/6014)

- Fixed ambiguous `factory` template specialization that caused compilation failures with nvcc + GCC 14.
[#6011](https://github.com/pybind/pybind11/pull/6011)

- Fixed crash in `def_readwrite` for non-smart-holder properties of smart-holder classes.
[#6008](https://github.com/pybind/pybind11/pull/6008)

- Fixed memory leak for `py::dynamic_attr()` objects on Python 3.13+ by clearing managed `__dict__` contents during deallocation.
[#5999](https://github.com/pybind/pybind11/pull/5999)

- Fixed binding of `noexcept` and ref-qualified (`&`, `&&`) methods inherited from unregistered base classes.
[#5992](https://github.com/pybind/pybind11/pull/5992)

Internal:

- Moved `tomlkit` dependency to the dev dependency group.
[#5990](https://github.com/pybind/pybind11/pull/5990)

- Switched to newer public CPython APIs (`PyType_GetFlags` and public vectorcall APIs where available).
[#6005](https://github.com/pybind/pybind11/pull/6005)

Tests:

- Made an async callback test deterministic by replacing fixed sleep with bounded waiting.
[#5986](https://github.com/pybind/pybind11/pull/5986)

CI:

- Re-enabled Android tests in the cibuildwheel workflow.
[#6001](https://github.com/pybind/pybind11/pull/6001)


## Version 3.0.2 (February 16, 2026)

New Features:
Expand Down
4 changes: 2 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ myst-parser==3.0.1
# via -r requirements.in
packaging==24.0
# via sphinx
pygments==2.17.2
pygments==2.20.0
# via
# furo
# sphinx
pyyaml==6.0.2
# via myst-parser
requests==2.32.4
requests==2.33.0
# via sphinx
snowballstemmer==2.2.0
# via sphinx
Expand Down
2 changes: 1 addition & 1 deletion include/pybind11/attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ struct type_record {
#ifdef PYBIND11_BACKWARD_COMPATIBILITY_TP_DICTOFFSET
dynamic_attr |= base_info->type->tp_dictoffset != 0;
#else
dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0;
dynamic_attr |= (PyType_GetFlags(base_info->type) & Py_TPFLAGS_MANAGED_DICT) != 0;
#endif

if (caster) {
Expand Down
35 changes: 24 additions & 11 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,7 @@ public:
template <typename T_, \
::pybind11::detail::enable_if_t< \
std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value, \
int> \
= 0> \
int> = 0> \
static ::pybind11::handle cast( \
T_ *src, ::pybind11::return_value_policy policy, ::pybind11::handle parent) { \
if (!src) \
Expand Down Expand Up @@ -1020,7 +1019,19 @@ struct copyable_holder_caster<
return smart_holder_type_caster_support::smart_holder_from_shared_ptr(
src, policy, parent, srcs.result);
}
return type_caster_base<type>::cast_holder(srcs, &src);

auto *tinfo = srcs.result.tinfo;
if (tinfo != nullptr && tinfo->holder_enum_v == holder_enum_t::std_shared_ptr) {
return type_caster_base<type>::cast_holder(srcs, &src);
}

if (parent) {
return type_caster_base<type>::cast(
srcs, return_value_policy::reference_internal, parent);
}

throw cast_error("Unable to convert std::shared_ptr<T> to Python when the bound type "
"does not use std::shared_ptr or py::smart_holder as its holder type");
}

// This function will succeed even if the `responsible_parent` does not own the
Expand Down Expand Up @@ -1662,8 +1673,7 @@ PYBIND11_NAMESPACE_END(detail)
template <typename T,
detail::enable_if_t<!detail::is_pyobject<T>::value
&& !detail::is_same_ignoring_cvref<T, PyObject *>::value,
int>
= 0>
int> = 0>
T cast(const handle &handle) {
using namespace detail;
constexpr bool is_enum_cast = type_uses_type_caster_enum_type<intrinsic_t<T>>::value;
Expand Down Expand Up @@ -1698,8 +1708,7 @@ template <typename T,
typename Handle,
detail::enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value
&& detail::is_same_ignoring_cvref<Handle, handle>::value,
int>
= 0>
int> = 0>
T cast(Handle &&handle) {
return handle.inc_ref().ptr();
}
Expand All @@ -1708,8 +1717,7 @@ template <typename T,
typename Object,
detail::enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value
&& detail::is_same_ignoring_cvref<Object, object>::value,
int>
= 0>
int> = 0>
T cast(Object &&obj) {
return obj.release().ptr();
}
Expand Down Expand Up @@ -2243,8 +2251,13 @@ class unpacking_collector {
if (m_names) {
nargs -= m_names.size();
}
PyObject *result = _PyObject_Vectorcall(
ptr, m_args.data() + 1, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, m_names.ptr());
PyObject *result =
#if PY_VERSION_HEX >= 0x03090000
PyObject_Vectorcall(
#else
_PyObject_Vectorcall(
#endif
ptr, m_args.data() + 1, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, m_names.ptr());
if (!result) {
throw error_already_set();
}
Expand Down
3 changes: 1 addition & 2 deletions include/pybind11/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ class duration_caster {
return src;
}
static const std::chrono::duration<rep, period> &
get_duration(const std::chrono::duration<rep, period> &&)
= delete;
get_duration(const std::chrono::duration<rep, period> &&) = delete;

// If this is a time_point get the time_since_epoch
template <typename Clock>
Expand Down
11 changes: 11 additions & 0 deletions include/pybind11/detail/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,17 @@ extern "C" inline void pybind11_object_dealloc(PyObject *self) {
PyObject_GC_UnTrack(self);
}

#if PY_VERSION_HEX >= 0x030D0000
// PyObject_ClearManagedDict() is available from Python 3.13+. It must be
// called before tp_free() because on Python 3.14+ tp_free no longer
// implicitly clears the managed dict, which would abandon the refcounts of
// objects stored in __dict__ of py::dynamic_attr() types, causing permanent
// memory leaks.
if (PyType_HasFeature(type, Py_TPFLAGS_MANAGED_DICT)) {
PyObject_ClearManagedDict(self);
}
#endif

clear_instance(self);

type->tp_free(self);
Expand Down
Loading
Loading