Skip to content

Commit

Permalink
Exceptions.c: use PyCode_NewEmpty() in Py3 instead of PyCode_New() (G…
Browse files Browse the repository at this point in the history
…H-4479)

With reference to #4365 (comment)
in Python 3 PyCode_NewEmpty does everything we need to set
exception traceback code objects.

This change is probably only a real improvement on Py3.11 onwards
(where the replacement for PyCode_new is currently pretty slow).
On earlier version it'll probably be fairly similar (maybe one extra allocation for the cline case?)
  • Loading branch information
da-woods authored and scoder committed Dec 5, 2021
1 parent f100ead commit 3edcef4
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions Cython/Utility/Exceptions.c
Expand Up @@ -709,31 +709,33 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
const char *funcname, int c_line,
int py_line, const char *filename) {
PyCodeObject *py_code = 0;
PyObject *py_srcfile = 0;
PyObject *py_funcname = 0;

PyCodeObject *py_code = NULL;
PyObject *py_funcname = NULL;
#if PY_MAJOR_VERSION < 3
PyObject *py_srcfile = NULL;

py_srcfile = PyString_FromString(filename);
#else
py_srcfile = PyUnicode_FromString(filename);
#endif
if (!py_srcfile) goto bad;
#endif

if (c_line) {
#if PY_MAJOR_VERSION < 3
py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, $cfilenm_cname, c_line);
if (!py_funcname) goto bad;
#else
py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, $cfilenm_cname, c_line);
if (!py_funcname) goto bad;
funcname = PyUnicode_AsUTF8(py_funcname);
if (!funcname) goto bad;
#endif
}
else {
#if PY_MAJOR_VERSION < 3
py_funcname = PyString_FromString(funcname);
#else
py_funcname = PyUnicode_FromString(funcname);
if (!py_funcname) goto bad;
#endif
}
if (!py_funcname) goto bad;
#if PY_MAJOR_VERSION < 3
py_code = __Pyx_PyCode_New(
0, /*int argcount,*/
0, /*int kwonlyargcount,*/
Expand All @@ -752,11 +754,16 @@ static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
$empty_bytes /*PyObject *lnotab*/
);
Py_DECREF(py_srcfile);
Py_DECREF(py_funcname);
#else
py_code = PyCode_NewEmpty(filename, funcname, py_line);
#endif
Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline
return py_code;
bad:
Py_XDECREF(py_srcfile);
Py_XDECREF(py_funcname);
#if PY_MAJOR_VERSION < 3
Py_XDECREF(py_srcfile);
#endif
return NULL;
}

Expand Down

0 comments on commit 3edcef4

Please sign in to comment.