PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/tool/error.py

https://bitbucket.org/akdominguez/pypy-rst-fix
Python | 163 lines | 155 code | 6 blank | 2 comment | 15 complexity | c6211914aad37d8af620557d7bd55b4d MD5 | raw file
  1. """ error handling features, just a way of displaying errors
  2. """
  3. from pypy.tool.ansi_print import ansi_log
  4. from pypy.objspace.flow.model import Variable
  5. import sys
  6. import py
  7. log = py.log.Producer("error")
  8. py.log.setconsumer("error", ansi_log)
  9. SHOW_TRACEBACK = False
  10. SHOW_ANNOTATIONS = True
  11. SHOW_DEFAULT_LINES_OF_CODE = 0
  12. from pypy.interpreter.pytraceback import offset2lineno
  13. def source_lines1(graph, block, operindex=None, offset=None, long=False, \
  14. show_lines_of_code=SHOW_DEFAULT_LINES_OF_CODE):
  15. if block is not None:
  16. if block is graph.returnblock:
  17. return ['<return block>']
  18. try:
  19. source = graph.source
  20. except AttributeError:
  21. return ['no source!']
  22. else:
  23. graph_lines = source.split("\n")
  24. if offset is not None:
  25. linestart = offset2lineno(graph.func.func_code, offset)
  26. linerange = (linestart, linestart)
  27. here = None
  28. else:
  29. if block is None or not block.operations:
  30. return []
  31. def toline(operindex):
  32. return offset2lineno(graph.func.func_code, block.operations[operindex].offset)
  33. if operindex is None:
  34. linerange = (toline(0), toline(-1))
  35. if not long:
  36. return ['?']
  37. here = None
  38. else:
  39. operline = toline(operindex)
  40. if long:
  41. linerange = (toline(0), toline(-1))
  42. here = operline
  43. else:
  44. linerange = (operline, operline)
  45. here = None
  46. lines = ["Happened at file %s line %d" % (graph.filename, here or linerange[0]), ""]
  47. for n in range(max(0, linerange[0]-show_lines_of_code), \
  48. min(linerange[1]+1+show_lines_of_code, len(graph_lines)+graph.startline)):
  49. if n == here:
  50. prefix = '==> '
  51. else:
  52. prefix = ' '
  53. lines.append(prefix + graph_lines[n-graph.startline])
  54. lines.append("")
  55. return lines
  56. def source_lines(graph, *args, **kwds):
  57. lines = source_lines1(graph, *args, **kwds)
  58. return ['In %r:' % (graph,)] + lines
  59. class AnnotatorError(Exception):
  60. pass
  61. class NoSuchAttrError(Exception):
  62. pass
  63. class ErrorWrapper(object):
  64. def __init__(self, msg):
  65. self.msg = msg
  66. def __repr__(self):
  67. return '<%s>' % (self.msg,)
  68. def gather_error(annotator, graph, block, operindex):
  69. msg = [""]
  70. if operindex is not None:
  71. oper = block.operations[operindex]
  72. if oper.opname == 'simple_call':
  73. format_simple_call(annotator, oper, msg)
  74. else:
  75. oper = None
  76. msg.append(" " + str(oper))
  77. msg += source_lines(graph, block, operindex, long=True)
  78. if oper is not None:
  79. if SHOW_ANNOTATIONS:
  80. msg.append("Known variable annotations:")
  81. for arg in oper.args + [oper.result]:
  82. if isinstance(arg, Variable):
  83. try:
  84. msg.append(" " + str(arg) + " = " + str(annotator.binding(arg)))
  85. except KeyError:
  86. pass
  87. return "\n".join(msg)
  88. def format_blocked_annotation_error(annotator, blocked_blocks):
  89. text = []
  90. for block, (graph, index) in blocked_blocks.items():
  91. text.append('-+' * 30)
  92. text.append("Blocked block -- operation cannot succeed")
  93. text.append(gather_error(annotator, graph, block, index))
  94. return '\n'.join(text)
  95. def format_simple_call(annotator, oper, msg):
  96. msg.append("Occurred processing the following simple_call:")
  97. try:
  98. descs = annotator.bindings[oper.args[0]].descriptions
  99. except (KeyError, AttributeError), e:
  100. msg.append(" (%s getting at the binding!)" % (
  101. e.__class__.__name__,))
  102. return
  103. for desc in list(descs):
  104. func = desc.pyobj
  105. if func is None:
  106. r = repr(desc)
  107. else:
  108. try:
  109. if isinstance(func, type):
  110. func_name = "%s.__init__" % func.__name__
  111. func = func.__init__.im_func
  112. else:
  113. func_name = func.func_name
  114. r = "function %s <%s, line %s>" % (func_name,
  115. func.func_code.co_filename, func.func_code.co_firstlineno)
  116. except (AttributeError, TypeError):
  117. r = repr(desc)
  118. msg.append(" %s returning" % (r,))
  119. msg.append("")
  120. def debug(drv, use_pdb=True):
  121. # XXX unify some code with pypy.translator.goal.translate
  122. from pypy.translator.tool.pdbplus import PdbPlusShow
  123. from pypy.translator.driver import log
  124. t = drv.translator
  125. class options:
  126. huge = 100
  127. tb = None
  128. import traceback
  129. errmsg = ["Error:\n"]
  130. exc, val, tb = sys.exc_info()
  131. errmsg.extend([" %s" % line for line in traceback.format_exception(exc, val, [])])
  132. block = getattr(val, '__annotator_block', None)
  133. if block:
  134. class FileLike:
  135. def write(self, s):
  136. errmsg.append(" %s" % s)
  137. errmsg.append("Processing block:\n")
  138. t.about(block, FileLike())
  139. log.ERROR(''.join(errmsg))
  140. log.event("start debugger...")
  141. if use_pdb:
  142. pdb_plus_show = PdbPlusShow(t)
  143. pdb_plus_show.start(tb)