diff --git a/jedi/evaluate/instance.py b/jedi/evaluate/instance.py index 4f325b40..6e12c8b0 100644 --- a/jedi/evaluate/instance.py +++ b/jedi/evaluate/instance.py @@ -347,6 +347,7 @@ class InstanceVarArgs(object): class InstanceFunctionExecution(er.FunctionExecutionContext): def __init__(self, instance, parent_context, funcdef, var_args): + self.instance = instance var_args = InstanceVarArgs(instance, funcdef, var_args) super(InstanceFunctionExecution, self).__init__( diff --git a/jedi/evaluate/param.py b/jedi/evaluate/param.py index a401db4e..170f1c71 100644 --- a/jedi/evaluate/param.py +++ b/jedi/evaluate/param.py @@ -1,13 +1,11 @@ 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 common from jedi.parser import tree from jedi.evaluate import iterable from jedi.evaluate import analysis -from jedi.evaluate import precedence from jedi.evaluate import context @@ -29,6 +27,8 @@ def try_iter_content(types, depth=0): class AbstractArguments(): + context = None + def eval_argument_clinic(self, parameters): """Uses a list with argument clinic information (see PEP 436).""" iterator = self.unpack() @@ -54,16 +54,17 @@ class AbstractArguments(): # TODO this method doesn't work with named args and a lot of other # things. Use unpack. 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): """ Evaluates all arguments as a support for static analysis (normally Jedi). """ + raise DeprecationWarning for key, element_values in self.unpack(): 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) @@ -77,7 +78,7 @@ class TreeArguments(AbstractArguments): :param argument_node: May be an argument_node or a list of nodes. """ self.argument_node = argument_node - self._context = context + self.context = context self._evaluator = evaluator self.trailer = trailer # Can be None, e.g. in a class definition. @@ -110,16 +111,16 @@ class TreeArguments(AbstractArguments): named_args = [] for stars, el in self._split(): if stars == 1: - arrays = self._context.eval_node(el) + arrays = self.context.eval_node(el) iterators = [_iterate_star_args(self._evaluator, a, el, func) for a in arrays] iterators = list(iterators) for values in list(zip_longest(*iterators)): # TODO zip_longest yields None, that means this would raise # an exception? - yield None, context.get_merged_lazy_context(values) + yield None, context.get_merged_lazycontext(values) elif stars == 2: - arrays = self._evaluator.eval_element(self._context, el) + arrays = self._evaluator.eval_element(self.context, el) for dct in arrays: for key, values in _star_star_dict(self._evaluator, dct, el, func): yield key, values @@ -127,14 +128,14 @@ class TreeArguments(AbstractArguments): if tree.is_node(el, 'argument'): c = el.children 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. # Include the brackets with the parent. comp = iterable.GeneratorComprehension( self._evaluator, self.argument_node.parent) yield None, context.LazyKnownContext(comp) 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 # after named argument, but in the actual order it's prepended. diff --git a/jedi/evaluate/stdlib.py b/jedi/evaluate/stdlib.py index 17361952..4bd6a80e 100644 --- a/jedi/evaluate/stdlib.py +++ b/jedi/evaluate/stdlib.py @@ -16,9 +16,9 @@ from jedi._compatibility import unicode from jedi.common import unite from jedi.evaluate import compiled from jedi.evaluate import representation as er +from jedi.evaluate.instance import InstanceFunctionExecution from jedi.evaluate import iterable from jedi.parser import ParserWithRecovery -from jedi.parser import tree from jedi import debug from jedi.evaluate import precedence 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) -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. """ @@ -91,8 +91,8 @@ def argument_clinic(string, want_obj=False, want_scope=False, want_arguments=Fal return set() else: kwargs = {} - if want_scope: - kwargs['scope'] = arguments.scope() + if want_context: + kwargs['context'] = arguments.context if want_obj: kwargs['obj'] = obj if want_arguments: @@ -134,22 +134,12 @@ class SuperInstance(er.Instance): super().__init__(evaluator, su and su[0] or self) -@argument_clinic('[type[, obj]], /', want_scope=True) -def builtins_super(evaluator, types, objects, scope): +@argument_clinic('[type[, obj]], /', want_context=True) +def builtins_super(evaluator, types, objects, context): # TODO make this able to detect multiple inheritance super - accept = (tree.Function, er.FunctionExecution) - if scope.isinstance(*accept): - wanted = (tree.Class, er.Instance) - 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() + if isinstance(context, InstanceFunctionExecution): + su = context.instance.py__class__().py__bases__() + return su[0].infer() return set()