Commits

Amaury Forgeot d'Arc  committed 9ccaaa9

CPython issue 13343: Fix a crash when a lambda expression uses a global
variable in the default value of a keyword-only argument:
(lambda *, arg=GLOBAL_NAME: None)

  • Participants
  • Parent commits 3b8a6e7
  • Branches py3k

Comments (0)

Files changed (4)

File pypy/interpreter/astcompiler/ast.py

             for node in seq:
                 node.walkabout(self)
 
+    def visit_kwonlydefaults(self, seq):
+        if seq is not None:
+            for node in seq:
+                if node:
+                    node.walkabout(self)
+
     def default_visitor(self, node):
         raise NodeVisitorNotImplemented
 

File pypy/interpreter/astcompiler/symtable.py

         args = func.args
         assert isinstance(args, ast.arguments)
         self.visit_sequence(args.defaults)
-        if args.kw_defaults:
-            for arg in args.kw_defaults:
-                if arg:
-                    arg.walkabout(self)
+        self.visit_kwonlydefaults(args.kw_defaults)
         self._visit_annotations(func)
         self.visit_sequence(func.decorator_list)
         new_scope = FunctionScope(func.name, func.lineno, func.col_offset)
         args = lamb.args
         assert isinstance(args, ast.arguments)
         self.visit_sequence(args.defaults)
+        self.visit_kwonlydefaults(args.kw_defaults)
         new_scope = FunctionScope("lambda", lamb.lineno, lamb.col_offset)
         self.push_scope(new_scope, lamb)
         lamb.args.walkabout(self)

File pypy/interpreter/astcompiler/test/test_symtable.py

         scp = self.mod_scope("with x as y: pass")
         assert scp.lookup("_[1]") == symtable.SCOPE_LOCAL
         assert scp.lookup("_[2]") == symtable.SCOPE_LOCAL
+
+    def test_issue13343(self):
+        scp = self.mod_scope("lambda *, k1=x, k2: None")
+        assert scp.lookup("x") == symtable.SCOPE_GLOBAL_IMPLICIT

File pypy/interpreter/astcompiler/tools/asdl_py.py

         self.emit("for node in seq:", 3)
         self.emit("node.walkabout(self)", 4)
         self.emit("")
+        self.emit("def visit_kwonlydefaults(self, seq):", 1)
+        self.emit("if seq is not None:", 2)
+        self.emit("for node in seq:", 3)
+        self.emit("if node:", 4)
+        self.emit("node.walkabout(self)", 5)
+        self.emit("")
         self.emit("def default_visitor(self, node):", 1)
         self.emit("raise NodeVisitorNotImplemented", 2)
         self.emit("")