forked from VimPlug/jedi
Super is now working. Still has the same flaws like the old implementation, but the tests are passing.
This commit is contained in:
@@ -233,7 +233,7 @@ class Evaluator(object):
|
||||
if trailer_op == '.':
|
||||
new_types += self.find_types(typ, node)
|
||||
elif trailer_op == '(':
|
||||
new_types += self.execute(typ, node)
|
||||
new_types += self.execute(typ, node, trailer)
|
||||
elif trailer_op == '[':
|
||||
try:
|
||||
get = typ.get_index_types
|
||||
@@ -245,8 +245,8 @@ class Evaluator(object):
|
||||
return new_types
|
||||
|
||||
@debug.increase_indent
|
||||
def execute(self, obj, arguments=()):
|
||||
arguments = param.Arguments(self, arguments)
|
||||
def execute(self, obj, arguments=(), trailer=None):
|
||||
arguments = param.Arguments(self, arguments, trailer)
|
||||
if obj.isinstance(er.Function):
|
||||
obj = obj.get_decorated_func()
|
||||
|
||||
|
||||
@@ -13,13 +13,14 @@ from jedi.evaluate import precedence
|
||||
|
||||
|
||||
class Arguments(pr.Base):
|
||||
def __init__(self, evaluator, argument_node):
|
||||
def __init__(self, evaluator, argument_node, trailer=None):
|
||||
"""
|
||||
The argument_node is either a parser node or a list of evaluated
|
||||
objects.
|
||||
"""
|
||||
self.argument_node = argument_node
|
||||
self._evaluator = evaluator
|
||||
self._trailer = trailer # Can be None, e.g. in a class definition.
|
||||
|
||||
def _split(self):
|
||||
if isinstance(self.argument_node, (tuple, list)):
|
||||
@@ -110,10 +111,14 @@ class Arguments(pr.Base):
|
||||
if not values and not optional:
|
||||
# For the stdlib we always want values. If we don't get them,
|
||||
# that's ok, maybe something is too hard to resolve, however,
|
||||
# we will not proceed with the evaluation of that function.
|
||||
# we will not proceed with the evaluation of that function.
|
||||
raise ValueError
|
||||
yield values
|
||||
|
||||
def scope(self):
|
||||
# Returns the scope in which the arguments are used.
|
||||
return (self._trailer or self.argument_node).get_parent_until(pr.IsScope)
|
||||
|
||||
def eval_args(self):
|
||||
return [self._evaluator.eval_element(el) for stars, el in self._split()]
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ def _follow_param(evaluator, params, index):
|
||||
return [stmt] # just some arbitrary object
|
||||
|
||||
|
||||
def argument_clinic(string, want_obj=False):
|
||||
def argument_clinic(string, want_obj=False, want_scope=False):
|
||||
"""
|
||||
Works like Argument Clinic (PEP 436), to validate function params.
|
||||
"""
|
||||
@@ -83,10 +83,12 @@ def argument_clinic(string, want_obj=False):
|
||||
except ValueError:
|
||||
return []
|
||||
else:
|
||||
kwargs = {}
|
||||
if want_scope:
|
||||
kwargs['scope'] = arguments.scope()
|
||||
if want_obj:
|
||||
return func(evaluator, obj, *lst)
|
||||
else:
|
||||
return func(evaluator, *lst)
|
||||
kwargs['obj'] = obj
|
||||
return func(evaluator, *lst, **kwargs)
|
||||
|
||||
return wrapper
|
||||
return f
|
||||
@@ -127,15 +129,14 @@ class SuperInstance(er.Instance):
|
||||
super().__init__(evaluator, su and su[0] or self)
|
||||
|
||||
|
||||
@argument_clinic('[type[, obj]], /', want_obj=True)
|
||||
def builtins_super(evaluator, obj, types, objects):
|
||||
@argument_clinic('[type[, obj]], /', want_scope=True)
|
||||
def builtins_super(evaluator, types, objects, scope):
|
||||
# TODO make this able to detect multiple inheritance super
|
||||
accept = (pr.Function, er.FunctionExecution)
|
||||
func = obj.get_parent_until(accept)
|
||||
if func.isinstance(*accept):
|
||||
if scope.isinstance(*accept):
|
||||
wanted = (pr.Class, er.Instance)
|
||||
cls = func.get_parent_until(accept + wanted,
|
||||
include_current=False)
|
||||
cls = scope.get_parent_until(accept + wanted,
|
||||
include_current=False)
|
||||
if isinstance(cls, wanted):
|
||||
if isinstance(cls, pr.Class):
|
||||
cls = er.Class(evaluator, cls)
|
||||
|
||||
Reference in New Issue
Block a user