diff -r 2bea77c643a0 -r 1010f737def2 eric6/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py --- a/eric6/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py Fri Jul 12 18:10:12 2019 +0200 +++ b/eric6/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py Fri Jul 12 18:11:54 2019 +0200 @@ -514,6 +514,13 @@ """Scope for a doctest.""" +class DummyNode(object): + """Used in place of an `ast.AST` to set error message positions""" + def __init__(self, lineno, col_offset): + self.lineno = lineno + self.col_offset = col_offset + + # Globally defined names which are not attributes of the builtins module, or # are only present on some platforms. _MAGIC_GLOBALS = ['__file__', '__builtins__', 'WindowsError'] @@ -530,13 +537,21 @@ return node.name -def is_typing_overload(value, scope): +def is_typing_overload(value, scope_stack): + def name_is_typing_overload(name): # type: (str) -> bool + for scope in reversed(scope_stack): + if name in scope: + return ( + isinstance(scope[name], ImportationFrom) and + scope[name].fullName == 'typing.overload' + ) + else: + return False + def is_typing_overload_decorator(node): return ( ( - isinstance(node, ast.Name) and - node.id in scope and - scope[node.id].fullName == 'typing.overload' + isinstance(node, ast.Name) and name_is_typing_overload(node.id) ) or ( isinstance(node, ast.Attribute) and isinstance(node.value, ast.Name) and @@ -547,8 +562,10 @@ return ( isinstance(value.source, ast.FunctionDef) and - len(value.source.decorator_list) == 1 and - is_typing_overload_decorator(value.source.decorator_list[0]) + any( + is_typing_overload_decorator(dec) + for dec in value.source.decorator_list + ) ) @@ -887,7 +904,7 @@ node, value.name, existing.source) elif not existing.used and value.redefines(existing): if value.name != '_' or isinstance(existing, Importation): - if not is_typing_overload(existing, self.scope): + if not is_typing_overload(existing, self.scopeStack): self.report(messages.RedefinedWhileUnused, node, value.name, existing.source) @@ -1062,7 +1079,7 @@ part = part.replace('...', 'Ellipsis') self.deferFunction(functools.partial( self.handleStringAnnotation, - part, node, lineno, col_offset, + part, DummyNode(lineno, col_offset), lineno, col_offset, messages.CommentAnnotationSyntaxError, )) @@ -1312,7 +1329,7 @@ node_value = Assignment(node_name, node) # Remove UndefinedName messages already reported for this name. - # TO DO: if the global is not used in this scope, it does not + # TODO: if the global is not used in this scope, it does not # become a globally defined name. See test_unused_global. self.messages = [ m for m in self.messages if not @@ -1471,7 +1488,7 @@ self.pushScope() - self.handleChildren(node, omit='decorator_list') + self.handleChildren(node, omit=['decorator_list', 'returns']) def checkUnusedAssignments(): """