Commit 8bb090b0 authored by Stefan Behnel's avatar Stefan Behnel

make libcython.py Py2/3 compatible to allows its immediate usage from both...

make libcython.py Py2/3 compatible to allows its immediate usage from both versions (and clean it up a little)
parent f4a2df85
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
GDB extension that adds Cython support. GDB extension that adds Cython support.
""" """
from __future__ import with_statement from __future__ import print_function
import sys import sys
import textwrap import textwrap
...@@ -54,6 +54,7 @@ PythonObject = 'PythonObject' ...@@ -54,6 +54,7 @@ PythonObject = 'PythonObject'
_data_types = dict(CObject=CObject, PythonObject=PythonObject) _data_types = dict(CObject=CObject, PythonObject=PythonObject)
_filesystemencoding = sys.getfilesystemencoding() or 'UTF-8' _filesystemencoding = sys.getfilesystemencoding() or 'UTF-8'
# decorators # decorators
def dont_suppress_errors(function): def dont_suppress_errors(function):
...@@ -68,6 +69,7 @@ def dont_suppress_errors(function): ...@@ -68,6 +69,7 @@ def dont_suppress_errors(function):
return wrapper return wrapper
def default_selected_gdb_frame(err=True): def default_selected_gdb_frame(err=True):
def decorator(function): def decorator(function):
@functools.wraps(function) @functools.wraps(function)
...@@ -84,6 +86,7 @@ def default_selected_gdb_frame(err=True): ...@@ -84,6 +86,7 @@ def default_selected_gdb_frame(err=True):
return wrapper return wrapper
return decorator return decorator
def require_cython_frame(function): def require_cython_frame(function):
@functools.wraps(function) @functools.wraps(function)
@require_running_program @require_running_program
...@@ -95,6 +98,7 @@ def require_cython_frame(function): ...@@ -95,6 +98,7 @@ def require_cython_frame(function):
return function(self, *args, **kwargs) return function(self, *args, **kwargs)
return wrapper return wrapper
def dispatch_on_frame(c_command, python_command=None): def dispatch_on_frame(c_command, python_command=None):
def decorator(function): def decorator(function):
@functools.wraps(function) @functools.wraps(function)
...@@ -115,6 +119,7 @@ def dispatch_on_frame(c_command, python_command=None): ...@@ -115,6 +119,7 @@ def dispatch_on_frame(c_command, python_command=None):
return wrapper return wrapper
return decorator return decorator
def require_running_program(function): def require_running_program(function):
@functools.wraps(function) @functools.wraps(function)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
...@@ -152,6 +157,7 @@ class CythonModule(object): ...@@ -152,6 +157,7 @@ class CythonModule(object):
self.lineno_c2cy = {} self.lineno_c2cy = {}
self.functions = {} self.functions = {}
class CythonVariable(object): class CythonVariable(object):
def __init__(self, name, cname, qualified_name, type, lineno): def __init__(self, name, cname, qualified_name, type, lineno):
...@@ -161,6 +167,7 @@ class CythonVariable(object): ...@@ -161,6 +167,7 @@ class CythonVariable(object):
self.type = type self.type = type
self.lineno = int(lineno) self.lineno = int(lineno)
class CythonFunction(CythonVariable): class CythonFunction(CythonVariable):
def __init__(self, def __init__(self,
module, module,
...@@ -297,7 +304,7 @@ class CythonBase(object): ...@@ -297,7 +304,7 @@ class CythonBase(object):
try: try:
source_desc, lineno = self.get_source_desc(frame) source_desc, lineno = self.get_source_desc(frame)
except NoFunctionNameInFrameError: except NoFunctionNameInFrameError:
print '#%-2d Unknown Frame (compile with -g)' % index print('#%-2d Unknown Frame (compile with -g)' % index)
return return
if not is_c and self.is_python_function(frame): if not is_c and self.is_python_function(frame):
...@@ -381,10 +388,9 @@ class CythonBase(object): ...@@ -381,10 +388,9 @@ class CythonBase(object):
typename = '(%s) ' % (value.type,) typename = '(%s) ' % (value.type,)
if max_name_length is None: if max_name_length is None:
print '%s%s = %s%s' % (prefix, name, typename, value) print('%s%s = %s%s' % (prefix, name, typename, value))
else: else:
print '%s%-*s = %s%s' % (prefix, max_name_length, name, typename, print('%s%-*s = %s%s' % (prefix, max_name_length, name, typename, value))
value)
def is_initialized(self, cython_func, local_name): def is_initialized(self, cython_func, local_name):
cyvar = cython_func.locals[local_name] cyvar = cython_func.locals[local_name]
...@@ -473,6 +479,7 @@ class CyGDBError(gdb.GdbError): ...@@ -473,6 +479,7 @@ class CyGDBError(gdb.GdbError):
args = args or (self.msg,) args = args or (self.msg,)
super(CyGDBError, self).__init__(*args) super(CyGDBError, self).__init__(*args)
class NoCythonFunctionInFrameError(CyGDBError): class NoCythonFunctionInFrameError(CyGDBError):
""" """
raised when the user requests the current cython function, which is raised when the user requests the current cython function, which is
...@@ -480,6 +487,7 @@ class NoCythonFunctionInFrameError(CyGDBError): ...@@ -480,6 +487,7 @@ class NoCythonFunctionInFrameError(CyGDBError):
""" """
msg = "Current function is a function cygdb doesn't know about" msg = "Current function is a function cygdb doesn't know about"
class NoFunctionNameInFrameError(NoCythonFunctionInFrameError): class NoFunctionNameInFrameError(NoCythonFunctionInFrameError):
""" """
raised when the name of the C function could not be determined raised when the name of the C function could not be determined
...@@ -509,21 +517,25 @@ class CythonParameter(gdb.Parameter): ...@@ -509,21 +517,25 @@ class CythonParameter(gdb.Parameter):
__nonzero__ = __bool__ # Python 2 __nonzero__ = __bool__ # Python 2
class CompleteUnqualifiedFunctionNames(CythonParameter): class CompleteUnqualifiedFunctionNames(CythonParameter):
""" """
Have 'cy break' complete unqualified function or method names. Have 'cy break' complete unqualified function or method names.
""" """
class ColorizeSourceCode(CythonParameter): class ColorizeSourceCode(CythonParameter):
""" """
Tell cygdb whether to colorize source code. Tell cygdb whether to colorize source code.
""" """
class TerminalBackground(CythonParameter): class TerminalBackground(CythonParameter):
""" """
Tell cygdb about the user's terminal background (light or dark). Tell cygdb about the user's terminal background (light or dark).
""" """
class CythonParameters(object): class CythonParameters(object):
""" """
Simple container class that might get more functionality in the distant Simple container class that might get more functionality in the distant
...@@ -636,7 +648,7 @@ class CyCy(CythonCommand): ...@@ -636,7 +648,7 @@ class CyCy(CythonCommand):
cy_eval = CyEval('cy_eval'), cy_eval = CyEval('cy_eval'),
) )
for command_name, command in commands.iteritems(): for command_name, command in commands.items():
command.cy = self command.cy = self
setattr(self, command_name, command) setattr(self, command_name, command)
...@@ -672,9 +684,8 @@ class CyImport(CythonCommand): ...@@ -672,9 +684,8 @@ class CyImport(CythonCommand):
for arg in string_to_argv(args): for arg in string_to_argv(args):
try: try:
f = open(arg) f = open(arg)
except OSError, e: except OSError as e:
raise gdb.GdbError('Unable to open file %r: %s' % raise gdb.GdbError('Unable to open file %r: %s' % (args, e.args[1]))
(args, e.args[1]))
t = etree.parse(f) t = etree.parse(f)
...@@ -782,9 +793,9 @@ class CyBreak(CythonCommand): ...@@ -782,9 +793,9 @@ class CyBreak(CythonCommand):
if len(funcs) > 1: if len(funcs) > 1:
# multiple functions, let the user pick one # multiple functions, let the user pick one
print 'There are multiple such functions:' print('There are multiple such functions:')
for idx, func in enumerate(funcs): for idx, func in enumerate(funcs):
print '%3d) %s' % (idx, func.qualified_name) print('%3d) %s' % (idx, func.qualified_name))
while True: while True:
try: try:
...@@ -804,7 +815,7 @@ class CyBreak(CythonCommand): ...@@ -804,7 +815,7 @@ class CyBreak(CythonCommand):
break_funcs = [funcs[int(result)]] break_funcs = [funcs[int(result)]]
break break
else: else:
print 'Not understood...' print('Not understood...')
else: else:
break_funcs = [funcs[0]] break_funcs = [funcs[0]]
...@@ -977,7 +988,7 @@ class CyUp(CythonCommand): ...@@ -977,7 +988,7 @@ class CyUp(CythonCommand):
gdb.execute(self._command, to_string=True) gdb.execute(self._command, to_string=True)
while not self.is_relevant_function(gdb.selected_frame()): while not self.is_relevant_function(gdb.selected_frame()):
gdb.execute(self._command, to_string=True) gdb.execute(self._command, to_string=True)
except RuntimeError, e: except RuntimeError as e:
raise gdb.GdbError(*e.args) raise gdb.GdbError(*e.args)
frame = gdb.selected_frame() frame = gdb.selected_frame()
...@@ -1020,7 +1031,7 @@ class CySelect(CythonCommand): ...@@ -1020,7 +1031,7 @@ class CySelect(CythonCommand):
try: try:
gdb.execute('select %d' % (stackdepth - stackno - 1,)) gdb.execute('select %d' % (stackdepth - stackno - 1,))
except RuntimeError, e: except RuntimeError as e:
raise gdb.GdbError(*e.args) raise gdb.GdbError(*e.args)
...@@ -1070,7 +1081,7 @@ class CyList(CythonCommand): ...@@ -1070,7 +1081,7 @@ class CyList(CythonCommand):
sd, lineno = self.get_source_desc() sd, lineno = self.get_source_desc()
source = sd.get_source(lineno - 5, lineno + 5, mark_line=lineno, source = sd.get_source(lineno - 5, lineno + 5, mark_line=lineno,
lex_entire=True) lex_entire=True)
print source print(source)
class CyPrint(CythonCommand): class CyPrint(CythonCommand):
...@@ -1104,7 +1115,8 @@ class CyPrint(CythonCommand): ...@@ -1104,7 +1115,8 @@ class CyPrint(CythonCommand):
return [] return []
sortkey = lambda (name, value): name.lower() sortkey = lambda item: item[0].lower()
class CyLocals(CythonCommand): class CyLocals(CythonCommand):
""" """
...@@ -1157,13 +1169,13 @@ class CyGlobals(CyLocals): ...@@ -1157,13 +1169,13 @@ class CyGlobals(CyLocals):
max_name_length = max(max_globals_len, max_globals_dict_len) max_name_length = max(max_globals_len, max_globals_dict_len)
seen = set() seen = set()
print 'Python globals:' print('Python globals:')
for k, v in sorted(global_python_dict.iteritems(), key=sortkey): for k, v in sorted(global_python_dict.iteritems(), key=sortkey):
v = v.get_truncated_repr(libpython.MAX_OUTPUT_LEN) v = v.get_truncated_repr(libpython.MAX_OUTPUT_LEN)
seen.add(k) seen.add(k)
print ' %-*s = %s' % (max_name_length, k, v) print(' %-*s = %s' % (max_name_length, k, v))
print 'C globals:' print('C globals:')
for name, cyvar in sorted(module_globals.iteritems(), key=sortkey): for name, cyvar in sorted(module_globals.iteritems(), key=sortkey):
if name not in seen: if name not in seen:
try: try:
...@@ -1176,7 +1188,6 @@ class CyGlobals(CyLocals): ...@@ -1176,7 +1188,6 @@ class CyGlobals(CyLocals):
max_name_length, ' ') max_name_length, ' ')
class EvaluateOrExecuteCodeMixin(object): class EvaluateOrExecuteCodeMixin(object):
""" """
Evaluate or execute Python code in a Cython or Python frame. The 'evalcode' Evaluate or execute Python code in a Cython or Python frame. The 'evalcode'
...@@ -1228,7 +1239,6 @@ class EvaluateOrExecuteCodeMixin(object): ...@@ -1228,7 +1239,6 @@ class EvaluateOrExecuteCodeMixin(object):
raise gdb.GdbError("There is no Cython or Python frame on the stack.") raise gdb.GdbError("There is no Cython or Python frame on the stack.")
def _evalcode_cython(self, executor, code, input_type): def _evalcode_cython(self, executor, code, input_type):
with libpython.FetchAndRestoreError(): with libpython.FetchAndRestoreError():
# get the dict of Cython globals and construct a dict in the # get the dict of Cython globals and construct a dict in the
...@@ -1384,6 +1394,7 @@ cython_info = CythonInfo() ...@@ -1384,6 +1394,7 @@ cython_info = CythonInfo()
cy = CyCy.register() cy = CyCy.register()
cython_info.cy = cy cython_info.cy = cy
def register_defines(): def register_defines():
libpython.source_gdb_script(textwrap.dedent("""\ libpython.source_gdb_script(textwrap.dedent("""\
define cy step define cy step
......
This diff is collapsed.
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