eric6/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py

changeset 7064
1010f737def2
parent 7060
d04e8965af91
child 7360
9190402e4505
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():
                 """

eric ide

mercurial