Skip to content

Commit 85d1bd8

Browse files
authored
Add PyCode_GetCode() function (#34)
1 parent 258f0eb commit 85d1bd8

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

docs/api.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ Latest version of the header file:
2727
Python 3.11
2828
-----------
2929

30+
.. c:function:: PyObject* PyCode_GetCode(PyObject *code)
31+
32+
See `PyCode_GetCode() documentation <https://docs.python.org/dev/c-api/code.html#c.PyCode_GetCode>`__.
33+
34+
Not available on PyPy.
35+
3036
.. c:function:: PyObject* PyFrame_GetBuiltins(PyFrameObject *frame)
3137
3238
See `PyFrame_GetBuiltins() documentation <https://docs.python.org/dev/c-api/frame.html#c.PyFrame_GetBuiltins>`__.

docs/changelog.rst

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

4+
* 2022-05-03: Add ``PyCode_GetCode()`` function.
45
* 2022-04-26: Rename the project from ``pythoncapi_compat`` to
56
``pythoncapi-compat``: replace the underscore separator with a dash.
67
* 2022-04-08: Add functions ``PyFrame_GetLocals()``, ``PyFrame_GetGlobals()``

pythoncapi_compat.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ _PyFrame_GetCodeBorrow(PyFrameObject *frame)
185185
}
186186

187187

188-
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
188+
// bpo-40421 added PyFrame_GetBack() to Python 3.9.0b1
189189
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
190190
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
191191
PyFrame_GetBack(PyFrameObject *frame)
@@ -487,6 +487,15 @@ PyFloat_Unpack8(const char *p, int le)
487487
#endif
488488

489489

490+
// gh-92154 added PyCode_GetCode() to Python 3.11.0b1
491+
#if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION)
492+
PyObject *PyCode_GetCode(PyCodeObject *code)
493+
{
494+
return Py_NewRef(code->co_code);
495+
}
496+
#endif
497+
498+
490499
// Py_UNUSED() was added to Python 3.4.0b2.
491500
#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED)
492501
# if defined(__GNUC__) || defined(__clang__)

tests/test_pythoncapi_compat.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ def main():
149149
global VERBOSE
150150
VERBOSE = ("-v" in sys.argv[1:] or "--verbose" in sys.argv[1:])
151151

152-
# Implementing PyFrame_GetLocals() requires the internal C API in Python
153-
# 3.11 alpha versions
154-
if 0x30b0000 <= sys.hexversion < 0x30b00a7:
152+
# Implementing PyFrame_GetLocals() and PyCode_GetCode() require the
153+
# internal C API in Python 3.11 alpha versions
154+
if 0x30b0000 <= sys.hexversion < 0x30b00b1:
155155
version = sys.version.split()[0]
156156
print("SKIP TESTS: Python %s is not supported" % version)
157157
return

tests/test_pythoncapi_compat_cext.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,30 @@ test_float_pack(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
489489
#endif
490490

491491

492+
#if !defined(PYPY_VERSION)
493+
static PyObject *
494+
test_code(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
495+
{
496+
PyThreadState *tstate = PyThreadState_Get();
497+
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
498+
if (frame == NULL) {
499+
PyErr_SetString(PyExc_AssertionError, "PyThreadState_GetFrame failed");
500+
return NULL;
501+
}
502+
PyCodeObject *code = PyFrame_GetCode(frame);
503+
504+
PyObject *co_code = PyCode_GetCode(code);
505+
assert(co_code != NULL);
506+
assert(PyBytes_Check(co_code));
507+
Py_DECREF(co_code);
508+
509+
Py_DECREF(code);
510+
Py_DECREF(frame);
511+
Py_RETURN_NONE;
512+
}
513+
#endif
514+
515+
492516
static struct PyMethodDef methods[] = {
493517
{"test_object", test_object, METH_NOARGS, NULL},
494518
{"test_py_is", test_py_is, METH_NOARGS, NULL},
@@ -503,6 +527,9 @@ static struct PyMethodDef methods[] = {
503527
{"test_module", test_module, METH_NOARGS, NULL},
504528
#if (PY_VERSION_HEX <= 0x030B00A1 || 0x030B00A7 <= PY_VERSION_HEX) && !defined(PYPY_VERSION)
505529
{"test_float_pack", test_float_pack, METH_NOARGS, NULL},
530+
#endif
531+
#if !defined(PYPY_VERSION)
532+
{"test_code", test_code, METH_NOARGS, NULL},
506533
#endif
507534
{NULL, NULL, 0, NULL}
508535
};

0 commit comments

Comments
 (0)