Issue 13787: PyCode_New not round-trippable (TypeError) (original) (raw)
On Python 3.1.4, attempting to create a code object will apparently result in a TypeError (must be str, not tuple), even when you're creating a code object from another, working code object:
co_what.py
def foo(): return 'bar'
co = foo.code
co_copy = type(co)(co.co_argcount, co.co_kwonlyargcount, co.co_nlocals, co.co_stacksize, co.co_flags, co.co_code, co.co_consts, co.co_names, co.co_varnames, co.co_freevars, co.co_cellvars, co.co_filename, co.co_name, co.co_firstlineno, co.co_lnotab)
EOF
$ python3 co_what.py Traceback (most recent call last): File "co_what.py", line 20, in co.co_lnotab) TypeError: must be str, not tuple
Looking at the PyCode_New function, all the arguments look correctly matched up according to the signature in my Python 3.1.4 build source (looks identical to the trunk source):
Objects/codeobject.c
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 *lnotab) { PyCodeObject *co; Py_ssize_t i;
/* Check argument types */
if (argcount < 0 || nlocals < 0 ||
code == NULL ||
consts == NULL || !PyTuple_Check(consts) ||
names == NULL || !PyTuple_Check(names) ||
varnames == NULL || !PyTuple_Check(varnames) ||
freevars == NULL || !PyTuple_Check(freevars) ||
cellvars == NULL || !PyTuple_Check(cellvars) ||
name == NULL || !PyUnicode_Check(name) ||
filename == NULL || !PyUnicode_Check(filename) ||
lnotab == NULL || !PyBytes_Check(lnotab) ||
!PyObject_CheckReadBuffer(code)) {
PyErr_BadInternalCall();
return NULL;
}And, for the record, this same behavior works just fine in the equivalent Python 2.
Yes, I knew it was an issue with crossed wires somewhere. The Python 2 code doesn't translate well to Python 3 because the function signature changed to add kwargonlycount. And I guess the argument order is substantially different, too, as described in Objects/codeobject.c#l291.
Thanks for clearing that up, though,
Mahmoud