Skip to content

Commit 33abddf

Browse files
committed
Also fix references in make_gen and __code__
1 parent 096d20f commit 33abddf

3 files changed

Lines changed: 80 additions & 17 deletions

File tree

Objects/clinic/funcobject.c.h

Lines changed: 51 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/funcobject.c

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -630,22 +630,33 @@ class function "PyFunctionObject *" "&PyFunction_Type"
630630

631631
#include "clinic/funcobject.c.h"
632632

633+
/*[clinic input]
634+
@critical_section
635+
@getter
636+
function.__code__
637+
[clinic start generated code]*/
638+
633639
static PyObject *
634-
func_get_code(PyObject *self, void *Py_UNUSED(ignored))
640+
function___code___get_impl(PyFunctionObject *self)
641+
/*[clinic end generated code: output=da514d8da1cae70f input=71be2f0bec958b7e]*/
635642
{
636-
PyFunctionObject *op = _PyFunction_CAST(self);
637-
if (PySys_Audit("object.__getattr__", "Os", op, "__code__") < 0) {
643+
if (PySys_Audit("object.__getattr__", "Os", self, "__code__") < 0) {
638644
return NULL;
639645
}
640646

641-
return Py_NewRef(op->func_code);
647+
return Py_NewRef(self->func_code);
642648
}
643649

650+
/*[clinic input]
651+
@critical_section
652+
@setter
653+
function.__code__
654+
[clinic start generated code]*/
655+
644656
static int
645-
func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
657+
function___code___set_impl(PyFunctionObject *self, PyObject *value)
658+
/*[clinic end generated code: output=3a90ece2bfc881d9 input=19f6eba9ab5d7b28]*/
646659
{
647-
PyFunctionObject *op = _PyFunction_CAST(self);
648-
649660
/* Not legal to del f.func_code or to set it to anything
650661
* other than a code object. */
651662
if (value == NULL || !PyCode_Check(value)) {
@@ -655,23 +666,23 @@ func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
655666
}
656667

657668
if (PySys_Audit("object.__setattr__", "OsO",
658-
op, "__code__", value) < 0) {
669+
self, "__code__", value) < 0) {
659670
return -1;
660671
}
661672

662673
int nfree = ((PyCodeObject *)value)->co_nfreevars;
663-
Py_ssize_t nclosure = (op->func_closure == NULL ? 0 :
664-
PyTuple_GET_SIZE(op->func_closure));
674+
Py_ssize_t nclosure = (self->func_closure == NULL ? 0 :
675+
PyTuple_GET_SIZE(self->func_closure));
665676
if (nclosure != nfree) {
666677
PyErr_Format(PyExc_ValueError,
667678
"%U() requires a code object with %zd free vars,"
668679
" not %d",
669-
op->func_name,
680+
self->func_name,
670681
nclosure, nfree);
671682
return -1;
672683
}
673684

674-
PyObject *func_code = PyFunction_GET_CODE(op);
685+
PyObject *func_code = PyFunction_GET_CODE(self);
675686
int old_flags = ((PyCodeObject *)func_code)->co_flags;
676687
int new_flags = ((PyCodeObject *)value)->co_flags;
677688
int mask = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR;
@@ -684,9 +695,9 @@ func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
684695
}
685696
}
686697

687-
handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value);
688-
_PyFunction_ClearVersion(op);
689-
Py_XSETREF(op->func_code, Py_NewRef(value));
698+
handle_func_event(PyFunction_EVENT_MODIFY_CODE, self, value);
699+
_PyFunction_ClearVersion(self);
700+
Py_XSETREF(self->func_code, Py_NewRef(value));
690701
return 0;
691702
}
692703

@@ -994,7 +1005,7 @@ _Py_set_function_type_params(PyThreadState *Py_UNUSED(ignored), PyObject *func,
9941005
}
9951006

9961007
static PyGetSetDef func_getsetlist[] = {
997-
{"__code__", func_get_code, func_set_code},
1008+
FUNCTION___CODE___GETSETDEF
9981009
{"__defaults__", func_get_defaults, func_set_defaults},
9991010
{"__kwdefaults__", func_get_kwdefaults, func_set_kwdefaults},
10001011
FUNCTION___ANNOTATIONS___GETSETDEF

Objects/genobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,10 +1106,12 @@ make_gen(PyTypeObject *type, PyFunctionObject *func)
11061106
gen->gi_exc_state.exc_value = NULL;
11071107
gen->gi_exc_state.previous_item = NULL;
11081108
gen->gi_iframe.f_executable = PyStackRef_None;
1109+
Py_BEGIN_CRITICAL_SECTION((PyObject *)func);
11091110
assert(func->func_name != NULL);
11101111
gen->gi_name = Py_NewRef(func->func_name);
11111112
assert(func->func_qualname != NULL);
11121113
gen->gi_qualname = Py_NewRef(func->func_qualname);
1114+
Py_END_CRITICAL_SECTION();
11131115
_PyObject_GC_TRACK(gen);
11141116
return (PyObject *)gen;
11151117
}

0 commit comments

Comments
 (0)