]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-115756: make PyCode_GetFirstFree an unstable API (GH-115781)
authorBogdan Romanyuk <65823030+wrongnull@users.noreply.github.com>
Tue, 19 Mar 2024 09:20:38 +0000 (12:20 +0300)
committerGitHub <noreply@github.com>
Tue, 19 Mar 2024 09:20:38 +0000 (09:20 +0000)
Doc/c-api/code.rst
Doc/whatsnew/3.13.rst
Include/cpython/code.h
Misc/NEWS.d/next/C API/2024-03-19-09-49-04.gh-issue-115756.4Ls_Tl.rst [new file with mode: 0644]
Objects/frameobject.c
Objects/typeobject.c
Python/ceval.c
Python/compile.c

index f6fdd7574323c7ef6ee15388a0818faebf0a8a08..968c472219c6431055fd3105a688e846a341d0a8 100644 (file)
@@ -34,10 +34,16 @@ bound into a function.
 
    Return the number of free variables in a code object.
 
-.. c:function:: int PyCode_GetFirstFree(PyCodeObject *co)
+.. c:function:: int PyUnstable_Code_GetFirstFree(PyCodeObject *co)
 
    Return the position of the first free variable in a code object.
 
+   .. versionchanged:: 3.13
+
+      Renamed from ``PyCode_GetFirstFree`` as part of :ref:`unstable-c-api`.
+      The old name is deprecated, but will remain available until the
+      signature changes again.
+
 .. c:function:: PyCodeObject* PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
 
    Return a new code object.  If you need a dummy code object to create a frame,
index 0553cc97c5c75af4d7ffc5122a36364160d026b4..0e04dcd196d3063296264f7a23ac5be5ed1a01c0 100644 (file)
@@ -1471,6 +1471,10 @@ Changes in the Python API
   than directories only. Users may add a trailing slash to match only
   directories.
 
+* :c:func:`!PyCode_GetFirstFree` is an ustable API now and has been renamed
+  to :c:func:`PyUnstable_Code_GetFirstFree`.
+  (Contributed by Bogdan Romanyuk in :gh:`115781`)
+
 
 Build Changes
 =============
index 4e7e212fd099db609ec468f2370e401dd2259b8f..d5dac1765638f9c62a7183a6ba823fae2b72bae9 100644 (file)
@@ -226,11 +226,15 @@ static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {
     return op->co_nfreevars;
 }
 
-static inline int PyCode_GetFirstFree(PyCodeObject *op) {
+static inline int PyUnstable_Code_GetFirstFree(PyCodeObject *op) {
     assert(PyCode_Check(op));
     return op->co_nlocalsplus - op->co_nfreevars;
 }
 
+Py_DEPRECATED(3.13) static inline int PyCode_GetFirstFree(PyCodeObject *op) {
+    return PyUnstable_Code_GetFirstFree(op);
+}
+
 #define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive)
 #define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
 
diff --git a/Misc/NEWS.d/next/C API/2024-03-19-09-49-04.gh-issue-115756.4Ls_Tl.rst b/Misc/NEWS.d/next/C API/2024-03-19-09-49-04.gh-issue-115756.4Ls_Tl.rst
new file mode 100644 (file)
index 0000000..6960395
--- /dev/null
@@ -0,0 +1,3 @@
+:c:func:`!PyCode_GetFirstFree` is an ustable API now and has been renamed to
+:c:func:`PyUnstable_Code_GetFirstFree`. (Contributed by Bogdan Romanyuk in
+:gh:`115781`)
index a914c61aac2fd51b717e99700739e5854b4cf0f6..d55c246d80dd6a71a5de4414ed17fffcf62616da 100644 (file)
@@ -1140,7 +1140,7 @@ frame_init_get_vars(_PyInterpreterFrame *frame)
 
     /* Free vars have not been initialized -- Do that */
     PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure;
-    int offset = PyCode_GetFirstFree(co);
+    int offset = PyUnstable_Code_GetFirstFree(co);
     for (int i = 0; i < co->co_nfreevars; ++i) {
         PyObject *o = PyTuple_GET_ITEM(closure, i);
         frame->localsplus[offset + i] = Py_NewRef(o);
index 24f314929851649b23f5386ee5783abe24f25c99..06c2fc8e6ca0724bd2db2792933415568ab698f5 100644 (file)
@@ -10884,7 +10884,7 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co,
 
     // Look for __class__ in the free vars.
     PyTypeObject *type = NULL;
-    int i = PyCode_GetFirstFree(co);
+    int i = PyUnstable_Code_GetFirstFree(co);
     for (; i < co->co_nlocalsplus; i++) {
         assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0);
         PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
index 9dbcd3da3fec27a34ed53ae5fd36e1080b91f659..b35a321c9431231d3f6b2f3538ff8d6cd8078a02 100644 (file)
@@ -2903,7 +2903,7 @@ _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg)
     if (_PyErr_Occurred(tstate))
         return;
     name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg);
-    if (oparg < PyCode_GetFirstFree(co)) {
+    if (oparg < PyUnstable_Code_GetFirstFree(co)) {
         _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError,
                                   UNBOUNDLOCAL_ERROR_MSG, name);
     } else {
index 6b17f3bcaf2264406e1a01c9682bb657fc8772a7..3291d31a5cc8ed42870dad9202f0ebc3fd4855ca 100644 (file)
@@ -1830,7 +1830,7 @@ compiler_make_closure(struct compiler *c, location loc,
                       PyCodeObject *co, Py_ssize_t flags)
 {
     if (co->co_nfreevars) {
-        int i = PyCode_GetFirstFree(co);
+        int i = PyUnstable_Code_GetFirstFree(co);
         for (; i < co->co_nlocalsplus; ++i) {
             /* Bypass com_addop_varname because it will generate
                LOAD_DEREF but LOAD_CLOSURE is needed.