[pypy-commit] pypy py3.7: yield in comprehensions is now a DeprecationWarning

cfbolz pypy.commits at gmail.com
Wed Jan 22 14:32:52 EST 2020


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.7
Changeset: r98570:f1eb4a075455
Date: 2020-01-22 20:32 +0100
http://bitbucket.org/pypy/pypy/changeset/f1eb4a075455/

Log:	yield in comprehensions is now a DeprecationWarning

diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -577,7 +577,7 @@
         if comp.is_async:
             self.scope.note_await(comp)
 
-    def _visit_comprehension(self, node, comps, *consider):
+    def _visit_comprehension(self, node, kind, comps, *consider):
         outer = comps[0]
         assert isinstance(outer, ast.comprehension)
         outer.iter.walkabout(self)
@@ -591,26 +591,25 @@
         for item in list(consider):
             item.walkabout(self)
         self.pop_scope()
-        # http://bugs.python.org/issue10544: was never fixed in CPython,
-        # but we can at least issue a SyntaxWarning in the meantime
+        # http://bugs.python.org/issue10544: a DeprecationWarning from 3.7 on,
+        # 3.8 will forbid it
         if new_scope.is_generator:
-            msg = ("'yield' inside a list or generator comprehension behaves "
-                   "unexpectedly (http://bugs.python.org/issue10544)")
-            misc.syntax_warning(self.space, msg, self.compile_info.filename,
-                                node.lineno, node.col_offset)
+            msg = "'yield' inside %s" % kind
+            space = self.space
+            space.warn(space.newtext(msg), space.w_DeprecationWarning)
         new_scope.is_generator |= isinstance(node, ast.GeneratorExp)
 
     def visit_ListComp(self, listcomp):
-        self._visit_comprehension(listcomp, listcomp.generators, listcomp.elt)
+        self._visit_comprehension(listcomp, "list comprehension", listcomp.generators, listcomp.elt)
 
     def visit_GeneratorExp(self, genexp):
-        self._visit_comprehension(genexp, genexp.generators, genexp.elt)
+        self._visit_comprehension(genexp, "generator expression", genexp.generators, genexp.elt)
 
     def visit_SetComp(self, setcomp):
-        self._visit_comprehension(setcomp, setcomp.generators, setcomp.elt)
+        self._visit_comprehension(setcomp, "set comprehension", setcomp.generators, setcomp.elt)
 
     def visit_DictComp(self, dictcomp):
-        self._visit_comprehension(dictcomp, dictcomp.generators,
+        self._visit_comprehension(dictcomp, "dict comprehension", dictcomp.generators,
                                   dictcomp.value, dictcomp.key)
 
     def visit_With(self, wih):
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1422,6 +1422,23 @@
         # compiling the produced AST previously triggered a crash
         compile(ast, '', 'exec')
 
+    def test_warn_yield(self):
+        import warnings
+        warnings.simplefilter("error", DeprecationWarning)
+        d = {}
+        with raises(DeprecationWarning) as info:
+            exec("x = [(yield 42) for i in j]", d)
+        assert str(info.value) == "'yield' inside list comprehension"
+        with raises(DeprecationWarning) as info:
+            exec("x = ((yield 42) for i in j)", d)
+        assert str(info.value) == "'yield' inside generator expression"
+        with raises(DeprecationWarning) as info:
+            exec("x = {(yield 42) for i in j}", d)
+        assert str(info.value) == "'yield' inside set comprehension"
+        with raises(DeprecationWarning) as info:
+            exec("x = {(yield 42): blub for i in j}", d)
+        assert str(info.value) == "'yield' inside dict comprehension"
+
 
 class TestOptimizations:
     def count_instructions(self, source):
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -343,7 +343,6 @@
             assert ex.match(self.space, self.space.w_SyntaxError)
 
     def test_globals_warnings(self):
-        # also tests some other constructions that give a warning
         space = self.space
         w_mod = space.appexec((), '():\n import warnings\n return warnings\n') #sys.getmodule('warnings')
         w_filterwarnings = space.getattr(w_mod, space.wrap('filterwarnings'))
@@ -365,18 +364,6 @@
     print x
     x = 2
     global x
-''', '''
-def wrong_listcomp():
-    return [(yield 42) for i in j]
-''', '''
-def wrong_gencomp():
-    return ((yield 42) for i in j)
-''', '''
-def wrong_dictcomp():
-    return {(yield 42):2 for i in j}
-''', '''
-def wrong_setcomp():
-    return {(yield 42) for i in j}
 '''):
 
             space.call_args(w_filterwarnings, filter_arg)


More information about the pypy-commit mailing list