summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2017-07-16 09:16:32 +0200
committerStefan Behnel <stefan_ml@behnel.de>2017-07-16 09:16:32 +0200
commitf7f9ae4c63930d089cebd169665695f8e729beeb (patch)
tree9430ddc1164bb109c8dea5135ea3918c7587328b
parent7ecce71eda300289a591187d316c9c57c0b68e2c (diff)
downloadcython-f7f9ae4c63930d089cebd169665695f8e729beeb.tar.gz
use faster __Pyx_PyObject_GetAttrStr() implementation and avoid static Python string reference in AddTraceback() helper
-rw-r--r--Cython/Compiler/Code.py4
-rw-r--r--Cython/Compiler/ModuleNode.py3
-rw-r--r--Cython/Utility/Exceptions.c14
3 files changed, 7 insertions, 14 deletions
diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py
index d0c473d78..354f299a2 100644
--- a/Cython/Compiler/Code.py
+++ b/Cython/Compiler/Code.py
@@ -2214,7 +2214,7 @@ class CCodeWriter(object):
def put_finish_refcount_context(self):
self.putln("__Pyx_RefNannyFinishContext();")
- def put_add_traceback(self, qualified_name):
+ def put_add_traceback(self, qualified_name, include_cline=True):
"""
Build a Python traceback for propagating exceptions.
@@ -2222,7 +2222,7 @@ class CCodeWriter(object):
"""
format_tuple = (
qualified_name,
- Naming.clineno_cname,
+ Naming.clineno_cname if include_cline else 0,
Naming.lineno_cname,
Naming.filename_cname,
)
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index 645ccf4d8..2949ceeb6 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -2251,9 +2251,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put_label(code.error_label)
for cname, type in code.funcstate.all_managed_temps():
code.put_xdecref(cname, type)
+ # module state might not be ready for traceback generation with C-line handling yet
code.putln('if (%s) {' % env.module_cname)
code.putln('if (%s) {' % env.module_dict_cname)
- code.put_add_traceback("init %s" % env.qualified_name)
+ code.put_add_traceback("init %s" % env.qualified_name, include_cline=False)
code.globalstate.use_utility_code(Nodes.traceback_utility_code)
# Module reference and module dict are in global variables which might still be needed
# for cleanup, atexit code, etc., so leaking is better than crashing.
diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c
index 743278056..de24c9cf8 100644
--- a/Cython/Utility/Exceptions.c
+++ b/Cython/Utility/Exceptions.c
@@ -536,6 +536,7 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
/////////////// AddTraceback ///////////////
//@requires: ModuleSetupCode.c::CodeObjectCache
+//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@substitute: naming
#include "compile.h"
@@ -603,21 +604,12 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
PyObject *use_cline = 0;
PyObject *ptype, *pvalue, *ptraceback;
- static PyObject* cline_in_traceback = NULL;
- if (cline_in_traceback == NULL) {
- #if PY_MAJOR_VERSION < 3
- cline_in_traceback = PyString_FromString("cline_in_traceback");
- #else
- cline_in_traceback = PyUnicode_FromString("cline_in_traceback");
- #endif
- }
-
if (c_line) {
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
- use_cline = PyObject_GetAttr(${cython_runtime_cname}, cline_in_traceback);
+ use_cline = __Pyx_PyObject_GetAttrStr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
if (use_cline == NULL) {
c_line = 0;
- PyObject_SetAttr(${cython_runtime_cname}, cline_in_traceback, Py_False);
+ PyObject_SetAttr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"), Py_False);
}
else if (PyObject_Not(use_cline) != 0) {
c_line = 0;