Skip to content

Commit d59e7e3

Browse files
committed
Add support for PyPy3.12 v8.0.0
1 parent b72bc5e commit d59e7e3

5 files changed

Lines changed: 41 additions & 6 deletions

File tree

docs/api.rst

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ functions for old Python versions.
88
Supported Python versions:
99

1010
* Python 3.6 - 3.15
11-
* PyPy 2.7 and PyPy 3.6 - 3.10
11+
* PyPy 3.6 - 3.12
1212

1313
C++03 and C++11 are supported on Python 3.6 and newer.
1414

@@ -239,6 +239,20 @@ Python 3.14
239239

240240
See `PyUnstable_Object_IsUniquelyReferenced() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_Object_IsUniquelyReferenced>`__.
241241

242+
Not available on PyPy 3.12.
243+
244+
.. c:function:: int PyUnstable_TryIncRef(PyObject *op)
245+
246+
See `PyUnstable_TryIncRef() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_TryIncRef>`__.
247+
248+
Not available on PyPy 3.12.
249+
250+
.. c:function:: void PyUnstable_EnableTryIncRef(PyObject *op)
251+
252+
See `PyUnstable_EnableTryIncRef() documentation <https://docs.python.org/dev/c-api/object.html#c.PyUnstable_EnableTryIncRef>`__.
253+
254+
Not available on PyPy 3.12.
255+
242256
Not supported:
243257

244258
* ``PyConfig_Names()``

docs/changelog.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
Changelog
22
=========
33

4+
* 2026-09-22: Add support for PyPy3.12 v8.0.0, which provides
5+
``PyFrame_GetCode()`` and ``PyInterpreterState_Get()``.
6+
``PyUnstable_Object_IsUniquelyReferenced()``, ``PyUnstable_TryIncRef()``
7+
and ``PyUnstable_EnableTryIncRef()`` are not available on PyPy3.12.
48
* 2026-09-07: Remove code to support Python 2.7, Python 3.5 and PyPy
59
for Python 2.7 ("pypy2").
610
Python 2.7 was no longer supported since August 2023.

pythoncapi_compat.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
126126

127127

128128
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
129-
#if PY_VERSION_HEX < 0x030900B1 || defined(PYPY_VERSION)
129+
// PyPy added PyFrame_GetCode() to PyPy3.12 v8.0.0
130+
#if PY_VERSION_HEX < 0x030900B1 || (defined(PYPY_VERSION) && PY_VERSION_HEX < 0x030C0000)
130131
static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
131132
{
132133
assert(frame != _Py_NULL);
@@ -285,7 +286,8 @@ _PyThreadState_GetFrameBorrow(PyThreadState *tstate)
285286

286287

287288
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
288-
#if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION)
289+
// PyPy added PyInterpreterState_Get() to PyPy3.12 v8.0.0
290+
#if PY_VERSION_HEX < 0x030900A5 || (defined(PYPY_VERSION) && PY_VERSION_HEX < 0x030C0000)
289291
static inline PyInterpreterState* PyInterpreterState_Get(void)
290292
{
291293
PyThreadState *tstate;
@@ -2130,7 +2132,8 @@ PyConfig_GetInt(const char *name, int *value)
21302132

21312133
// gh-133144 added PyUnstable_Object_IsUniquelyReferenced() to Python 3.14.0b1.
21322134
// Adapted from _PyObject_IsUniquelyReferenced() implementation.
2133-
#if PY_VERSION_HEX < 0x030E00B0
2135+
// Not available on PyPy3.12: ob_refcnt carries an internal tag.
2136+
#if PY_VERSION_HEX < 0x030E00B0 && (!defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030C0000)
21342137
static inline int PyUnstable_Object_IsUniquelyReferenced(PyObject *obj)
21352138
{
21362139
#if !defined(Py_GIL_DISABLED)
@@ -2148,7 +2151,8 @@ static inline int PyUnstable_Object_IsUniquelyReferenced(PyObject *obj)
21482151

21492152
// gh-128926 added PyUnstable_TryIncRef() and PyUnstable_EnableTryIncRef() to
21502153
// Python 3.14.0a5. Adapted from _Py_TryIncref() and _PyObject_SetMaybeWeakref().
2151-
#if PY_VERSION_HEX < 0x030E00A5
2154+
// Not available on PyPy3.12: ob_refcnt carries an internal tag.
2155+
#if PY_VERSION_HEX < 0x030E00A5 && (!defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030C0000)
21522156
static inline int PyUnstable_TryIncRef(PyObject *op)
21532157
{
21542158
#ifndef Py_GIL_DISABLED

runtests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"pypy3.9",
4949
"pypy3.10",
5050
"pypy3.11",
51+
"pypy3.12",
5152
)
5253

5354

tests/test_pythoncapi_compat_cext.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,8 @@ test_unicodewriter_format(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19561956
}
19571957
#endif
19581958

1959+
// PyUnstable_Object_IsUniquelyReferenced() is not available on PyPy3.12.
1960+
#if !defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030C0000
19591961
static PyObject *
19601962
test_uniquely_referenced(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19611963
{
@@ -1975,6 +1977,7 @@ test_uniquely_referenced(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19751977

19761978
Py_RETURN_NONE;
19771979
}
1980+
#endif
19781981

19791982
static PyObject *
19801983
test_bytes(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
@@ -2419,7 +2422,9 @@ test_tuple(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
24192422
return test_tuple_fromarray();
24202423
}
24212424

2422-
// Test adapted from CPython's _testcapi/object.c
2425+
// Test adapted from CPython's _testcapi/object.c.
2426+
// PyUnstable_TryIncRef() is not available on PyPy3.12.
2427+
#if !defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030C0000
24232428
static int TryIncref_dealloc_called = 0;
24242429

24252430
static void
@@ -2458,6 +2463,7 @@ test_try_incref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
24582463
assert(TryIncref_dealloc_called == 1);
24592464
Py_RETURN_NONE;
24602465
}
2466+
#endif
24612467

24622468
#if 0x030D0000 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
24632469
static PyObject *
@@ -2545,10 +2551,14 @@ static struct PyMethodDef methods[] = {
25452551
{"test_config", test_config, METH_NOARGS, _Py_NULL},
25462552
#endif
25472553
{"test_sys", test_sys, METH_NOARGS, _Py_NULL},
2554+
#if !defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030C0000
25482555
{"test_uniquely_referenced", test_uniquely_referenced, METH_NOARGS, _Py_NULL},
2556+
#endif
25492557
{"test_byteswriter", test_byteswriter, METH_NOARGS, _Py_NULL},
25502558
{"test_tuple", test_tuple, METH_NOARGS, _Py_NULL},
2559+
#if !defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030C0000
25512560
{"test_try_incref", test_try_incref, METH_NOARGS, _Py_NULL},
2561+
#endif
25522562
#if 0x030D0000 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
25532563
{"test_set_immortal", test_set_immortal, METH_NOARGS, _Py_NULL},
25542564
#endif
@@ -2580,13 +2590,15 @@ module_exec(PyObject *module)
25802590
return -1;
25812591
}
25822592
#endif
2593+
#if !defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030C0000
25832594
TryIncrefType.tp_name = "TryIncrefType";
25842595
TryIncrefType.tp_basicsize = sizeof(PyObject);
25852596
TryIncrefType.tp_dealloc = TryIncref_dealloc;
25862597
TryIncrefType.tp_free = PyObject_Del;
25872598
if (PyType_Ready(&TryIncrefType) < 0) {
25882599
return -1;
25892600
}
2601+
#endif
25902602
return 0;
25912603
}
25922604

0 commit comments

Comments
 (0)