From b465df6829a3049402886f83fed401a569df0760 Mon Sep 17 00:00:00 2001 From: Mark Florisson Date: Mon, 1 Nov 2010 22:53:00 +0100 Subject: [PATCH] Add py-globals command Align the values of py-locals, py-globals, cy locals and cy globals according to the maximum length of the variable names --- Cython/Debugger/libcython.py | 38 ++++++++++++++++++++++++------------ Cython/Debugger/libpython.py | 33 ++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/Cython/Debugger/libcython.py b/Cython/Debugger/libcython.py index 272b8265..dac01842 100644 --- a/Cython/Debugger/libcython.py +++ b/Cython/Debugger/libcython.py @@ -248,9 +248,9 @@ class CythonBase(object): return False - def print_cython_var_if_initialized(self, varname): + def print_cython_var_if_initialized(self, varname, max_name_length=None): try: - self.cy.print_.invoke(varname, True) + self.cy.print_.invoke(varname, True, max_name_length) except gdb.GdbError: # variable not initialized yet pass @@ -731,13 +731,18 @@ class CyPrint(CythonCommand): command_class = gdb.COMMAND_DATA @dispatch_on_frame(c_command='print', python_command='py-print') - def invoke(self, name, from_tty): + def invoke(self, name, from_tty, max_name_length=None): cname = self.cy.cy_cname.invoke(name, string=True) try: - print '%s = %s' % (name, gdb.parse_and_eval(cname)) + value = gdb.parse_and_eval(cname) except RuntimeError, e: raise gdb.GdbError("Variable %s is not initialized yet." % (name,)) - + else: + if max_name_length is None: + print '%s = %s' % (name, value) + else: + print '%-*s = %s' % (max_name_length, name, value) + def complete(self): if self.is_cython_function(): f = self.get_cython_function() @@ -757,8 +762,10 @@ class CyLocals(CythonCommand): @dispatch_on_frame(c_command='info locals', python_command='py-locals') def invoke(self, args, from_tty): - for varname in self.get_cython_function().locals: - self.print_cython_var_if_initialized(varname) + local_cython_vars = self.get_cython_function().locals + max_name_length = len(max(local_cython_vars, key=len)) + for varname in local_cython_vars: + self.print_cython_var_if_initialized(varname, max_name_length) class CyGlobals(CythonCommand): @@ -783,10 +790,15 @@ class CyGlobals(CythonCommand): """)) m = m.cast(PyModuleObject.pointer()) - d = libpython.PyObjectPtr.from_pyobject_ptr(m['md_dict']) + pyobject_dict = libpython.PyObjectPtr.from_pyobject_ptr(m['md_dict']) + + module_globals = self.get_cython_function().module.globals + # - 2 for the surrounding quotes + max_name_length = max(len(max(module_globals, key=len)), + len(max(pyobject_dict.iteritems())) - 2) seen = set() - for k, v in d.iteritems(): + for k, v in pyobject_dict.iteritems(): # Note: k and v are values in the inferior, they are # libpython.PyObjectPtr objects @@ -796,12 +808,12 @@ class CyGlobals(CythonCommand): v = v.get_truncated_repr(libpython.MAX_OUTPUT_LEN) seen.add(k) - print '%s = %s' % (k, v) + print '%-*s = %s' % (max_name_length, k, v) - module_globals = self.get_cython_function().module.globals for varname in seen.symmetric_difference(module_globals): - self.print_cython_var_if_initialized(varname) - + self.print_cython_var_if_initialized(varname, max_name_length) + + # Functions class CyCName(gdb.Function, CythonBase): diff --git a/Cython/Debugger/libpython.py b/Cython/Debugger/libpython.py index acd4a88c..0ed013a8 100644 --- a/Cython/Debugger/libpython.py +++ b/Cython/Debugger/libpython.py @@ -1427,12 +1427,6 @@ PyPrint() class PyLocals(gdb.Command): 'Look up the given python variable name, and print it' - def __init__(self): - gdb.Command.__init__ (self, - "py-locals", - gdb.COMMAND_DATA, - gdb.COMPLETE_NONE) - def invoke(self, args, from_tty): name = str(args) @@ -1447,12 +1441,29 @@ class PyLocals(gdb.Command): print 'Unable to read information on python frame' return - for pyop_name, pyop_value in pyop_frame.iter_locals(): - print ('%s = %s' - % (pyop_name.proxyval(set()), - pyop_value.get_truncated_repr(MAX_OUTPUT_LEN))) + namespace = self.get_namespace(pyop_frame) + namespace = [(name.proxyval(set()), val) for name, val in namespace] + + name, val = max(namespace, key=lambda (name, val): len(name)) + max_name_length = len(name) + + for name, pyop_value in namespace: + value = pyop_value.get_truncated_repr(MAX_OUTPUT_LEN) + print ('%-*s = %s' % (max_name_length, name, value)) + + def get_namespace(self, pyop_frame): + return pyop_frame.iter_locals() + + +class PyGlobals(PyLocals): + 'List all the globals in the currently select Python frame' + + def get_namespace(self, pyop_frame): + return pyop_frame.iter_globals() + -PyLocals() +PyLocals("py-locals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) +PyGlobals("py-globals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) class _LoggingState(object): -- 2.26.2