Ronny Pfannschmidt avatar Ronny Pfannschmidt committed ab9af67

condition and exception scopes also can escape via return

Comments (0)

Files changed (2)

pyflakes/checker.py

         self.globals = {}
 
 class ConditionScope(Scope):
-    #: set of the scope raises and may be discarded for promotion
-    raises = False
+    #: set of the scope leaves and may be discarded for promotion
+    escapes = False
 
     def __init__(self, parent):
         self.parent = parent
             self.addBinding(node.lineno, importation)
 
     def RETURN(self, node):
+        self.scope.escapes = True
         if not node.value:
             return
         self.handleNode(node.value, node)
             handler_scopes.append(self.popScope())
 
         #XXX complicated logic, check
-        valid_scopes = [scope for scope in handler_scopes if not scope.raises]
+        valid_scopes = [scope for scope in handler_scopes if not scope.escapes]
         if valid_scopes:
             common = set(valid_scopes[0])
             for scope in valid_scopes[1:]:
             # when the body scope doesnt raise,
             # its currently the best to consider its names
             # availiable for the orelse part
-            if not body_scope.raises:
+            if not body_scope.escapes:
                 common.update(body_scope)
 
             for name in common:
         """
         mark a scope if a exception is raised in it
         """
-        self.scope.raises = True
+        self.scope.escapes = True
         self.handleChildren(node)
 
 
             self.handleNode(stmt, node)
         else_scope = self.popScope()
 
-        if body_scope.raises and else_scope.raises:
+        if body_scope.escapes and else_scope.escapes:
             pass
-        elif body_scope.raises:
+        elif body_scope.escapes:
             self.scope.update(else_scope)
-        elif else_scope.raises:
+        elif else_scope.escapes:
             self.scope.update(body_scope)
         else:
             #XXX: better scheme for unsure bindings

pyflakes/test/test_scopes.py

             print(a)
         """)
 
+    def test_return_in_else_will_propagate_body(self):
+        self.flakes("""
+            if True:
+                a = 1
+            else:
+                return ValueError
+            print(a)
+        """, m.ExceptionReturn)
+
+    def test_return_in_body_will_propagate_else(self):
+        self.flakes("""
+            if True:
+                return ValueError
+            else:
+                a = 1
+            print(a)
+        """, m.ExceptionReturn)
 
     def test_nested_propagation(self):
         self.flakes("""
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.