[Zope-Checkins] CVS: Zope/lib/python/Products/PythonScripts - PythonScript.py:1.40.2.1
Shane Hathaway
shane@cvs.zope.org
Fri, 8 Mar 2002 11:42:12 -0500
Update of /cvs-repository/Zope/lib/python/Products/PythonScripts
In directory cvs.zope.org:/tmp/cvs-serv2444
Modified Files:
Tag: shane-better-tracebacks-branch
PythonScript.py
Log Message:
Added traceback supplements to PythonScripts and added comments about
the possible weaknesses of the current way functions are used.
=== Zope/lib/python/Products/PythonScripts/PythonScript.py 1.40 => 1.40.2.1 ===
'_getitem_': guarded_getitem,
'_write_': full_write_guard,
- '_print_': RestrictedPython.PrintCollector
+ '_print_': RestrictedPython.PrintCollector,
}
l = {}
exec code in g, l
@@ -286,15 +286,24 @@
# Got a cached value.
return result
- __traceback_info__ = bound_names, args, kw, self.func_defaults
+ #__traceback_info__ = bound_names, args, kw, self.func_defaults
f = self._v_f
if f is None:
+ __traceback_supplement__ = (
+ PythonScriptTracebackSupplement, self)
raise RuntimeError, '%s %s has errors.' % (self.meta_type, self.id)
+
if bound_names is not None:
- # Updating func_globals directly *should* be thread-safe.
+ # XXX This causes the whole acquisition chain
+ # to be held by self._v_f. I think we really should
+ # use new.function() instead, similar to
+ # CMFCore.FSPythonScript. new.function() takes
+ # about 8 microseconds on a 1 GHz Athlon. - Shane
f.func_globals.update(bound_names)
-
+ f.func_globals['__traceback_supplement__'] = (
+ PythonScriptTracebackSupplement, self, -1)
+
# Execute the function in a new security context.
security=getSecurityManager()
security.addContext(self)
@@ -466,6 +475,15 @@
if RESPONSE is not None:
RESPONSE.setHeader('Content-Type', 'text/plain')
return self.read()
+
+
+class PythonScriptTracebackSupplement:
+ """Implementation of Products.ErrorReporter.ITracebackSupplement"""
+ def __init__(self, script, line=0):
+ self.manageable_object = script
+ # If line is set to -1, it means to use tb_lineno.
+ self.line = line
+
_first_indent = re.compile('(?m)^ *(?! |$)')
_nonempty_line = re.compile('(?m)^(.*\S.*)$')