Issue #14965: Bring Tools/parser/unparse.py up to date with the Python 3.3. Grammar.

This commit is contained in:
Mark Dickinson 2012-05-06 17:35:19 +01:00
commit fe8440aec0
3 changed files with 60 additions and 19 deletions

View File

@ -28,6 +28,12 @@ Library
- Issue #14127 and #10148: shutil.copystat now preserves exact mtime and atime - Issue #14127 and #10148: shutil.copystat now preserves exact mtime and atime
on filesystems providing nanosecond resolution. on filesystems providing nanosecond resolution.
Tools/Demos
-----------
- Issue #14965: Bring Tools/parser/unparse.py support up to date with
the Python 3.3 Grammar.
What's New in Python 3.3.0 Alpha 3? What's New in Python 3.3.0 Alpha 3?
=================================== ===================================

View File

@ -93,6 +93,21 @@ finally:
suite5 suite5
""" """
with_simple = """\
with f():
suite1
"""
with_as = """\
with f() as x:
suite1
"""
with_two_items = """\
with f() as x, g() as y:
suite1
"""
class ASTTestCase(unittest.TestCase): class ASTTestCase(unittest.TestCase):
def assertASTEqual(self, ast1, ast2): def assertASTEqual(self, ast1, ast2):
self.assertEqual(ast.dump(ast1), ast.dump(ast2)) self.assertEqual(ast.dump(ast1), ast.dump(ast2))
@ -209,6 +224,22 @@ class UnparseTestCase(ASTTestCase):
def test_try_except_finally(self): def test_try_except_finally(self):
self.check_roundtrip(try_except_finally) self.check_roundtrip(try_except_finally)
def test_starred_assignment(self):
self.check_roundtrip("a, *b, c = seq")
self.check_roundtrip("a, (*b, c) = seq")
self.check_roundtrip("a, *b[0], c = seq")
self.check_roundtrip("a, *(b, c) = seq")
def test_with_simple(self):
self.check_roundtrip(with_simple)
def test_with_as(self):
self.check_roundtrip(with_as)
def test_with_two_items(self):
self.check_roundtrip(with_two_items)
class DirectoryTestCase(ASTTestCase): class DirectoryTestCase(ASTTestCase):
"""Test roundtrip behaviour on all files in Lib and Lib/test.""" """Test roundtrip behaviour on all files in Lib and Lib/test."""

View File

@ -147,6 +147,14 @@ class Unparser:
self.dispatch(t.value) self.dispatch(t.value)
self.write(")") self.write(")")
def _YieldFrom(self, t):
self.write("(")
self.write("yield from")
if t.value:
self.write(" ")
self.dispatch(t.value)
self.write(")")
def _Raise(self, t): def _Raise(self, t):
self.fill("raise") self.fill("raise")
if not t.exc: if not t.exc:
@ -158,12 +166,11 @@ class Unparser:
self.write(" from ") self.write(" from ")
self.dispatch(t.cause) self.dispatch(t.cause)
def _TryExcept(self, t): def _Try(self, t):
self.fill("try") self.fill("try")
self.enter() self.enter()
self.dispatch(t.body) self.dispatch(t.body)
self.leave() self.leave()
for ex in t.handlers: for ex in t.handlers:
self.dispatch(ex) self.dispatch(ex)
if t.orelse: if t.orelse:
@ -171,22 +178,12 @@ class Unparser:
self.enter() self.enter()
self.dispatch(t.orelse) self.dispatch(t.orelse)
self.leave() self.leave()
if t.finalbody:
def _TryFinally(self, t): self.fill("finally")
if len(t.body) == 1 and isinstance(t.body[0], ast.TryExcept):
# try-except-finally
self.dispatch(t.body)
else:
self.fill("try")
self.enter() self.enter()
self.dispatch(t.body) self.dispatch(t.finalbody)
self.leave() self.leave()
self.fill("finally")
self.enter()
self.dispatch(t.finalbody)
self.leave()
def _ExceptHandler(self, t): def _ExceptHandler(self, t):
self.fill("except") self.fill("except")
if t.type: if t.type:
@ -296,10 +293,7 @@ class Unparser:
def _With(self, t): def _With(self, t):
self.fill("with ") self.fill("with ")
self.dispatch(t.context_expr) interleave(lambda: self.write(", "), self.dispatch, t.items)
if t.optional_vars:
self.write(" as ")
self.dispatch(t.optional_vars)
self.enter() self.enter()
self.dispatch(t.body) self.dispatch(t.body)
self.leave() self.leave()
@ -472,6 +466,10 @@ class Unparser:
self.dispatch(t.slice) self.dispatch(t.slice)
self.write("]") self.write("]")
def _Starred(self, t):
self.write("*")
self.dispatch(t.value)
# slice # slice
def _Ellipsis(self, t): def _Ellipsis(self, t):
self.write("...") self.write("...")
@ -560,6 +558,12 @@ class Unparser:
if t.asname: if t.asname:
self.write(" as "+t.asname) self.write(" as "+t.asname)
def _withitem(self, t):
self.dispatch(t.context_expr)
if t.optional_vars:
self.write(" as ")
self.dispatch(t.optional_vars)
def roundtrip(filename, output=sys.stdout): def roundtrip(filename, output=sys.stdout):
with open(filename, "rb") as pyfile: with open(filename, "rb") as pyfile:
encoding = tokenize.detect_encoding(pyfile.readline)[0] encoding = tokenize.detect_encoding(pyfile.readline)[0]