Skip to content

fix: support PyPy 8.0.0 (3.11 and 3.12) - #6197

Merged
rwgk merged 6 commits into
masterfrom
pypy-8
Oct 19, 2026
Merged

rwgk merged 6 commits into
masterfrom
pypy-8

Conversation

@henryiii

@henryiii henryiii commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

🤖 AI text below 🤖

Description

Test PyPy 8.0.0 in CI on both 3.11 and 3.12. PyPy 3.12 found two bugs:

  • Deallocating a py::dynamic_attr() instance aborted with "Invalid usage of a dying CPython object". PyPy 3.12's _PyObject_GetDictPtr() now publishes the dict into the C slot and cannot be called from tp_dealloc (on 3.11 it always returned NULL). On PyPy, pybind11 now reads the slot from tp_dictoffset. test_mi_dynamic_attributes now runs the GC so that the crash is deterministic.
  • memoryview::from_buffer() passes temporary shape/strides arrays. PyPy (8.0.0 and older) keeps these pointers without copying them unless they point to the inline _shape/_strides arrays of Py_buffer. On 3.12 this gave a MemoryError. On PyPy, pybind11 now copies the values into those arrays. Upstream PyPy fixed this on the py3.12 branch after 8.0.0.

I ran the full test suite locally on macOS with PyPy 3.11 and 3.12 (8.0.0).

Suggested changelog entry:

  • Support PyPy 8.0.0 (3.11 and 3.12): fix a crash when deallocating py::dynamic_attr() instances and a dangling shape/strides pointer in memoryview::from_buffer() on PyPy.

Fix two problems found with PyPy 3.12:

- Deallocating a py::dynamic_attr() instance aborted, because PyPy 3.12's
  _PyObject_GetDictPtr() cannot be called from tp_dealloc. Read the dict
  slot from tp_dictoffset on PyPy instead.
- memoryview::from_buffer() passed temporary shape/strides arrays, which
  PyPy keeps without copying. Use PyPy's inline _shape/_strides arrays.

Assisted-by: ClaudeCode:claude-opus-5-5
A later PyPy GC at an arbitrary point can run the Python-calling destructor
and abort.

Assisted-by: ClaudeCode:claude-opus-5-5
@henryiii
henryiii marked this pull request as ready for review October 7, 2026 19:16
rwgk added 3 commits October 17, 2026 13:58
PyPy 8.0.1 fixes the deallocation bug, but 8.0.x releases share an
extension ABI. Retain the workaround throughout that minor series so
extensions built with newer headers can still run on 8.0.0.

Register PYPY_VERSION_NUM with the inline-header configuration checker.
Update the Linux Python 3.11 and macOS Python 3.12 jobs to PyPy 8.0.1.
Keep Linux Python 3.12 on 8.0.0 to exercise the deallocation and memoryview
workarounds without adding jobs.

@rwgk rwgk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@henryiii I added a couple commits and merged master:

  • f584dca fix: limit PyPy dict deallocation workaround to 8.0.x
  • 9f74660 ci: test PyPy 8.0.1 while retaining 8.0.0 regression coverage
  • 9d8db4b Merge branch 'master' into upstream→pypy-8

Keep a pinned PyPy 7.3.23 / Python 3.11 job alongside the PyPy 8 matrix while PyPy 7 remains supported.

Assisted-by: Codex
@rwgk

rwgk commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Commit 3d087e1 retains one explicitly pinned PyPy 7 CI job while this PR adds PyPy 8 coverage. Without that addition, the matrix update would remove our remaining PyPy 7 coverage, even though we have not decided to drop PyPy 7 support.

The retained job runs PyPy 7.3.23 / Python 3.11 on Linux. This is particularly relevant to #6193, which restricts the explicit __index__ fallback for complex conversion to PyPy < 8. The retained PyPy 7 job exercises that fallback, while the PyPy 8 jobs exercise the native C API conversion path.

We have already tested the interaction between these PRs: the CI-only integration PR #6206 merges #6197 into #6193, and its full CI passed with 85 successful checks and two skips. Both conversion paths have therefore been tested together.

I'll go ahead and merge this PR and #6193. Dropping PyPy 7 support can be discussed separately. If we decide to do so, we can remove the remaining PyPy 7 job and the workarounds needed only for PyPy 7 in a follow-up PR.

@rwgk
rwgk merged commit e51c2fd into master Oct 19, 2026
149 of 152 checks passed
@rwgk
rwgk deleted the pypy-8 branch October 19, 2026 02:35
@github-actions github-actions Bot added the needs changelog Possibly needs a changelog entry label Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs changelog Possibly needs a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants