1
0
forked from VimPlug/jedi

Use super().__getattribute__ instead of custom AttributeErrors in __getattr__.

This commit is contained in:
Dave Halter
2016-10-21 02:12:54 +02:00
parent cad9ae8ab1
commit 4ccfbb4962
5 changed files with 28 additions and 28 deletions

View File

@@ -63,11 +63,11 @@ class BaseDefinition(object):
""" """
An instance of :class:`jedi.parser.reprsentation.Name` subclass. An instance of :class:`jedi.parser.reprsentation.Name` subclass.
""" """
self._definition = evaluator.wrap(self._name.get_definition()) #self._definition = list(self._name.infer())[0]
self.is_keyword = isinstance(self._definition, keywords.Keyword) #self.is_keyword = isinstance(self._definition, keywords.Keyword)
# generate a path to the definition # generate a path to the definition
self._module = name.get_parent_until() self._module = name.parent_context.get_root_context()
if self.in_builtin_module(): if self.in_builtin_module():
self.module_path = None self.module_path = None
else: else:
@@ -508,6 +508,8 @@ class Completion(BaseDefinition):
def _follow_statements_imports(self): def _follow_statements_imports(self):
# imports completion is very complicated and needs to be treated # imports completion is very complicated and needs to be treated
# separately in Completion. # separately in Completion.
return self._name.infer()
# TODO REMOVE
definition = self._definition definition = self._definition
if definition.isinstance(tree.Import): if definition.isinstance(tree.Import):
i = imports.ImportWrapper(self._evaluator, self._name) i = imports.ImportWrapper(self._evaluator, self._name)

View File

