forked from VimPlug/jedi
Fix super calls.
This commit is contained in:
@@ -347,6 +347,7 @@ class InstanceVarArgs(object):
|
|||||||
|
|
||||||
class InstanceFunctionExecution(er.FunctionExecutionContext):
|
class InstanceFunctionExecution(er.FunctionExecutionContext):
|
||||||
def __init__(self, instance, parent_context, funcdef, var_args):
|
def __init__(self, instance, parent_context, funcdef, var_args):
|
||||||
|
self.instance = instance
|
||||||
var_args = InstanceVarArgs(instance, funcdef, var_args)
|
var_args = InstanceVarArgs(instance, funcdef, var_args)
|
||||||
|
|
||||||
super(InstanceFunctionExecution, self).__init__(
|
super(InstanceFunctionExecution, self).__init__(
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from itertools import chain
|
|
||||||
|
|
||||||
from jedi._compatibility import unicode, zip_longest
|
from jedi._compatibility import zip_longest
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import common
|
from jedi import common
|
||||||
from jedi.parser import tree
|
from jedi.parser import tree
|
||||||
from jedi.evaluate import iterable
|
from jedi.evaluate import iterable
|
||||||
from jedi.evaluate import analysis
|
from jedi.evaluate import analysis
|
||||||
from jedi.evaluate import precedence
|
|
||||||
from jedi.evaluate import context
|
from jedi.evaluate import context
|
||||||
|
|
||||||
|
|
||||||
@@ -29,6 +27,8 @@ def try_iter_content(types, depth=0):
|
|||||||
|
|
||||||
|
|
||||||
class AbstractArguments():
|
class AbstractArguments():
|
||||||
|
context = None
|
||||||
|
|
||||||
def eval_argument_clinic(self, parameters):
|
def eval_argument_clinic(self, parameters):
|
||||||
"""Uses a list with argument clinic information (see PEP 436)."""
|
"""Uses a list with argument clinic information (see PEP 436)."""
|
||||||
iterator = self.unpack()
|
iterator = self.unpack()
|
||||||
@@ -54,16 +54,17 @@ class AbstractArguments():
|
|||||||
# TODO this method doesn't work with named args and a lot of other
|
# TODO this method doesn't work with named args and a lot of other
|
||||||
# things. Use unpack.
|
# things. Use unpack.
|
||||||
raise DeprecationWarning
|
raise DeprecationWarning
|
||||||
return [self._evaluator.eval_element(self._context, el) for stars, el in self._split()]
|
return [self._evaluator.eval_element(self.context, el) for stars, el in self._split()]
|
||||||
|
|
||||||
def eval_all(self, func=None):
|
def eval_all(self, func=None):
|
||||||
"""
|
"""
|
||||||
Evaluates all arguments as a support for static analysis
|
Evaluates all arguments as a support for static analysis
|
||||||
(normally Jedi).
|
(normally Jedi).
|
||||||
"""
|
"""
|
||||||
|
raise DeprecationWarning
|
||||||
for key, element_values in self.unpack():
|
for key, element_values in self.unpack():
|
||||||
for element in element_values:
|
for element in element_values:
|
||||||
types = self._evaluator.eval_element(self._context, element)
|
types = self._evaluator.eval_element(self.context, element)
|
||||||
try_iter_content(types)
|
try_iter_content(types)
|
||||||
|
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ class TreeArguments(AbstractArguments):
|
|||||||
:param argument_node: May be an argument_node or a list of nodes.
|
:param argument_node: May be an argument_node or a list of nodes.
|
||||||
"""
|
"""
|
||||||
self.argument_node = argument_node
|
self.argument_node = argument_node
|
||||||
self._context = context
|
self.context = context
|
||||||
self._evaluator = evaluator
|
self._evaluator = evaluator
|
||||||
self.trailer = trailer # Can be None, e.g. in a class definition.
|
self.trailer = trailer # Can be None, e.g. in a class definition.
|
||||||
|
|
||||||
@@ -110,16 +111,16 @@ class TreeArguments(AbstractArguments):
|
|||||||
named_args = []
|
named_args = []
|
||||||
for stars, el in self._split():
|
for stars, el in self._split():
|
||||||
if stars == 1:
|
if stars == 1:
|
||||||
arrays = self._context.eval_node(el)
|
arrays = self.context.eval_node(el)
|
||||||
iterators = [_iterate_star_args(self._evaluator, a, el, func)
|
iterators = [_iterate_star_args(self._evaluator, a, el, func)
|
||||||
for a in arrays]
|
for a in arrays]
|
||||||
iterators = list(iterators)
|
iterators = list(iterators)
|
||||||
for values in list(zip_longest(*iterators)):
|
for values in list(zip_longest(*iterators)):
|
||||||
# TODO zip_longest yields None, that means this would raise
|
# TODO zip_longest yields None, that means this would raise
|
||||||
# an exception?
|
# an exception?
|
||||||
yield None, context.get_merged_lazy_context(values)
|
yield None, context.get_merged_lazycontext(values)
|
||||||
elif stars == 2:
|
elif stars == 2:
|
||||||
arrays = self._evaluator.eval_element(self._context, el)
|
arrays = self._evaluator.eval_element(self.context, el)
|
||||||
for dct in arrays:
|
for dct in arrays:
|
||||||
for key, values in _star_star_dict(self._evaluator, dct, el, func):
|
for key, values in _star_star_dict(self._evaluator, dct, el, func):
|
||||||
yield key, values
|
yield key, values
|
||||||
@@ -127,14 +128,14 @@ class TreeArguments(AbstractArguments):
|
|||||||
if tree.is_node(el, 'argument'):
|
if tree.is_node(el, 'argument'):
|
||||||
c = el.children
|
c = el.children
|
||||||
if len(c) == 3: # Keyword argument.
|
if len(c) == 3: # Keyword argument.
|
||||||
named_args.append((c[0].value, context.LazyTreeContext(self._context, c[2]),))
|
named_args.append((c[0].value, context.LazyTreeContext(self.context, c[2]),))
|
||||||
else: # Generator comprehension.
|
else: # Generator comprehension.
|
||||||
# Include the brackets with the parent.
|
# Include the brackets with the parent.
|
||||||
comp = iterable.GeneratorComprehension(
|
comp = iterable.GeneratorComprehension(
|
||||||
self._evaluator, self.argument_node.parent)
|
self._evaluator, self.argument_node.parent)
|
||||||
yield None, context.LazyKnownContext(comp)
|
yield None, context.LazyKnownContext(comp)
|
||||||
else:
|
else:
|
||||||
yield None, context.LazyTreeContext(self._context, el)
|
yield None, context.LazyTreeContext(self.context, el)
|
||||||
|
|
||||||
# Reordering var_args is necessary, because star args sometimes appear
|
# Reordering var_args is necessary, because star args sometimes appear
|
||||||
# after named argument, but in the actual order it's prepended.
|
# after named argument, but in the actual order it's prepended.
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ from jedi._compatibility import unicode
|
|||||||
from jedi.common import unite
|
from jedi.common import unite
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
|
from jedi.evaluate.instance import InstanceFunctionExecution
|
||||||
from jedi.evaluate import iterable
|
from jedi.evaluate import iterable
|
||||||
from jedi.parser import ParserWithRecovery
|
from jedi.parser import ParserWithRecovery
|
||||||
from jedi.parser import tree
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.evaluate import precedence
|
from jedi.evaluate import precedence
|
||||||
from jedi.evaluate import param
|
from jedi.evaluate import param
|
||||||
@@ -61,7 +61,7 @@ def _follow_param(evaluator, arguments, index):
|
|||||||
return unite(evaluator.eval_element(v) for v in values)
|
return unite(evaluator.eval_element(v) for v in values)
|
||||||
|
|
||||||
|
|
||||||
def argument_clinic(string, want_obj=False, want_scope=False, want_arguments=False):
|
def argument_clinic(string, want_obj=False, want_context=False, want_arguments=False):
|
||||||
"""
|
"""
|
||||||
Works like Argument Clinic (PEP 436), to validate function params.
|
Works like Argument Clinic (PEP 436), to validate function params.
|
||||||
"""
|
"""
|
||||||
@@ -91,8 +91,8 @@ def argument_clinic(string, want_obj=False, want_scope=False, want_arguments=Fal
|
|||||||
return set()
|
return set()
|
||||||
else:
|
else:
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if want_scope:
|
if want_context:
|
||||||
kwargs['scope'] = arguments.scope()
|
kwargs['context'] = arguments.context
|
||||||
if want_obj:
|
if want_obj:
|
||||||
kwargs['obj'] = obj
|
kwargs['obj'] = obj
|
||||||
if want_arguments:
|
if want_arguments:
|
||||||
@@ -134,22 +134,12 @@ class SuperInstance(er.Instance):
|
|||||||
super().__init__(evaluator, su and su[0] or self)
|
super().__init__(evaluator, su and su[0] or self)
|
||||||
|
|
||||||
|
|
||||||
@argument_clinic('[type[, obj]], /', want_scope=True)
|
@argument_clinic('[type[, obj]], /', want_context=True)
|
||||||
def builtins_super(evaluator, types, objects, scope):
|
def builtins_super(evaluator, types, objects, context):
|
||||||
# TODO make this able to detect multiple inheritance super
|
# TODO make this able to detect multiple inheritance super
|
||||||
accept = (tree.Function, er.FunctionExecution)
|
if isinstance(context, InstanceFunctionExecution):
|
||||||
if scope.isinstance(*accept):
|
su = context.instance.py__class__().py__bases__()
|
||||||
wanted = (tree.Class, er.Instance)
|
return su[0].infer()
|
||||||
cls = scope.get_parent_until(accept + wanted,
|
|
||||||
include_current=False)
|
|
||||||
if isinstance(cls, wanted):
|
|
||||||
if isinstance(cls, tree.Class):
|
|
||||||
cls = er.Class(evaluator, cls)
|
|
||||||
elif isinstance(cls, er.Instance):
|
|
||||||
cls = cls.base
|
|
||||||
su = cls.py__bases__()
|
|
||||||
if su:
|
|
||||||
return su[0].infer()
|
|
||||||
return set()
|
return set()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user