init
This commit is contained in:
commit
38355d2442
9083 changed files with 1225834 additions and 0 deletions
306
.venv/lib/python3.8/site-packages/rope/base/pyobjects.py
Normal file
306
.venv/lib/python3.8/site-packages/rope/base/pyobjects.py
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
from rope.base.fscommands import _decode_data
|
||||
from rope.base import ast, exceptions, utils
|
||||
|
||||
|
||||
class PyObject(object):
|
||||
def __init__(self, type_):
|
||||
if type_ is None:
|
||||
type_ = self
|
||||
self.type = type_
|
||||
|
||||
def get_attributes(self):
|
||||
if self.type is self:
|
||||
return {}
|
||||
return self.type.get_attributes()
|
||||
|
||||
def get_attribute(self, name):
|
||||
if name not in self.get_attributes():
|
||||
raise exceptions.AttributeNotFoundError("Attribute %s not found" % name)
|
||||
return self.get_attributes()[name]
|
||||
|
||||
def get_type(self):
|
||||
return self.type
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""The same as ``get_attribute(key)``"""
|
||||
return self.get_attribute(key)
|
||||
|
||||
def __contains__(self, key):
|
||||
"""The same as ``key in self.get_attributes()``"""
|
||||
return key in self.get_attributes()
|
||||
|
||||
def __eq__(self, obj):
|
||||
"""Check the equality of two `PyObject`
|
||||
|
||||
Currently it is assumed that instances (the direct instances
|
||||
of `PyObject`, not the instances of its subclasses) are equal
|
||||
if their types are equal. For every other object like
|
||||
defineds or builtins rope assumes objects are reference
|
||||
objects and their identities should match.
|
||||
|
||||
"""
|
||||
if self.__class__ != obj.__class__:
|
||||
return False
|
||||
if type(self) == PyObject:
|
||||
if self is not self.type:
|
||||
return self.type == obj.type
|
||||
else:
|
||||
return self.type is obj.type
|
||||
return self is obj
|
||||
|
||||
def __ne__(self, obj):
|
||||
return not self.__eq__(obj)
|
||||
|
||||
def __hash__(self):
|
||||
"""See docs for `__eq__()` method"""
|
||||
if type(self) == PyObject and self != self.type:
|
||||
return hash(self.type) + 1
|
||||
else:
|
||||
return super(PyObject, self).__hash__()
|
||||
|
||||
def __iter__(self):
|
||||
"""The same as ``iter(self.get_attributes())``"""
|
||||
return iter(self.get_attributes())
|
||||
|
||||
_types = None
|
||||
_unknown = None
|
||||
|
||||
@staticmethod
|
||||
def _get_base_type(name):
|
||||
if PyObject._types is None:
|
||||
PyObject._types = {}
|
||||
base_type = PyObject(None)
|
||||
PyObject._types["Type"] = base_type
|
||||
PyObject._types["Module"] = PyObject(base_type)
|
||||
PyObject._types["Function"] = PyObject(base_type)
|
||||
PyObject._types["Unknown"] = PyObject(base_type)
|
||||
return PyObject._types[name]
|
||||
|
||||
|
||||
def get_base_type(name):
|
||||
"""Return the base type with name `name`.
|
||||
|
||||
The base types are 'Type', 'Function', 'Module' and 'Unknown'. It
|
||||
was used to check the type of a `PyObject` but currently its use
|
||||
is discouraged. Use classes defined in this module instead.
|
||||
For example instead of
|
||||
``pyobject.get_type() == get_base_type('Function')`` use
|
||||
``isinstance(pyobject, AbstractFunction)``.
|
||||
|
||||
You can use `AbstractClass` for classes, `AbstractFunction` for
|
||||
functions, and `AbstractModule` for modules. You can also use
|
||||
`PyFunction` and `PyClass` for testing if an object is
|
||||
defined somewhere and rope can access its source. These classes
|
||||
provide more methods.
|
||||
|
||||
"""
|
||||
return PyObject._get_base_type(name)
|
||||
|
||||
|
||||
def get_unknown():
|
||||
"""Return a pyobject whose type is unknown
|
||||
|
||||
Note that two unknown objects are equal. So for example you can
|
||||
write::
|
||||
|
||||
if pyname.get_object() == get_unknown():
|
||||
print('cannot determine what this pyname holds')
|
||||
|
||||
Rope could have used `None` for indicating unknown objects but
|
||||
we had to check that in many places. So actually this method
|
||||
returns a null object.
|
||||
|
||||
"""
|
||||
if PyObject._unknown is None:
|
||||
PyObject._unknown = PyObject(get_base_type("Unknown"))
|
||||
return PyObject._unknown
|
||||
|
||||
|
||||
class AbstractClass(PyObject):
|
||||
def __init__(self):
|
||||
super(AbstractClass, self).__init__(get_base_type("Type"))
|
||||
|
||||
def get_name(self):
|
||||
pass
|
||||
|
||||
def get_doc(self):
|
||||
pass
|
||||
|
||||
def get_superclasses(self):
|
||||
return []
|
||||
|
||||
|
||||
class AbstractFunction(PyObject):
|
||||
def __init__(self):
|
||||
super(AbstractFunction, self).__init__(get_base_type("Function"))
|
||||
|
||||
def get_name(self):
|
||||
pass
|
||||
|
||||
def get_doc(self):
|
||||
pass
|
||||
|
||||
def get_param_names(self, special_args=True):
|
||||
return []
|
||||
|
||||
def get_returned_object(self, args):
|
||||
return get_unknown()
|
||||
|
||||
|
||||
class AbstractModule(PyObject):
|
||||
def __init__(self, doc=None):
|
||||
super(AbstractModule, self).__init__(get_base_type("Module"))
|
||||
|
||||
def get_doc(self):
|
||||
pass
|
||||
|
||||
def get_resource(self):
|
||||
pass
|
||||
|
||||
|
||||
class PyDefinedObject(object):
|
||||
"""Python defined names that rope can access their sources"""
|
||||
|
||||
def __init__(self, pycore, ast_node, parent):
|
||||
self.pycore = pycore
|
||||
self.ast_node = ast_node
|
||||
self.scope = None
|
||||
self.parent = parent
|
||||
self.structural_attributes = None
|
||||
self.concluded_attributes = self.get_module()._get_concluded_data()
|
||||
self.attributes = self.get_module()._get_concluded_data()
|
||||
self.defineds = None
|
||||
|
||||
visitor_class = None
|
||||
|
||||
@utils.prevent_recursion(lambda: {})
|
||||
def _get_structural_attributes(self):
|
||||
if self.structural_attributes is None:
|
||||
self.structural_attributes = self._create_structural_attributes()
|
||||
return self.structural_attributes
|
||||
|
||||
@utils.prevent_recursion(lambda: {})
|
||||
def _get_concluded_attributes(self):
|
||||
if self.concluded_attributes.get() is None:
|
||||
self._get_structural_attributes()
|
||||
self.concluded_attributes.set(self._create_concluded_attributes())
|
||||
return self.concluded_attributes.get()
|
||||
|
||||
def get_attributes(self):
|
||||
if self.attributes.get() is None:
|
||||
result = dict(self._get_concluded_attributes())
|
||||
result.update(self._get_structural_attributes())
|
||||
self.attributes.set(result)
|
||||
return self.attributes.get()
|
||||
|
||||
def get_attribute(self, name):
|
||||
if name in self._get_structural_attributes():
|
||||
return self._get_structural_attributes()[name]
|
||||
if name in self._get_concluded_attributes():
|
||||
return self._get_concluded_attributes()[name]
|
||||
raise exceptions.AttributeNotFoundError("Attribute %s not found" % name)
|
||||
|
||||
def get_scope(self):
|
||||
if self.scope is None:
|
||||
self.scope = self._create_scope()
|
||||
return self.scope
|
||||
|
||||
def get_module(self):
|
||||
current_object = self
|
||||
while current_object.parent is not None:
|
||||
current_object = current_object.parent
|
||||
return current_object
|
||||
|
||||
def get_doc(self):
|
||||
if len(self.get_ast().body) > 0:
|
||||
expr = self.get_ast().body[0]
|
||||
if isinstance(expr, ast.Expr) and isinstance(expr.value, ast.Str):
|
||||
docstring = expr.value.s
|
||||
coding = self.get_module().coding
|
||||
return _decode_data(docstring, coding)
|
||||
|
||||
def _get_defined_objects(self):
|
||||
if self.defineds is None:
|
||||
self._get_structural_attributes()
|
||||
return self.defineds
|
||||
|
||||
def _create_structural_attributes(self):
|
||||
if self.visitor_class is None:
|
||||
return {}
|
||||
new_visitor = self.visitor_class(self.pycore, self)
|
||||
for child in ast.get_child_nodes(self.ast_node):
|
||||
ast.walk(child, new_visitor)
|
||||
self.defineds = new_visitor.defineds
|
||||
return new_visitor.names
|
||||
|
||||
def _create_concluded_attributes(self):
|
||||
return {}
|
||||
|
||||
def get_ast(self):
|
||||
return self.ast_node
|
||||
|
||||
def _create_scope(self):
|
||||
pass
|
||||
|
||||
|
||||
class PyFunction(PyDefinedObject, AbstractFunction):
|
||||
"""Only a placeholder"""
|
||||
|
||||
|
||||
class PyComprehension(PyDefinedObject, PyObject):
|
||||
"""Only a placeholder"""
|
||||
|
||||
|
||||
class PyClass(PyDefinedObject, AbstractClass):
|
||||
"""Only a placeholder"""
|
||||
|
||||
|
||||
class _ConcludedData(object):
|
||||
def __init__(self):
|
||||
self.data_ = None
|
||||
|
||||
def set(self, data):
|
||||
self.data_ = data
|
||||
|
||||
def get(self):
|
||||
return self.data_
|
||||
|
||||
data = property(get, set)
|
||||
|
||||
def _invalidate(self):
|
||||
self.data = None
|
||||
|
||||
def __str__(self):
|
||||
return "<" + str(self.data) + ">"
|
||||
|
||||
|
||||
class _PyModule(PyDefinedObject, AbstractModule):
|
||||
def __init__(self, pycore, ast_node, resource):
|
||||
self.resource = resource
|
||||
self.concluded_data = []
|
||||
AbstractModule.__init__(self)
|
||||
PyDefinedObject.__init__(self, pycore, ast_node, None)
|
||||
|
||||
def _get_concluded_data(self):
|
||||
new_data = _ConcludedData()
|
||||
self.concluded_data.append(new_data)
|
||||
return new_data
|
||||
|
||||
def _forget_concluded_data(self):
|
||||
for data in self.concluded_data:
|
||||
data._invalidate()
|
||||
|
||||
def get_resource(self):
|
||||
return self.resource
|
||||
|
||||
|
||||
class PyModule(_PyModule):
|
||||
"""Only a placeholder"""
|
||||
|
||||
|
||||
class PyPackage(_PyModule):
|
||||
"""Only a placeholder"""
|
||||
|
||||
|
||||
class IsBeingInferredError(exceptions.RopeError):
|
||||
pass
|
||||
Loading…
Add table
Add a link
Reference in a new issue