Skip to content

Commit b4cf220

Browse files
vstinnerhugovk
andauthored
Add further support for PyPy3.12 v8.0.0 (#180)
PyUnstable_Object_IsUniquelyReferenced(), PyUnstable_TryIncRef() and PyUnstable_EnableTryIncRef() are no longer available on PyPy. Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
1 parent 2b39be8 commit b4cf220

6 files changed

Lines changed: 38 additions & 6 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ jobs:
4343
- "pypy3.9"
4444
- "pypy3.10"
4545
- "pypy3.11"
46+
- "pypy3.12"
4647

4748
# Old PyPy versions
4849
# See https://github.com/pypy/pypy/issues/3990

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. ``Py_REFCNT()`` semantics is different on PyPy.
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. ``Py_REFCNT()`` semantics is different on PyPy.
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. ``Py_REFCNT()`` semantics is different on PyPy.
255+
242256
Not supported:
243257

244258
* ``PyConfig_Names()``

docs/changelog.rst

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

4-
* 2026-09-22: Add initial support for PyPy3.12 v8.0.0, which provides
4+
* 2026-09-23: ``PyUnstable_Object_IsUniquelyReferenced()``,
5+
``PyUnstable_TryIncRef()`` and ``PyUnstable_EnableTryIncRef()`` are no longer
6+
available on PyPy. ``Py_REFCNT()`` semantics is different on PyPy.
7+
* 2026-09-22: Add support for PyPy3.12 v8.0.0, which provides
58
``PyFrame_GetCode()`` and ``PyInterpreterState_Get()``.
69
* 2026-09-07: Remove code to support Python 2.7, Python 3.5 and PyPy
710
for Python 2.7 ("pypy2").

pythoncapi_compat.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,8 @@ PyConfig_GetInt(const char *name, int *value)
21322132

21332133
// gh-133144 added PyUnstable_Object_IsUniquelyReferenced() to Python 3.14.0b1.
21342134
// Adapted from _PyObject_IsUniquelyReferenced() implementation.
2135-
#if PY_VERSION_HEX < 0x030E00B0
2135+
// Not available on PyPy: Py_REFCNT() semantics is different on PyPy.
2136+
#if PY_VERSION_HEX < 0x030E00B0 && !defined(PYPY_VERSION)
21362137
static inline int PyUnstable_Object_IsUniquelyReferenced(PyObject *obj)
21372138
{
21382139
#if !defined(Py_GIL_DISABLED)
@@ -2150,7 +2151,8 @@ static inline int PyUnstable_Object_IsUniquelyReferenced(PyObject *obj)
21502151

21512152
// gh-128926 added PyUnstable_TryIncRef() and PyUnstable_EnableTryIncRef() to
21522153
// Python 3.14.0a5. Adapted from _Py_TryIncref() and _PyObject_SetMaybeWeakref().
2153-
#if PY_VERSION_HEX < 0x030E00A5
2154+
// Not available on PyPy: Py_REFCNT() semantics is different on PyPy.
2155+
#if PY_VERSION_HEX < 0x030E00A5 && !defined(PYPY_VERSION)
21542156
static inline int PyUnstable_TryIncRef(PyObject *op)
21552157
{
21562158
#ifndef Py_GIL_DISABLED
@@ -2221,7 +2223,7 @@ static inline void PyUnstable_EnableTryIncRef(PyObject *op)
22212223
(void)op; // unused argument
22222224
#endif
22232225
}
2224-
#endif
2226+
#endif // PY_VERSION_HEX < 0x030E00A5 && !defined(PYPY_VERSION)
22252227

22262228

22272229
#if PY_VERSION_HEX < 0x030F0000

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: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,7 @@ test_unicodewriter_format(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19561956
}
19571957
#endif
19581958

1959+
#ifndef PYPY_VERSION
19591960
static PyObject *
19601961
test_uniquely_referenced(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19611962
{
@@ -1975,6 +1976,7 @@ test_uniquely_referenced(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args))
19751976

19761977
Py_RETURN_NONE;
19771978
}
1979+
#endif // !PYPY_VERSION
19781980

19791981
static PyObject *
19801982
test_bytes(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
@@ -2419,7 +2421,9 @@ test_tuple(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
24192421
return test_tuple_fromarray();
24202422
}
24212423

2422-
// Test adapted from CPython's _testcapi/object.c
2424+
// Test adapted from CPython's _testcapi/object.c.
2425+
// PyUnstable_TryIncRef() is not available on PyPy.
2426+
#ifndef PYPY_VERSION
24232427
static int TryIncref_dealloc_called = 0;
24242428

24252429
static void
@@ -2458,6 +2462,7 @@ test_try_incref(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
24582462
assert(TryIncref_dealloc_called == 1);
24592463
Py_RETURN_NONE;
24602464
}
2465+
#endif // !PYPY_VERSION
24612466

24622467
#if 0x030D0000 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
24632468
static PyObject *
@@ -2545,10 +2550,14 @@ static struct PyMethodDef methods[] = {
25452550
{"test_config", test_config, METH_NOARGS, _Py_NULL},
25462551
#endif
25472552
{"test_sys", test_sys, METH_NOARGS, _Py_NULL},
2553+
#ifndef PYPY_VERSION
25482554
{"test_uniquely_referenced", test_uniquely_referenced, METH_NOARGS, _Py_NULL},
2555+
#endif
25492556
{"test_byteswriter", test_byteswriter, METH_NOARGS, _Py_NULL},
25502557
{"test_tuple", test_tuple, METH_NOARGS, _Py_NULL},
2558+
#ifndef PYPY_VERSION
25512559
{"test_try_incref", test_try_incref, METH_NOARGS, _Py_NULL},
2560+
#endif
25522561
#if 0x030D0000 <= PY_VERSION_HEX && !defined(PYPY_VERSION)
25532562
{"test_set_immortal", test_set_immortal, METH_NOARGS, _Py_NULL},
25542563
#endif
@@ -2580,13 +2589,15 @@ module_exec(PyObject *module)
25802589
return -1;
25812590
}
25822591
#endif
2592+
#ifndef PYPY_VERSION
25832593
TryIncrefType.tp_name = "TryIncrefType";
25842594
TryIncrefType.tp_basicsize = sizeof(PyObject);
25852595
TryIncrefType.tp_dealloc = TryIncref_dealloc;
25862596
TryIncrefType.tp_free = PyObject_Del;
25872597
if (PyType_Ready(&TryIncrefType) < 0) {
25882598
return -1;
25892599
}
2600+
#endif
25902601
return 0;
25912602
}
25922603

0 commit comments

Comments
 (0)