Skip to content

release: 0.29.3 - #6416

Open
davidhewitt wants to merge 47 commits into
release-0.29from
release-0.29.3
Open

davidhewitt wants to merge 47 commits into
release-0.29from
release-0.29.3

Conversation

@davidhewitt

Copy link
Copy Markdown
Member

This PR contains backfixes for the 0.29 release series, targeting the release-0.29 branch. It's not all possible fixes, just everything which I could cherry-pick relatively cleanly.

I hadn't wanted to do this (as CI has been bumpy recently and required a bit of hacking to fix); I was thinking we could get away with going straight for the 0.30 release. Sadly I think given a number of the recent bug discoveries I think this patch release is justified. In particular it seems like we're broken with a few various "supported" interpreters and it seems worth landing fixes for those in a patch release.

Before releasing, I want to merge (and cherry-pick):

Might also be worth landing a fix for #6392 if someone has time to triage & investigate it (sounds potentially problematic).

chirizxc and others added 30 commits September 15, 2026 15:58
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6 to 7.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](actions/checkout@v7...v7.0.1)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Preallocate sets when extracting Python set values

* Document Python set extraction allocation improvement

* Remove ineffective set capacity assertions

* Preallocate BTreeSet extraction buffers

* Fix Clippy Vec import for set extraction
* update `PySet_GET_SIZE` and similar for free-threaded Python

* split `cpython` portion of `setobject.h` off
* internal: simplify module creation conditional branches

* further cleanup

* fixup test
* ci: fix ffi-check for backport of `Py_CompileStringFlags` symbol

* always use latest Python versions
* ci: pin the `careful` job to nightly-2026-08-06

From nightly-2026-08-07 cargo no longer finds the sysroot `cargo careful`
builds for itself when running test binaries. Proc-macro crates link `libstd`
dynamically, so the `pyo3-macros` test binary can't start:

    error while loading shared libraries: libstd-<hash>.so: cannot open
    shared object file: No such file or directory

That aborts the job before it gets to anything else. Pin to the last nightly
where it works; revert to `@nightly` once
RalfJung/cargo-careful#55 is fixed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N96dd4VafzejRKxEuk1pU4

* ci: fix `wasm32-wasip1` job against CPython 3.14.7

Two problems, both surfaced by CPython 3.14 moving to a new patch release:

* `test-wasm` points the embedded interpreter at `PYTHONPATH=/lib`, which has
  never existed in the CPython checkout. It worked because `getpath` found the
  build tree itself, via the `Modules/Setup.local` landmark next to the
  "executable". CPython 3.14.7 removed that fallback (gh-151544), so the test
  binaries now die on startup with "Fatal Python error: Failed to import
  encodings module". Pass the stdlib and the WASI build directory explicitly.

* The `.nox/wasi` cache is keyed on `UV_PYTHON` ("3.14"), not on the CPython
  version nox builds and then looks for, so a new patch release restores the
  previous one's build and skips the build step. `cargo test` then fails
  immediately with "failed to search the lib dir at PYO3_CROSS_LIB_DIR=...".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N96dd4VafzejRKxEuk1pU4

* Update .github/workflows/ci.yml

Co-authored-by: David Hewitt <mail@davidhewitt.dev>

* Update noxfile.py

Co-authored-by: David Hewitt <mail@davidhewitt.dev>

