Commit 9140d0f9 authored by Mark Florisson's avatar Mark Florisson

Debugger closure support

parent e5bb833d
...@@ -1591,6 +1591,11 @@ class DebugTransform(CythonTransform): ...@@ -1591,6 +1591,11 @@ class DebugTransform(CythonTransform):
#self.c_output_file = options.output_file #self.c_output_file = options.output_file
self.c_output_file = result.c_file self.c_output_file = result.c_file
# Closure support, basically treat nested functions as if the AST were
# never nested
self.in_funcdef = False
self.nested_funcdefs = []
# tells visit_NameNode whether it should register step-into functions # tells visit_NameNode whether it should register step-into functions
self.register_stepinto = False self.register_stepinto = False
...@@ -1606,6 +1611,8 @@ class DebugTransform(CythonTransform): ...@@ -1606,6 +1611,8 @@ class DebugTransform(CythonTransform):
# serialize functions # serialize functions
self.tb.start('Functions') self.tb.start('Functions')
self.visitchildren(node) self.visitchildren(node)
for nested_funcdef in self.nested_funcdefs:
self.visit_FuncDefNode(nested_funcdef)
self.tb.end('Functions') self.tb.end('Functions')
# 2.3 compatibility. Serialize global variables # 2.3 compatibility. Serialize global variables
...@@ -1627,6 +1634,12 @@ class DebugTransform(CythonTransform): ...@@ -1627,6 +1634,12 @@ class DebugTransform(CythonTransform):
def visit_FuncDefNode(self, node): def visit_FuncDefNode(self, node):
self.visited.add(node.local_scope.qualified_name) self.visited.add(node.local_scope.qualified_name)
if self.in_funcdef:
if not self.register_stepinto:
self.nested_funcdefs.append(node)
return node
# node.entry.visibility = 'extern' # node.entry.visibility = 'extern'
if node.py_func is None: if node.py_func is None:
pf_cname = '' pf_cname = ''
...@@ -1654,7 +1667,9 @@ class DebugTransform(CythonTransform): ...@@ -1654,7 +1667,9 @@ class DebugTransform(CythonTransform):
self.tb.start('StepIntoFunctions') self.tb.start('StepIntoFunctions')
self.register_stepinto = True self.register_stepinto = True
self.in_funcdef = True
self.visitchildren(node) self.visitchildren(node)
self.in_funcdef = False
self.register_stepinto = False self.register_stepinto = False
self.tb.end('StepIntoFunctions') self.tb.end('StepIntoFunctions')
self.tb.end('Function') self.tb.end('Function')
......
...@@ -182,7 +182,8 @@ class TestDebugTransform(DebuggerTestCase): ...@@ -182,7 +182,8 @@ class TestDebugTransform(DebuggerTestCase):
self.assertEqual('PythonObject', xml_globals.get('python_var')) self.assertEqual('PythonObject', xml_globals.get('python_var'))
# test functions # test functions
funcnames = 'codefile.spam', 'codefile.ham', 'codefile.eggs' funcnames = ('codefile.spam', 'codefile.ham', 'codefile.eggs',
'codefile.closure', 'codefile.inner')
required_xml_attrs = 'name', 'cname', 'qualified_name' required_xml_attrs = 'name', 'cname', 'qualified_name'
assert all([f in xml_funcs for f in funcnames]) assert all([f in xml_funcs for f in funcnames])
spam, ham, eggs = [xml_funcs[funcname] for funcname in funcnames] spam, ham, eggs = [xml_funcs[funcname] for funcname in funcnames]
......
...@@ -22,15 +22,21 @@ def spam(a=0): ...@@ -22,15 +22,21 @@ def spam(a=0):
os.path.join("foo", "bar") os.path.join("foo", "bar")
some_c_function() some_c_function()
cdef ham(): cpdef eggs():
pass pass
cpdef eggs(): cdef ham():
pass pass
cdef class SomeClass(object): cdef class SomeClass(object):
def spam(self): def spam(self):
pass pass
def closure():
a = 1
def inner():
b = 2
return inner
spam() spam()
print "bye!" print "bye!"
...@@ -98,7 +98,7 @@ class TestDebugInformationClasses(DebugTestCase): ...@@ -98,7 +98,7 @@ class TestDebugInformationClasses(DebugTestCase):
'codefile.SomeClass.spam') 'codefile.SomeClass.spam')
self.assertEqual(self.spam_func.module, self.module) self.assertEqual(self.spam_func.module, self.module)
assert self.eggs_func.pf_cname assert self.eggs_func.pf_cname, (self.eggs_func, self.eggs_func.pf_cname)
assert not self.ham_func.pf_cname assert not self.ham_func.pf_cname
assert not self.spam_func.pf_cname assert not self.spam_func.pf_cname
assert not self.spam_meth.pf_cname assert not self.spam_meth.pf_cname
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment