mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 14:34:31 +08:00
Fix super call goto for multiple inheritance, fixes #1311
This commit is contained in:
@@ -241,7 +241,7 @@ class _ContextWrapperBase(HelperContextMixin):
|
|||||||
return cls(*args, **kwargs)
|
return cls(*args, **kwargs)
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
assert name != '_wrapped_context'
|
assert name != '_wrapped_context', 'Problem with _get_wrapped_context'
|
||||||
return getattr(self._wrapped_context, name)
|
return getattr(self._wrapped_context, name)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,9 @@ from jedi.evaluate.arguments import ValuesArguments, \
|
|||||||
repack_with_argument_clinic, AbstractArguments, TreeArgumentsWrapper
|
repack_with_argument_clinic, AbstractArguments, TreeArgumentsWrapper
|
||||||
from jedi.evaluate import analysis
|
from jedi.evaluate import analysis
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate.context.instance import \
|
from jedi.evaluate.context.instance import BoundMethod, InstanceArguments
|
||||||
AbstractInstanceContext, BoundMethod, InstanceArguments
|
|
||||||
from jedi.evaluate.base_context import ContextualizedNode, \
|
from jedi.evaluate.base_context import ContextualizedNode, \
|
||||||
NO_CONTEXTS, ContextSet, ContextWrapper
|
NO_CONTEXTS, ContextSet, ContextWrapper, LazyContextWrapper
|
||||||
from jedi.evaluate.context import ClassContext, ModuleContext, \
|
from jedi.evaluate.context import ClassContext, ModuleContext, \
|
||||||
FunctionExecutionContext
|
FunctionExecutionContext
|
||||||
from jedi.evaluate.context import iterable
|
from jedi.evaluate.context import iterable
|
||||||
@@ -230,20 +229,38 @@ def builtins_type(objects, bases, dicts):
|
|||||||
return objects.py__class__()
|
return objects.py__class__()
|
||||||
|
|
||||||
|
|
||||||
class SuperInstance(AbstractInstanceContext):
|
class SuperInstance(LazyContextWrapper):
|
||||||
"""To be used like the object ``super`` returns."""
|
"""To be used like the object ``super`` returns."""
|
||||||
def __init__(self, evaluator, cls):
|
def __init__(self, evaluator, instance):
|
||||||
su = cls.py_mro()[1]
|
self.evaluator = evaluator
|
||||||
super().__init__(evaluator, su and su[0] or self)
|
self._instance = instance # Corresponds to super().__self__
|
||||||
|
|
||||||
|
def _get_bases(self):
|
||||||
|
return self._instance.py__class__().py__bases__()
|
||||||
|
|
||||||
|
def _get_wrapped_context(self):
|
||||||
|
objs = self._get_bases()[0].infer().execute_evaluated()
|
||||||
|
if not objs:
|
||||||
|
# This is just a fallback and will only be used, if it's not
|
||||||
|
# possible to find a class
|
||||||
|
return self._instance
|
||||||
|
return next(iter(objs))
|
||||||
|
|
||||||
|
def get_filters(self, search_global=False, until_position=None, origin_scope=None):
|
||||||
|
for b in self._get_bases():
|
||||||
|
for obj in b.infer().execute_evaluated():
|
||||||
|
for f in obj.get_filters():
|
||||||
|
yield f
|
||||||
|
|
||||||
|
|
||||||
@argument_clinic('[type[, obj]], /', want_context=True)
|
@argument_clinic('[type[, obj]], /', want_context=True)
|
||||||
def builtins_super(types, objects, context):
|
def builtins_super(types, objects, context):
|
||||||
# TODO make this able to detect multiple inheritance super
|
|
||||||
if isinstance(context, FunctionExecutionContext):
|
if isinstance(context, FunctionExecutionContext):
|
||||||
if isinstance(context.var_args, InstanceArguments):
|
if isinstance(context.var_args, InstanceArguments):
|
||||||
su = context.var_args.instance.py__class__().py__bases__()
|
instance = context.var_args.instance
|
||||||
return su[0].infer().execute_evaluated()
|
# TODO if a class is given it doesn't have to be the direct super
|
||||||
|
# class, it can be an anecestor from long ago.
|
||||||
|
return ContextSet({SuperInstance(instance.evaluator, instance)})
|
||||||
|
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,23 @@ class X():
|
|||||||
#! 3 []
|
#! 3 []
|
||||||
X(foo=x)
|
X(foo=x)
|
||||||
|
|
||||||
|
|
||||||
|
# Multiple inheritance
|
||||||
|
class Foo:
|
||||||
|
def foo(self):
|
||||||
|
print("foo")
|
||||||
|
class Bar:
|
||||||
|
def bar(self):
|
||||||
|
print("bar")
|
||||||
|
class Baz(Foo, Bar):
|
||||||
|
def baz(self):
|
||||||
|
#! ['def foo']
|
||||||
|
super().foo
|
||||||
|
#! ['def bar']
|
||||||
|
super().bar
|
||||||
|
#! ['instance Foo']
|
||||||
|
super()
|
||||||
|
|
||||||
# -----------------
|
# -----------------
|
||||||
# imports
|
# imports
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|||||||
Reference in New Issue
Block a user