1
0
forked from VimPlug/jedi

Remove the logic to not use getattr on instances in CompiledObjects.

This commit is contained in:
Dave Halter
2016-07-01 18:11:44 +02:00
parent 056ad1b8a8
commit 2652666080
2 changed files with 29 additions and 27 deletions

View File

@@ -83,7 +83,7 @@ class CompiledObject(Base):
def params(self): def params(self):
params_str, ret = self._parse_function_doc() params_str, ret = self._parse_function_doc()
tokens = params_str.split(',') tokens = params_str.split(',')
if inspect.ismethoddescriptor(self._cls().obj): if inspect.ismethoddescriptor(self.obj):
tokens.insert(0, 'self') tokens.insert(0, 'self')
params = [] params = []
for p in tokens: for p in tokens:
@@ -107,20 +107,20 @@ class CompiledObject(Base):
if fake.is_class_instance(self.obj): if fake.is_class_instance(self.obj):
return 'instance' return 'instance'
cls = self._cls().obj obj = self.obj
if inspect.isclass(cls): if inspect.isclass(obj):
return 'class' return 'class'
elif inspect.ismodule(cls): elif inspect.ismodule(obj):
return 'module' return 'module'
elif inspect.isbuiltin(cls) or inspect.ismethod(cls) \ elif inspect.isbuiltin(obj) or inspect.ismethod(obj) \
or inspect.ismethoddescriptor(cls) or inspect.isfunction(cls): or inspect.ismethoddescriptor(obj) or inspect.isfunction(obj):
return 'function' return 'function'
raise NotImplementedError raise NotImplementedError
@property @property
def type(self): def type(self):
"""Imitate the tree.Node.type values.""" """Imitate the tree.Node.type values."""
cls = self._cls().obj cls = self._get_class()
if inspect.isclass(cls): if inspect.isclass(cls):
return 'classdef' return 'classdef'
elif inspect.ismodule(cls): elif inspect.ismodule(cls):
@@ -131,16 +131,23 @@ class CompiledObject(Base):
@underscore_memoization @underscore_memoization
def _cls(self): def _cls(self):
"""
We used to limit the lookups for instantiated objects like list(), but
this is not the case anymore. Python itself
"""
# Ensures that a CompiledObject is returned that is not an instance (like list) # Ensures that a CompiledObject is returned that is not an instance (like list)
if fake.is_class_instance(self.obj): return self
def _get_class(self):
if not fake.is_class_instance(self.obj):
return self.obj
try: try:
c = self.obj.__class__ return self.obj.__class__
except AttributeError: except AttributeError:
# happens with numpy.core.umath._UFUNC_API (you get it # happens with numpy.core.umath._UFUNC_API (you get it
# automatically by doing `import numpy`. # automatically by doing `import numpy`.
c = type(None) return type
return create(self._evaluator, c, self.parent)
return self
@property @property
def names_dict(self): def names_dict(self):
@@ -156,16 +163,11 @@ class CompiledObject(Base):
search_global shouldn't change the fact that there's one dict, this way search_global shouldn't change the fact that there's one dict, this way
there's only one `object`. there's only one `object`.
""" """
cls = self._cls() return [LazyNamesDict(self._evaluator, self, is_instance)]
if cls != self:
# If we are working with a class, the names_dict should not include
# class names.
is_instance = True
return [LazyNamesDict(self._evaluator, cls, is_instance)]
def get_subscope_by_name(self, name): def get_subscope_by_name(self, name):
if name in dir(self._cls().obj): if name in dir(self.obj):
return CompiledName(self._evaluator, self._cls(), name).parent return CompiledName(self._evaluator, self, name).parent
else: else:
raise KeyError("CompiledObject doesn't have an attribute '%s'." % name) raise KeyError("CompiledObject doesn't have an attribute '%s'." % name)
@@ -189,7 +191,7 @@ class CompiledObject(Base):
@property @property
def name(self): def name(self):
# might not exist sometimes (raises AttributeError) # might not exist sometimes (raises AttributeError)
return FakeName(self._cls().obj.__name__, self) return FakeName(self._get_class().__name__, self)
def _execute_function(self, params): def _execute_function(self, params):
if self.type != 'funcdef': if self.type != 'funcdef':
@@ -218,7 +220,7 @@ class CompiledObject(Base):
""" """
module = self.get_parent_until() module = self.get_parent_until()
faked_subscopes = [] faked_subscopes = []
for name in dir(self._cls().obj): for name in dir(self.obj):
f = fake.get_faked(module.obj, self.obj, name) f = fake.get_faked(module.obj, self.obj, name)
if f: if f:
f.parent = self f.parent = self
@@ -269,7 +271,7 @@ class LazyNamesDict(object):
""" """
name_class = CompiledName name_class = CompiledName
def __init__(self, evaluator, compiled_obj, is_instance): def __init__(self, evaluator, compiled_obj, is_instance=False):
self._evaluator = evaluator self._evaluator = evaluator
self._compiled_obj = compiled_obj self._compiled_obj = compiled_obj
self._is_instance = is_instance self._is_instance = is_instance

View File

@@ -35,7 +35,7 @@ class MixedObject(object):
@property @property
def names_dict(self): def names_dict(self):
return LazyMixedNamesDict(self._evaluator, self, is_instance=False) return LazyMixedNamesDict(self._evaluator, self)
def names_dicts(self, search_global): def names_dicts(self, search_global):
# TODO is this needed? # TODO is this needed?