Fix issues with default parameters in functions and classes

Default parameters were resolved at the wrong starting position. Fixes #1044
This commit is contained in:
Dave Halter
2018-03-08 09:59:09 +01:00
parent 14ac6b11b9
commit 51e0d5d12f
4 changed files with 38 additions and 4 deletions

View File

@@ -136,7 +136,7 @@ class ClassContext(use_metaclass(CachedMetaClass, TreeContext)):
arglist = self.tree_node.get_super_arglist() arglist = self.tree_node.get_super_arglist()
if arglist: if arglist:
from jedi.evaluate import arguments from jedi.evaluate import arguments
args = arguments.TreeArguments(self.evaluator, self, arglist) args = arguments.TreeArguments(self.evaluator, self.parent_context, arglist)
return [value for key, value in args.unpack() if key is None] return [value for key, value in args.unpack() if key is None]
else: else:
return [LazyKnownContext(compiled.builtin_from_name(self.evaluator, u'object'))] return [LazyKnownContext(compiled.builtin_from_name(self.evaluator, u'object'))]

View File

@@ -95,7 +95,26 @@ class NameFinder(object):
def get_filters(self, search_global=False): def get_filters(self, search_global=False):
origin_scope = self._get_origin_scope() origin_scope = self._get_origin_scope()
if search_global: if search_global:
return get_global_filters(self._evaluator, self._context, self._position, origin_scope) position = self._position
# For functions and classes the defaults don't belong to the
# function and get evaluated in the context before the function. So
# make sure to exclude the function/class name.
if origin_scope is not None:
ancestor = search_ancestor(origin_scope, 'funcdef', 'classdef', 'lambdef')
lambdef = None
if ancestor == 'lambdef':
# For lambdas it's even more complicated since parts will
# be evaluated later.
lambdef = ancestor
ancestor = search_ancestor(origin_scope, 'funcdef', 'classdef')
if ancestor is not None:
colon = ancestor.children[-2]
if position < colon.start_pos:
if lambdef is None or position < lambdef.children[-2].start_pos:
position = ancestor.start_pos
return get_global_filters(self._evaluator, self._context, position, origin_scope)
else: else:
return self._context.get_filters(search_global, self._position, origin_scope=origin_scope) return self._context.get_filters(search_global, self._position, origin_scope=origin_scope)

View File

@@ -422,17 +422,18 @@ class Super(object):
a = 3 a = 3
def return_sup(self): def return_sup(self):
return 1 return 1
SuperCopy = Super
class TestSuper(Super): class TestSuper(Super):
#? #?
super() super()
def test(self): def test(self):
#? Super() #? SuperCopy()
super() super()
#? ['a'] #? ['a']
super().a super().a
if 1: if 1:
#? Super() #? SuperCopy()
super() super()
def a(): def a():
#? #?
@@ -446,6 +447,17 @@ class TestSuper(Super):
TestSuper().return_sup() TestSuper().return_sup()
Super = 3
class Foo():
def foo(self):
return 1
# Somehow overwriting the same name caused problems (#1044)
class Foo(Foo):
def foo(self):
#? int()
super().foo()
# ----------------- # -----------------
# if flow at class level # if flow at class level
# ----------------- # -----------------

View File

@@ -201,6 +201,9 @@ def default_function(a=default):
#? int() #? int()
default_function() default_function()
def default(a=default):
#? int()
a
# ----------------- # -----------------
# closures # closures