From 49623f8699af5736db1d391559b50e9ac6de79bd Mon Sep 17 00:00:00 2001 From: Mark Florisson Date: Mon, 10 Jan 2011 23:57:08 +0100 Subject: [PATCH] Debugger: Detect whether the scope object and cell and free variables have been initialized for closures --- .../Debugger/Tests/test_libcython_in_gdb.py | 7 +++-- Cython/Debugger/libcython.py | 27 +++++++++---------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Cython/Debugger/Tests/test_libcython_in_gdb.py b/Cython/Debugger/Tests/test_libcython_in_gdb.py index 89ff7fdd..295f8b29 100644 --- a/Cython/Debugger/Tests/test_libcython_in_gdb.py +++ b/Cython/Debugger/Tests/test_libcython_in_gdb.py @@ -384,7 +384,8 @@ class TestClosure(DebugTestCase): def test_inner(self): self.break_and_run_func('inner') - + self.assertEqual('', gdb.execute('cy locals', to_string=True)) + # Allow the Cython-generated code to initialize the scope variable gdb.execute('cy step') @@ -394,10 +395,12 @@ class TestClosure(DebugTestCase): def test_outer(self): self.break_and_run_func('outer') + self.assertEqual('', gdb.execute('cy locals', to_string=True)) # Initialize scope with 'a' uninitialized gdb.execute('cy step') - + self.assertEqual('', gdb.execute('cy locals', to_string=True)) + # Initialize 'a' to 1 gdb.execute('cy step') print_result = gdb.execute('cy print a', to_string=True).strip() diff --git a/Cython/Debugger/libcython.py b/Cython/Debugger/libcython.py index d5f0c48d..82d3479c 100644 --- a/Cython/Debugger/libcython.py +++ b/Cython/Debugger/libcython.py @@ -393,12 +393,12 @@ class CythonBase(object): if islocal: cyvar = cython_func.locals[local_name] if '->' in cyvar.cname: - # Closed over free variable - try: - gdb.parse_and_eval(cyvar.cname) + # Closed over free variable + if self.get_cython_lineno() >= cython_func.lineno + 1: + if cyvar.type == PythonObject: + return long(gdb.parse_and_eval(cyvar.cname)) return True - except RuntimeError: - return False + return False cur_lineno = self.get_cython_lineno() return (local_name in cython_func.arguments or @@ -1302,17 +1302,16 @@ class CyCValue(CyCName): @require_cython_frame @gdb_function_value_to_unicode def invoke(self, cyname, frame=None): - try: + globals_dict = self.get_cython_globals_dict() + cython_function = self.get_cython_function(frame) + + if self.is_initialized(cython_function, cyname): cname = super(CyCValue, self).invoke(cyname, frame=frame) return gdb.parse_and_eval(cname) - except (gdb.GdbError, RuntimeError), e: - # variable exists but may not have been initialized yet, or may be - # in the globals dict of the Cython module - d = self.get_cython_globals_dict() - if cyname in d: - return d[cyname]._gdbval - - raise gdb.GdbError(str(e)) + elif cyname in globals_dict: + return globals_dict[cyname]._gdbval + else: + raise gdb.GdbError("Variable %s is not initialized." % cyname) class CyLine(gdb.Function, CythonBase): -- 2.26.2