Add py-globals command
authorMark Florisson <markflorisson88@gmail.com>
Mon, 1 Nov 2010 21:53:00 +0000 (22:53 +0100)
committerMark Florisson <markflorisson88@gmail.com>
Mon, 1 Nov 2010 21:53:00 +0000 (22:53 +0100)
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
Cython/Debugger/libpython.py

index 272b8265a122f2cb64601b1c37a986f6dac7259a..dac018420f5a8f686545c0e3eac59df0e035b6c2 100644 (file)
@@ -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):
index acd4a88ccb66bc811f78da32685a5f236cb7c2ca..0ed013a8ed60a3c5984bd1107ecc3cca11bbaefc 100644 (file)
@@ -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):