@@ -28,16 +28,12 @@ def get_call_signature_param_names(call_signatures):
def filter_names(evaluator, completion_names, stack, like_name): def filter_names(evaluator, completion_names, stack, like_name):
comp_dct = {} comp_dct = {}
for name in set(completion_names): for name in completion_names:
print(name)
if settings.case_insensitive_completion \ if settings.case_insensitive_completion \
and str(name).lower().startswith(like_name.lower()) \ and name.string_name.lower().startswith(like_name.lower()) \
or str(name).startswith(like_name): or name.string_name.startswith(like_name):
if isinstance(name.parent, (tree.Function, tree.Class)): print(name, name.infer())
# TODO I think this is a hack. It should be an
# er.Function/er.Class before that.
name = evaluator.wrap(name.parent).name
new = classes.Completion( new = classes.Completion(
evaluator, evaluator,
name, name,

View File

@@ -12,7 +12,7 @@ from jedi import debug
from jedi.cache import underscore_memoization, memoize_method from jedi.cache import underscore_memoization, memoize_method
from jedi.parser.tree import Param, Base, Operator from jedi.parser.tree import Param, Base, Operator
from jedi.evaluate.helpers import FakeName from jedi.evaluate.helpers import FakeName
from jedi.evaluate.filters import AbstractFilter from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition
from . import fake from . import fake
@@ -254,19 +254,18 @@ class CompiledObject(Base):
return [] # Builtins don't have imports return [] # Builtins don't have imports
class CompiledName(FakeName): class CompiledName(AbstractNameDefinition):
def __init__(self, evaluator, compiled_obj, name): def __init__(self, evaluator, compiled_obj, name):
super(CompiledName, self).__init__(name)
self._evaluator = evaluator self._evaluator = evaluator
self._compiled_obj = compiled_obj self._compiled_obj = compiled_obj
self.name = name self.string_name = name
def __repr__(self): def __repr__(self):
try: try:
name = self._compiled_obj.name # __name__ is not defined all the time name = self._compiled_obj.name # __name__ is not defined all the time
except AttributeError: except AttributeError:
name = None name = None
return '<%s: (%s).%s>' % (type(self).__name__, name, self.name) return '<%s: (%s).%s>' % (type(self).__name__, name, self.string_name)
def is_definition(self): def is_definition(self):
return True return True
@@ -274,7 +273,7 @@ class CompiledName(FakeName):
@underscore_memoization @underscore_memoization
def infer(self): def infer(self):
module = self._compiled_obj.get_parent_until() module = self._compiled_obj.get_parent_until()
return [_create_from_name(self._evaluator, module, self._compiled_obj, self.name)] return [_create_from_name(self._evaluator, module, self._compiled_obj, self.string_name)]
class LazyNamesDict(object): class LazyNamesDict(object):

View File

@@ -11,11 +11,7 @@ from jedi.common import to_list
class AbstractNameDefinition(object): class AbstractNameDefinition(object):
start_pos = None start_pos = None
string_name = None
@property
@abstractmethod
def string_name(self):
raise NotImplementedError
@abstractmethod @abstractmethod
def infer(self): def infer(self):
@@ -44,7 +40,7 @@ class TreeNameDefinition(AbstractNameDefinition):
return _name_to_types(self.parent_context._evaluator, self.parent_context, self._name, None) return _name_to_types(self.parent_context._evaluator, self.parent_context, self._name, None)
def __repr__(self): def __repr__(self):
return '%s: %s@%s' % (type(self).__name__, self.string_name, self.start_pos) return '<%s: %s@%s>' % (type(self).__name__, self.string_name, self.start_pos)
class AbstractFilter(object): class AbstractFilter(object):
@@ -122,6 +118,7 @@ class FunctionExecutionFilter(ParserTreeFilter):
until_position=None, origin_scope=None): until_position=None, origin_scope=None):
super(FunctionExecutionFilter, self).__init__( super(FunctionExecutionFilter, self).__init__(
evaluator, evaluator,
context,
parser_scope, parser_scope,
until_position, until_position,
origin_scope origin_scope

View File

@@ -67,6 +67,13 @@ class Context(object):
def get_parent_flow_context(self): def get_parent_flow_context(self):
return self.parent_context return self.parent_context
def get_root_context(self):
context = self
while True:
if context.parent_context is None:
return context
context = context.parent_context
class FlowContext(Context): class FlowContext(Context):
def get_parent_flow_context(self): def get_parent_flow_context(self):
@@ -74,7 +81,7 @@ class FlowContext(Context):
return self.parent_context return self.parent_context
class Executed(tree.Base): class Executed(Context, tree.Base):
""" """
An instance is also an executable - because __init__ is called An instance is also an executable - because __init__ is called
:param var_args: The param input array, consist of a parser node or a list. :param var_args: The param input array, consist of a parser node or a list.
@@ -279,8 +286,7 @@ class Instance(use_metaclass(CachedMetaClass, Executed)):
def __getattr__(self, name): def __getattr__(self, name):
if name not in ['start_pos', 'end_pos', 'get_imports', 'type', if name not in ['start_pos', 'end_pos', 'get_imports', 'type',
'doc', 'raw_doc']: 'doc', 'raw_doc']:
raise AttributeError("Instance %s: Don't touch this (%s)!" return super(Instance, self).__getattribute__(name)
% (self, name))
return getattr(self.base, name) return getattr(self.base, name)
def __repr__(self): def __repr__(self):
@@ -615,7 +621,7 @@ class ClassContext(use_metaclass(CachedMetaClass, Context, Wrapper)):
if name not in ['start_pos', 'end_pos', 'parent', 'raw_doc', if name not in ['start_pos', 'end_pos', 'parent', 'raw_doc',
'doc', 'get_imports', 'get_parent_until', 'get_code', 'doc', 'get_imports', 'get_parent_until', 'get_code',
'subscopes', 'names_dict', 'type']: 'subscopes', 'names_dict', 'type']:
raise AttributeError("Don't touch this: %s of %s !" % (name, self)) return super(ClassContext, self).__getattribute__(name)
return getattr(self.base, name) return getattr(self.base, name)
def __repr__(self): def __repr__(self):
@@ -901,7 +907,7 @@ class FunctionExecution(Executed):
def __getattr__(self, name): def __getattr__(self, name):
if name not in ['start_pos', 'end_pos', 'imports', 'name', 'type']: if name not in ['start_pos', 'end_pos', 'imports', 'name', 'type']:
raise AttributeError('Tried to access %s: %s. Why?' % (name, self)) return super(FunctionExecution, self).__getattribute__(name)
return getattr(self.base, name) return getattr(self.base, name)
@common.safe_property @common.safe_property