diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index f1d9386c..ef62c378 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -5,6 +5,7 @@ import inspect import re import sys import os +from functools import partial from jedi._compatibility import builtins as _builtins, unicode from jedi import debug @@ -22,6 +23,19 @@ _path_re = re.compile('(?:\.[^{0}]+|[{0}]__init__\.py)$'.format(re.escape(_sep)) del _sep +class CheckAttribute(object): + """Raises an AttributeError if the attribute X isn't available.""" + def __init__(self, func): + self.func = func + # Remove the py in front of e.g. py__call__. + self.check_name = func.__name__[2:] + + def __get__(self, instance, owner): + # This might raise an AttributeError. That's wanted. + getattr(instance.obj, self.check_name) + return partial(self.func, instance) + + class CompiledObject(Base): # comply with the parser start_pos = 0, 0 @@ -45,9 +59,15 @@ class CompiledObject(Base): self.obj.__call__ return actual + @CheckAttribute + def py__class__(self, evaluator): + return CompiledObject(self.obj.__class__, parent=self.parent) + + @CheckAttribute def py__mro__(self, evaluator): return tuple(create(evaluator, cls) for cls in self.obj.__mro__) + @CheckAttribute def py__bases__(self, evaluator): return tuple(create(evaluator, cls) for cls in self.obj.__bases__) @@ -55,7 +75,7 @@ class CompiledObject(Base): return bool(self.obj) def is_class(self): - return isinstance(self.obj, type) + return inspect.isclass(self.obj) @property def doc(self): diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index b41fa574..ca331c8f 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -110,6 +110,9 @@ class Instance(use_metaclass(CachedMetaClass, Executed)): return actual + def py__class__(self, evaluator): + return self.base + def py__bool__(self): # Signalize that we don't know about the bool type. return None diff --git a/jedi/evaluate/stdlib.py b/jedi/evaluate/stdlib.py index 6ca65ff2..eb991f23 100644 --- a/jedi/evaluate/stdlib.py +++ b/jedi/evaluate/stdlib.py @@ -140,7 +140,7 @@ def builtins_isinstance(evaluator, obj, params): for o in obj: for cls in classes: try: - mro_func = o.base.py__mro__ + mro_func = o.py__class__(evaluator).py__mro__ except AttributeError: return any_bool else: