pynames.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import rope.base.pyobjects
  2. from rope.base import exceptions, utils
  3. class PyName(object):
  4. """References to `PyObject`\s inside python programs"""
  5. def get_object(self):
  6. """Return the `PyObject` object referenced by this `PyName`"""
  7. def get_definition_location(self):
  8. """Return a (module, lineno) tuple"""
  9. class DefinedName(PyName):
  10. def __init__(self, pyobject):
  11. self.pyobject = pyobject
  12. def get_object(self):
  13. return self.pyobject
  14. def get_definition_location(self):
  15. return (self.pyobject.get_module(), self.pyobject.get_ast().lineno)
  16. class AssignedName(PyName):
  17. """Only a placeholder"""
  18. class UnboundName(PyName):
  19. def __init__(self, pyobject=None):
  20. self.pyobject = pyobject
  21. if self.pyobject is None:
  22. self.pyobject = rope.base.pyobjects.get_unknown()
  23. def get_object(self):
  24. return self.pyobject
  25. def get_definition_location(self):
  26. return (None, None)
  27. class AssignmentValue(object):
  28. """An assigned expression"""
  29. def __init__(self, ast_node, levels=None, evaluation='',
  30. assign_type=False):
  31. """The `level` is `None` for simple assignments and is
  32. a list of numbers for tuple assignments for example in::
  33. a, (b, c) = x
  34. The levels for for `a` is ``[0]``, for `b` is ``[1, 0]`` and for
  35. `c` is ``[1, 1]``.
  36. """
  37. self.ast_node = ast_node
  38. if levels == None:
  39. self.levels = []
  40. else:
  41. self.levels = levels
  42. self.evaluation = evaluation
  43. self.assign_type = assign_type
  44. def get_lineno(self):
  45. return self.ast_node.lineno
  46. class EvaluatedName(PyName):
  47. """A name whose object will be evaluated later"""
  48. def __init__(self, callback, module=None, lineno=None):
  49. self.module = module
  50. self.lineno = lineno
  51. self.callback = callback
  52. self.pyobject = _Inferred(callback, _get_concluded_data(module))
  53. def get_object(self):
  54. return self.pyobject.get()
  55. def get_definition_location(self):
  56. return (self.module, self.lineno)
  57. def invalidate(self):
  58. """Forget the `PyObject` this `PyName` holds"""
  59. self.pyobject.set(None)
  60. class ParameterName(PyName):
  61. """Only a placeholder"""
  62. class ImportedModule(PyName):
  63. def __init__(self, importing_module, module_name=None,
  64. level=0, resource=None):
  65. self.importing_module = importing_module
  66. self.module_name = module_name
  67. self.level = level
  68. self.resource = resource
  69. self.pymodule = _get_concluded_data(self.importing_module)
  70. def _current_folder(self):
  71. resource = self.importing_module.get_module().get_resource()
  72. if resource is None:
  73. return None
  74. return resource.parent
  75. def _get_pymodule(self):
  76. if self.pymodule.get() is None:
  77. pycore = self.importing_module.pycore
  78. if self.resource is not None:
  79. self.pymodule.set(pycore.resource_to_pyobject(self.resource))
  80. elif self.module_name is not None:
  81. try:
  82. if self.level == 0:
  83. pymodule = pycore.get_module(self.module_name,
  84. self._current_folder())
  85. else:
  86. pymodule = pycore.get_relative_module(
  87. self.module_name, self._current_folder(), self.level)
  88. self.pymodule.set(pymodule)
  89. except exceptions.ModuleNotFoundError:
  90. pass
  91. return self.pymodule.get()
  92. def get_object(self):
  93. if self._get_pymodule() is None:
  94. return rope.base.pyobjects.get_unknown()
  95. return self._get_pymodule()
  96. def get_definition_location(self):
  97. pymodule = self._get_pymodule()
  98. if not isinstance(pymodule, rope.base.pyobjects.PyDefinedObject):
  99. return (None, None)
  100. return (pymodule.get_module(), 1)
  101. class ImportedName(PyName):
  102. def __init__(self, imported_module, imported_name):
  103. self.imported_module = imported_module
  104. self.imported_name = imported_name
  105. def _get_imported_pyname(self):
  106. try:
  107. result = self.imported_module.get_object()[self.imported_name]
  108. if result != self:
  109. return result
  110. except exceptions.AttributeNotFoundError:
  111. pass
  112. return UnboundName()
  113. @utils.prevent_recursion(rope.base.pyobjects.get_unknown)
  114. def get_object(self):
  115. return self._get_imported_pyname().get_object()
  116. @utils.prevent_recursion(lambda: (None, None))
  117. def get_definition_location(self):
  118. return self._get_imported_pyname().get_definition_location()
  119. def _get_concluded_data(module):
  120. if module is None:
  121. return rope.base.pyobjects._ConcludedData()
  122. return module._get_concluded_data()
  123. def _circular_inference():
  124. raise rope.base.pyobjects.IsBeingInferredError(
  125. 'Circular Object Inference')
  126. class _Inferred(object):
  127. def __init__(self, get_inferred, concluded=None):
  128. self.get_inferred = get_inferred
  129. self.concluded = concluded
  130. if self.concluded is None:
  131. self.temp = None
  132. @utils.prevent_recursion(_circular_inference)
  133. def get(self, *args, **kwds):
  134. if self.concluded is None or self.concluded.get() is None:
  135. self.set(self.get_inferred(*args, **kwds))
  136. if self._get() is None:
  137. self.set(rope.base.pyobjects.get_unknown())
  138. return self._get()
  139. def set(self, pyobject):
  140. if self.concluded is not None:
  141. self.concluded.set(pyobject)
  142. self.temp = pyobject
  143. def _get(self):
  144. if self.concluded is not None:
  145. return self.concluded.get()
  146. return self.temp