diff options
author | Gabriele N. Tornetta <P403n1x87@users.noreply.github.com> | 2021-07-07 11:21:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-07 11:21:51 (GMT) |
commit | 2f180ce2cb6e6a7e3c517495e0f4873d6aaf5f2f (patch) | |
tree | 446776f951c764ef32fbe91e80c7928be0fe54b4 /Objects | |
parent | 32096df0e00e692ee6dc688e62213bff0dffd573 (diff) | |
download | cpython-2f180ce2cb6e6a7e3c517495e0f4873d6aaf5f2f.zip cpython-2f180ce2cb6e6a7e3c517495e0f4873d6aaf5f2f.tar.gz cpython-2f180ce2cb6e6a7e3c517495e0f4873d6aaf5f2f.tar.bz2 |
bpo-44530: Add co_qualname field to PyCodeObject (GH-26941)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/clinic/codeobject.c.h | 103 | ||||
-rw-r--r-- | Objects/codeobject.c | 56 | ||||
-rw-r--r-- | Objects/funcobject.c | 4 | ||||
-rw-r--r-- | Objects/genobject.c | 2 |
4 files changed, 104 insertions, 61 deletions
diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index 48aa8d7..d8a95ca 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -5,8 +5,8 @@ preserve PyDoc_STRVAR(code_new__doc__, "code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" " flags, codestring, constants, names, varnames, filename, name,\n" -" firstlineno, linetable, endlinetable, columntable, exceptiontable,\n" -" freevars=(), cellvars=(), /)\n" +" qualname, firstlineno, linetable, endlinetable, columntable,\n" +" exceptiontable, freevars=(), cellvars=(), /)\n" "--\n" "\n" "Create a code object. Not for the faint of heart."); @@ -16,9 +16,10 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *filename, PyObject *name, - int firstlineno, PyObject *linetable, PyObject *endlinetable, - PyObject *columntable, PyObject *exceptiontable, - PyObject *freevars, PyObject *cellvars); + PyObject *qualname, int firstlineno, PyObject *linetable, + PyObject *endlinetable, PyObject *columntable, + PyObject *exceptiontable, PyObject *freevars, + PyObject *cellvars); static PyObject * code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) @@ -36,6 +37,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject *varnames; PyObject *filename; PyObject *name; + PyObject *qualname; int firstlineno; PyObject *linetable; PyObject *endlinetable; @@ -48,7 +50,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) !_PyArg_NoKeywords("code", kwargs)) { goto exit; } - if (!_PyArg_CheckPositional("code", PyTuple_GET_SIZE(args), 17, 19)) { + if (!_PyArg_CheckPositional("code", PyTuple_GET_SIZE(args), 18, 20)) { goto exit; } argcount = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); @@ -111,38 +113,38 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto exit; } name = PyTuple_GET_ITEM(args, 11); - firstlineno = _PyLong_AsInt(PyTuple_GET_ITEM(args, 12)); - if (firstlineno == -1 && PyErr_Occurred()) { + if (!PyUnicode_Check(PyTuple_GET_ITEM(args, 12))) { + _PyArg_BadArgument("code", "argument 13", "str", PyTuple_GET_ITEM(args, 12)); goto exit; } - if (!PyBytes_Check(PyTuple_GET_ITEM(args, 13))) { - _PyArg_BadArgument("code", "argument 14", "bytes", PyTuple_GET_ITEM(args, 13)); + if (PyUnicode_READY(PyTuple_GET_ITEM(args, 12)) == -1) { + goto exit; + } + qualname = PyTuple_GET_ITEM(args, 12); + firstlineno = _PyLong_AsInt(PyTuple_GET_ITEM(args, 13)); + if (firstlineno == -1 && PyErr_Occurred()) { goto exit; } - linetable = PyTuple_GET_ITEM(args, 13); if (!PyBytes_Check(PyTuple_GET_ITEM(args, 14))) { _PyArg_BadArgument("code", "argument 15", "bytes", PyTuple_GET_ITEM(args, 14)); goto exit; } - endlinetable = PyTuple_GET_ITEM(args, 14); + linetable = PyTuple_GET_ITEM(args, 14); if (!PyBytes_Check(PyTuple_GET_ITEM(args, 15))) { _PyArg_BadArgument("code", "argument 16", "bytes", PyTuple_GET_ITEM(args, 15)); goto exit; } - columntable = PyTuple_GET_ITEM(args, 15); + endlinetable = PyTuple_GET_ITEM(args, 15); if (!PyBytes_Check(PyTuple_GET_ITEM(args, 16))) { _PyArg_BadArgument("code", "argument 17", "bytes", PyTuple_GET_ITEM(args, 16)); goto exit; } - exceptiontable = PyTuple_GET_ITEM(args, 16); - if (PyTuple_GET_SIZE(args) < 18) { - goto skip_optional; - } - if (!PyTuple_Check(PyTuple_GET_ITEM(args, 17))) { - _PyArg_BadArgument("code", "argument 18", "tuple", PyTuple_GET_ITEM(args, 17)); + columntable = PyTuple_GET_ITEM(args, 16); + if (!PyBytes_Check(PyTuple_GET_ITEM(args, 17))) { + _PyArg_BadArgument("code", "argument 18", "bytes", PyTuple_GET_ITEM(args, 17)); goto exit; } - freevars = PyTuple_GET_ITEM(args, 17); + exceptiontable = PyTuple_GET_ITEM(args, 17); if (PyTuple_GET_SIZE(args) < 19) { goto skip_optional; } @@ -150,9 +152,17 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) _PyArg_BadArgument("code", "argument 19", "tuple", PyTuple_GET_ITEM(args, 18)); goto exit; } - cellvars = PyTuple_GET_ITEM(args, 18); + freevars = PyTuple_GET_ITEM(args, 18); + if (PyTuple_GET_SIZE(args) < 20) { + goto skip_optional; + } + if (!PyTuple_Check(PyTuple_GET_ITEM(args, 19))) { + _PyArg_BadArgument("code", "argument 20", "tuple", PyTuple_GET_ITEM(args, 19)); + goto exit; + } + cellvars = PyTuple_GET_ITEM(args, 19); skip_optional: - return_value = code_new_impl(type, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, linetable, endlinetable, columntable, exceptiontable, freevars, cellvars); + return_value = code_new_impl(type, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, qualname, firstlineno, linetable, endlinetable, columntable, exceptiontable, freevars, cellvars); exit: return return_value; @@ -164,8 +174,8 @@ PyDoc_STRVAR(code_replace__doc__, " co_flags=-1, co_firstlineno=-1, co_code=None, co_consts=None,\n" " co_names=None, co_varnames=None, co_freevars=None,\n" " co_cellvars=None, co_filename=None, co_name=None,\n" -" co_linetable=None, co_endlinetable=None, co_columntable=None,\n" -" co_exceptiontable=None)\n" +" co_qualname=None, co_linetable=None, co_endlinetable=None,\n" +" co_columntable=None, co_exceptiontable=None)\n" "--\n" "\n" "Return a copy of the code object with new values for the specified fields."); @@ -181,7 +191,8 @@ code_replace_impl(PyCodeObject *self, int co_argcount, PyObject *co_consts, PyObject *co_names, PyObject *co_varnames, PyObject *co_freevars, PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyBytesObject *co_linetable, + PyObject *co_name, PyObject *co_qualname, + PyBytesObject *co_linetable, PyBytesObject *co_endlinetable, PyBytesObject *co_columntable, PyBytesObject *co_exceptiontable); @@ -190,9 +201,9 @@ static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_linetable", "co_endlinetable", "co_columntable", "co_exceptiontable", NULL}; + static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_qualname", "co_linetable", "co_endlinetable", "co_columntable", "co_exceptiontable", NULL}; static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; - PyObject *argsbuf[19]; + PyObject *argsbuf[20]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int co_argcount = self->co_argcount; int co_posonlyargcount = self->co_posonlyargcount; @@ -209,6 +220,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *co_cellvars = self->co_cellvars; PyObject *co_filename = self->co_filename; PyObject *co_name = self->co_name; + PyObject *co_qualname = self->co_qualname; PyBytesObject *co_linetable = (PyBytesObject *)self->co_linetable; PyBytesObject *co_endlinetable = (PyBytesObject *)self->co_endlinetable; PyBytesObject *co_columntable = (PyBytesObject *)self->co_columntable; @@ -371,42 +383,55 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[15]) { - if (!PyBytes_Check(args[15])) { - _PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[15]); + if (!PyUnicode_Check(args[15])) { + _PyArg_BadArgument("replace", "argument 'co_qualname'", "str", args[15]); + goto exit; + } + if (PyUnicode_READY(args[15]) == -1) { goto exit; } - co_linetable = (PyBytesObject *)args[15]; + co_qualname = args[15]; if (!--noptargs) { goto skip_optional_kwonly; } } if (args[16]) { if (!PyBytes_Check(args[16])) { - _PyArg_BadArgument("replace", "argument 'co_endlinetable'", "bytes", args[16]); + _PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[16]); goto exit; } - co_endlinetable = (PyBytesObject *)args[16]; + co_linetable = (PyBytesObject *)args[16]; if (!--noptargs) { goto skip_optional_kwonly; } } if (args[17]) { if (!PyBytes_Check(args[17])) { - _PyArg_BadArgument("replace", "argument 'co_columntable'", "bytes", args[17]); + _PyArg_BadArgument("replace", "argument 'co_endlinetable'", "bytes", args[17]); + goto exit; + } + co_endlinetable = (PyBytesObject *)args[17]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[18]) { + if (!PyBytes_Check(args[18])) { + _PyArg_BadArgument("replace", "argument 'co_columntable'", "bytes", args[18]); goto exit; } - co_columntable = (PyBytesObject *)args[17]; + co_columntable = (PyBytesObject *)args[18]; if (!--noptargs) { goto skip_optional_kwonly; } } - if (!PyBytes_Check(args[18])) { - _PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[18]); + if (!PyBytes_Check(args[19])) { + _PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[19]); goto exit; } - co_exceptiontable = (PyBytesObject *)args[18]; + co_exceptiontable = (PyBytesObject *)args[19]; skip_optional_kwonly: - return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_linetable, co_endlinetable, co_columntable, co_exceptiontable); + return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_linetable, co_endlinetable, co_columntable, co_exceptiontable); exit: return return_value; @@ -448,4 +473,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=a75c9ca013d9bf7d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=12b394f0212b1c1e input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index aa36175..140d5a0 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -242,6 +242,7 @@ _PyCode_Validate(struct _PyCodeConstructor *con) PyTuple_GET_SIZE(con->localsplusnames) != PyBytes_GET_SIZE(con->localspluskinds) || con->name == NULL || !PyUnicode_Check(con->name) || + con->qualname == NULL || !PyUnicode_Check(con->qualname) || con->filename == NULL || !PyUnicode_Check(con->filename) || con->linetable == NULL || !PyBytes_Check(con->linetable) || con->endlinetable == NULL || @@ -300,6 +301,8 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_filename = con->filename; Py_INCREF(con->name); co->co_name = con->name; + Py_INCREF(con->qualname); + co->co_qualname = con->qualname; co->co_flags = con->flags; Py_INCREF(con->code); @@ -359,6 +362,9 @@ _PyCode_New(struct _PyCodeConstructor *con) if (PyUnicode_READY(con->name) < 0) { return NULL; } + if (PyUnicode_READY(con->qualname) < 0) { + return NULL; + } if (PyUnicode_READY(con->filename) < 0) { return NULL; } @@ -393,7 +399,8 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, - PyObject *filename, PyObject *name, int firstlineno, + PyObject *filename, PyObject *name, + PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *endlinetable, PyObject *columntable, PyObject *exceptiontable) { @@ -465,6 +472,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, struct _PyCodeConstructor con = { .filename = filename, .name = name, + .qualname = qualname, .flags = flags, .code = code, @@ -522,15 +530,15 @@ PyCode_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, int firstlineno, - PyObject *linetable, PyObject *endlinetable, + PyObject *filename, PyObject *name, PyObject *qualname, + int firstlineno, PyObject *linetable, PyObject *endlinetable, PyObject *columntable, PyObject *exceptiontable) { return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals, stacksize, flags, code, consts, names, varnames, freevars, cellvars, filename, - name, firstlineno, linetable, endlinetable, - columntable, exceptiontable); + name, qualname, firstlineno, linetable, + endlinetable, columntable, exceptiontable); } PyCodeObject * @@ -562,6 +570,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) struct _PyCodeConstructor con = { .filename = filename_ob, .name = funcname_ob, + .qualname = funcname_ob, .code = emptystring, .firstlineno = firstlineno, .linetable = emptystring, @@ -1210,6 +1219,7 @@ code.__new__ as code_new varnames: object(subclass_of="&PyTuple_Type") filename: unicode name: unicode + qualname: unicode firstlineno: int linetable: object(subclass_of="&PyBytes_Type") endlinetable: object(subclass_of="&PyBytes_Type") @@ -1227,10 +1237,11 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *filename, PyObject *name, - int firstlineno, PyObject *linetable, PyObject *endlinetable, - PyObject *columntable, PyObject *exceptiontable, - PyObject *freevars, PyObject *cellvars) -/*[clinic end generated code: output=014e77ed052be1a9 input=b22afe3c31be0b6e]*/ + PyObject *qualname, int firstlineno, PyObject *linetable, + PyObject *endlinetable, PyObject *columntable, + PyObject *exceptiontable, PyObject *freevars, + PyObject *cellvars) +/*[clinic end generated code: output=e1d2086aa8da7c08 input=ba12d68bd8fa0620]*/ { PyObject *co = NULL; PyObject *ournames = NULL; @@ -1238,8 +1249,8 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, PyObject *ourfreevars = NULL; PyObject *ourcellvars = NULL; - if (PySys_Audit("code.__new__", "OOOiiiiii", - code, filename, name, argcount, posonlyargcount, + if (PySys_Audit("code.__new__", "OOOOiiiiii", + code, filename, name, qualname, argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags) < 0) { goto cleanup; } @@ -1296,9 +1307,9 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, code, consts, ournames, ourvarnames, ourfreevars, ourcellvars, filename, - name, firstlineno, linetable, - endlinetable, columntable, - exceptiontable + name, qualname, firstlineno, + linetable, endlinetable, + columntable, exceptiontable ); cleanup: Py_XDECREF(ournames); @@ -1336,6 +1347,7 @@ code_dealloc(PyCodeObject *co) Py_XDECREF(co->co_cellvars); Py_XDECREF(co->co_filename); Py_XDECREF(co->co_name); + Py_XDECREF(co->co_qualname); Py_XDECREF(co->co_linetable); Py_XDECREF(co->co_endlinetable); Py_XDECREF(co->co_columntable); @@ -1474,6 +1486,7 @@ static PyMemberDef code_memberlist[] = { {"co_names", T_OBJECT, OFF(co_names), READONLY}, {"co_filename", T_OBJECT, OFF(co_filename), READONLY}, {"co_name", T_OBJECT, OFF(co_name), READONLY}, + {"co_qualname", T_OBJECT, OFF(co_qualname), READONLY}, {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY}, {"co_linetable", T_OBJECT, OFF(co_linetable), READONLY}, {"co_endlinetable", T_OBJECT, OFF(co_endlinetable), READONLY}, @@ -1570,6 +1583,7 @@ code.replace co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None co_filename: unicode(c_default="self->co_filename") = None co_name: unicode(c_default="self->co_name") = None + co_qualname: unicode(c_default="self->co_qualname") = None co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None co_endlinetable: PyBytesObject(c_default="(PyBytesObject *)self->co_endlinetable") = None co_columntable: PyBytesObject(c_default="(PyBytesObject *)self->co_columntable") = None @@ -1586,11 +1600,12 @@ code_replace_impl(PyCodeObject *self, int co_argcount, PyObject *co_consts, PyObject *co_names, PyObject *co_varnames, PyObject *co_freevars, PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyBytesObject *co_linetable, + PyObject *co_name, PyObject *co_qualname, + PyBytesObject *co_linetable, PyBytesObject *co_endlinetable, PyBytesObject *co_columntable, PyBytesObject *co_exceptiontable) -/*[clinic end generated code: output=1189cc8699162b11 input=29c8d25567d86c0d]*/ +/*[clinic end generated code: output=da699b6261fddc13 input=a8e93823df0aec35]*/ { #define CHECK_INT_ARG(ARG) \ if (ARG < 0) { \ @@ -1609,8 +1624,8 @@ code_replace_impl(PyCodeObject *self, int co_argcount, #undef CHECK_INT_ARG - if (PySys_Audit("code.__new__", "OOOiiiiii", - co_code, co_filename, co_name, co_argcount, + if (PySys_Audit("code.__new__", "OOOOiiiiii", + co_code, co_filename, co_name, co_qualname, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags) < 0) { return NULL; @@ -1646,8 +1661,9 @@ code_replace_impl(PyCodeObject *self, int co_argcount, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, - co_firstlineno, (PyObject*)co_linetable, (PyObject*)co_endlinetable, - (PyObject*)co_columntable, (PyObject*)co_exceptiontable); + co_qualname, co_firstlineno, (PyObject*)co_linetable, + (PyObject*)co_endlinetable, (PyObject*)co_columntable, + (PyObject*)co_exceptiontable); error: Py_XDECREF(varnames); diff --git a/Objects/funcobject.c b/Objects/funcobject.c index dc27215..4eff6d2 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -22,9 +22,11 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname PyObject *name = code_obj->co_name; assert(name != NULL); Py_INCREF(name); + if (!qualname) { - qualname = name; + qualname = code_obj->co_qualname; } + assert(qualname != NULL); Py_INCREF(qualname); PyObject *consts = code_obj->co_consts; diff --git a/Objects/genobject.c b/Objects/genobject.c index db00d19..27fe15c 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -840,7 +840,7 @@ gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, if (qualname != NULL) gen->gi_qualname = qualname; else - gen->gi_qualname = gen->gi_name; + gen->gi_qualname = gen->gi_code->co_qualname; Py_INCREF(gen->gi_qualname); _PyObject_GC_TRACK(gen); return (PyObject *)gen; |