ast.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import _ast
  2. from _ast import *
  3. from rope.base import fscommands
  4. def parse(source, filename='<string>'):
  5. # NOTE: the raw string should be given to `compile` function
  6. if isinstance(source, unicode):
  7. source = fscommands.unicode_to_file_data(source)
  8. if '\r' in source:
  9. source = source.replace('\r\n', '\n').replace('\r', '\n')
  10. if not source.endswith('\n'):
  11. source += '\n'
  12. try:
  13. return compile(source, filename, 'exec', _ast.PyCF_ONLY_AST)
  14. except (TypeError, ValueError), e:
  15. error = SyntaxError()
  16. error.lineno = 1
  17. error.filename = filename
  18. error.msg = str(e)
  19. raise error
  20. def walk(node, walker):
  21. """Walk the syntax tree"""
  22. method_name = '_' + node.__class__.__name__
  23. method = getattr(walker, method_name, None)
  24. if method is not None:
  25. if isinstance(node, _ast.ImportFrom) and node.module is None:
  26. # In python < 2.7 ``node.module == ''`` for relative imports
  27. # but for python 2.7 it is None. Generalizing it to ''.
  28. node.module = ''
  29. return method(node)
  30. for child in get_child_nodes(node):
  31. walk(child, walker)
  32. def get_child_nodes(node):
  33. if isinstance(node, _ast.Module):
  34. return node.body
  35. result = []
  36. if node._fields is not None:
  37. for name in node._fields:
  38. child = getattr(node, name)
  39. if isinstance(child, list):
  40. for entry in child:
  41. if isinstance(entry, _ast.AST):
  42. result.append(entry)
  43. if isinstance(child, _ast.AST):
  44. result.append(child)
  45. return result
  46. def call_for_nodes(node, callback, recursive=False):
  47. """If callback returns `True` the child nodes are skipped"""
  48. result = callback(node)
  49. if recursive and not result:
  50. for child in get_child_nodes(node):
  51. call_for_nodes(child, callback, recursive)
  52. def get_children(node):
  53. result = []
  54. if node._fields is not None:
  55. for name in node._fields:
  56. if name in ['lineno', 'col_offset']:
  57. continue
  58. child = getattr(node, name)
  59. result.append(child)
  60. return result