* Update .github/workflows/ci.yml

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: David Hewitt <mail@davidhewitt.dev>
…`Copy` classes (#6309)

* fix `clippy::clone_on_copy` firing on `#[pyclass(from_py_object)]` + `Copy` classes

Move the clone out of the generated `FromPyObject` impl into a generic
helper where the type is only known to be `Clone`, so the lint cannot
trigger. Fixes #6308.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* bless UI test snapshot for trimmed `FromPyObject` diagnostic paths

The generated `extract` body no longer references `FromPyObject` items
inline, which changes how rustc renders the trait path in unrelated
diagnostics in the same crate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* bless `default` revision UI test snapshot as well

Same trimmed-path diagnostic drift as the `inspect` revision; this
snapshot only runs without `experimental-inspect` enabled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: David Hewitt <mail@davidhewitt.dev>
Bumps [CodSpeedHQ/action](https://github.com/codspeedhq/action) from 5.0.1 to 5.0.3.
- [Release notes](https://github.com/codspeedhq/action/releases)
- [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md)
- [Commits](CodSpeedHQ/action@v5.0.1...v5.0.3)

---
updated-dependencies:
- dependency-name: CodSpeedHQ/action
  dependency-version: 5.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* refactor: move some tests inside the lib

* fix abi3 gates

* correct std imports

* fixup imports

* fixup chrono-tz tests

* format
Addresses one item from gh-3310's checklist ("String intern!"). The
guide already covers extract-vs-cast, Bound::py, calling conventions,
Python::detach, and the reference pool, but never mentioned intern!,
even though it's one of the simplest, most broadly applicable
optimizations (avoiding a repeated PyString allocation at call sites
that reuse the same string, e.g. dict keys/attribute names).

The example follows the same before/after style as the rest of the
guide and is adapted from the intern! macro's own doc comment in
src/sync.rs, which is already an existing, passing doctest - not new,
unverified example code.

Not addressing gh-3310's other checklist items in this PR:
- The Vec<u8>/Cow<[u8]> item was confirmed already resolved by the
  IntoPyObject rework in the issue's own comment thread (by
  @Icxolu), so documenting it as a live gotcha would now be
  inaccurate.
- The remaining items (conversion overhead in general,
  #[pyo3(get)] deep-cloning, dictionary dispatch) need more source
  investigation than fits one PR; leaving those for follow-up.
…6340)

* ci: bump wasi builds to use 3.15, read WASI SDK from cpython config

* fixup emscripten build
* `experimental-inspect`: cover the `Option`-returning `__next__` / `__anext__` shapes

Route A: one wrapper carrying both the conversion and the type hint

Review pass on the `IterNextOutput` wrapper

pytests: assert the generated `__next__` / `__anext__` hints

* Address review

- Use `StaticIdent` for the hard-coded wrapper / fallback names instead of
  `&str` + `format_ident!` (and `TokenGenerator` on the slot side).
- Drop the `asyncness` guard around the `__next__` / `__anext__` return type:
  `async fn` does not compile for *any* slot method today (the slot body hands
  the future straight to `IntoPyCallbackOutput`), so the guard was unreachable.
- Note in `impl_/pymethods.rs` that `am_anext` has no null-without-error
  convention, so `StopAsyncIteration` has to be raised explicitly.

* pytests: skip the async-iter test on GraalPy < 25.1

`PyClassOptionAsyncIter.__anext__` signals exhaustion the way the
`am_anext` slot has to: it raises `StopAsyncIteration` synchronously,
since the slot has no "returned null, no error set" convention.

GraalPy < 25.1 lets such a synchronous raise escape `async for` instead
of ending the loop. That is not specific to native classes -- a plain
Python class with a non-`async def __anext__` reproduces it -- and it is
already fixed in GraalPy 25.1, so gate the test on the version rather
than on the implementation alone.
* suppress warning

* suppress warning in proc-macro generated code
* Use Cargo workspace publishing

Simplify the publishing setup by using https://doc.rust-lang.org/cargo/CHANGELOG.html#cargo-190-2025-09-18

* Remove `cargo publish` for noxfile

It's only runnable in CI anyway.
`Arc::<[u8]>::from(py_bytearray.to_vec())` creates a `Vec` copy of the `PyByteArray` contents, then immediately copies that `Vec` into an `Arc<[u8]>`. It should copy the `PyByteArray` contents directly into the `Arc<[u8]>`. This PR inlines `PyByteArrayMethods::to_vec` into `PyBackedBytes::from` without the unnecessary copy.

See: <https://github.com/PyO3/pyo3/blob/75507833367e5267dd6fdd7e48de628e4b8e53e0/src/types/bytearray.rs#L291-L300>.
…ectory (#6365)

* experimental-inspect: write nested package stubs into their own directory

* Correct newsfragement number
* preliminary fixes for PyPy 3.12

* fixup
dependabot Bot and others added 11 commits September 15, 2026 16:14
Bumps [CodSpeedHQ/action](https://github.com/codspeedhq/action) from 5.0.3 to 5.2.1.
- [Release notes](https://github.com/codspeedhq/action/releases)
- [Changelog](https://github.com/CodSpeedHQ/action/blob/main/CHANGELOG.md)
- [Commits](CodSpeedHQ/action@v5.0.3...v5.2.1)

---
updated-dependencies:
- dependency-name: CodSpeedHQ/action
  dependency-version: 5.2.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Add eval frame FFI bindings

* Add eval frame FFI bindings

* Fix eval code extra index link name
* Fix empty tuple type hints rendering as invalid `tuple[]`

* remove empty tuple test already covered by integration test
…one` default (#6363)

* experimental-inspect: give slot-wrapper trailing arguments their `None` default

* test: cover the slot table's optional trailing argument counts

* Drop redundant optional_trailing_args test
…6397)

* Escape control characters as Python, not as Rust

`Display for PyStaticExpr` rendered string constants with `{value:?}`,
which uses Rust's escaping rules. Rust writes an unprintable character
as `\u{1b}`; Python's `\u` escape takes exactly four hex digits, so that
form is a SyntaxError rather than an escape. Any string constant holding
a C0 control character other than NUL, tab, newline or carriage return
therefore rendered as invalid Python -- an ANSI sequence in a signature
default such as `"\x1b[0m"` is the realistic way to hit it.

The sibling renderer in `pyo3-introspection/src/stubs.rs` already gets
this right, writing `\x1b`. This mirrors its escape table so the two
agree.

The existing test covered `"\0\t\\\""`, the four characters whose Rust
and Python escapes happen to be identical, so the divergence did not
show up.

* Add newsfragment

* Cover the newline, carriage return and literal-character arms
….abc.Buffer` (py312+) (#6395)

* Introspection: use `typing_extensions.Buffer` instead of `collections.abc.Buffer` (py312+)

* Introspection: only import `Buffer` from `typing_extensions` on `python<3.12`

Co-authored-by: Jonas Dedden <mail@jonas-dedden.de>

* Introspection: apply review suggestions for the `typing_extensions.Buffer` fix

Co-authored-by: Thomas Tanon <thomas@pellissier-tanon.fr>

---------

Co-authored-by: Jonas Dedden <mail@jonas-dedden.de>
Co-authored-by: Thomas Tanon <thomas@pellissier-tanon.fr>
* Introspection: Escape stub docstrings to prevent invalid syntax.

* Introspection: don't escape `"` in docstrings unless necessary

Co-authored-by: Thomas Tanon <thomas@pellissier-tanon.fr>

---------

Co-authored-by: Thomas Tanon <thomas@pellissier-tanon.fr>
* Record successful attach only after attaching in SuspendAttach

* fix limited API builds

* add release note

* simplify test
@codspeed

codspeed Bot commented Sep 15, 2026

Copy link
Copy Markdown

Hooray! CodSpeed harness just leveled up!

The base and head of this comparison were measured with different runner settings, so their benchmark values are not directly comparable.

What changed between base and head:

Re-run the base with the same settings to get a valid performance comparison.


Comparing release-0.29.3 (e02eaf5) with release-0.29 (646a38d)1

Open in CodSpeed

Footnotes

  1. No successful run was found on release-0.29 (a70d17f) during the generation of this report, so e69ae19 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

davidhewitt and others added 6 commits September 17, 2026 07:49
* fix raw-dylib opt-out on windows x86

* newsfragment

* correct PyPy build failures

* `PyVectorcall_Call` is 3.12+

* workaround incorrect lib name for PyPy with raw-dylib opt out

* fix `PyVectorcall_Call` cfg
* ci: update ffi-check for PyPy symbol mangling change

* fix formatting

* fix ffi check failures on older versions

* fix pypy 3.11 link aliases

* fmt

* try fix windows build

* try to fix windows

* try switch to allowlist for bindgen

* try to make link failures on windows easier to diagnose

* fix link name for pypy without raw-dylib

* fix missing PyPy link name attributes

* only decorate x86 symbols on `raw-dylib` builds

* Update link name for PyVectorcall_Call in abstract_.rs

* fmt
* internal: new badges

* Update README.md

* Update README.md
* check static addresses match in `pyo3-ffi-check`

* newsfragments

* fix private symbols

* fmt

* fix windows-only pypy symbol
* fix FFI cases where PyPy replaced function with macro

* newsfragment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.