diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2010-06-29 10:01:48 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2010-06-29 10:01:48 (GMT) |
commit | 8042e2819227af0653f4e5b172a3bd372dde4a92 (patch) | |
tree | 368d38189c1e254883be9bd3bb4379f95785369d /Demo | |
parent | 3eb0290346199a850bc0b001c3e15ea75fdfff8f (diff) | |
download | cpython-8042e2819227af0653f4e5b172a3bd372dde4a92.zip cpython-8042e2819227af0653f4e5b172a3bd372dde4a92.tar.gz cpython-8042e2819227af0653f4e5b172a3bd372dde4a92.tar.bz2 |
More unparse.py fixes:
- parenthesize lambdas, to avoid turning (lambda : int)() into lambda: int()
- unparse an infinite float literals in the AST as an overflowing finite value
unparse.py now successfully round-trips on all valid Lib/*.py and Lib/test/*.py files.
Diffstat (limited to 'Demo')
-rw-r--r-- | Demo/parser/test_unparse.py | 7 | ||||
-rw-r--r-- | Demo/parser/unparse.py | 30 |
2 files changed, 26 insertions, 11 deletions
diff --git a/Demo/parser/test_unparse.py b/Demo/parser/test_unparse.py index 0d13897..b0a773d 100644 --- a/Demo/parser/test_unparse.py +++ b/Demo/parser/test_unparse.py @@ -87,6 +87,13 @@ class UnparseTestCase(unittest.TestCase): def test_integer_parens(self): self.check_roundtrip("3 .__abs__()") + def test_huge_float(self): + self.check_roundtrip("1e1000") + self.check_roundtrip("-1e1000") + + def test_lambda_parentheses(self): + self.check_roundtrip("(lambda: int)()") + def test_chained_comparisons(self): self.check_roundtrip("1 < 4 <= 5") self.check_roundtrip("a is b is c is not d") diff --git a/Demo/parser/unparse.py b/Demo/parser/unparse.py index 2c383a5..048f8ca 100644 --- a/Demo/parser/unparse.py +++ b/Demo/parser/unparse.py @@ -1,5 +1,6 @@ "Usage: unparse.py <path to source file>" import sys +import math import ast import tokenize import io @@ -302,17 +303,22 @@ class Unparser: self.write("`") def _Num(self, t): - # Add parentheses around numeric literals to avoid: - # - # (1) turning (-1)**2 into -1**2, and - # (2) turning 3 .__abs__() into 3.__abs__() - # - # For (1), note that Python doesn't actually have negative - # numeric literals, but (at least in Python 2.x) there's a CST - # transformation that can produce negative Nums in the AST. - self.write("(") - self.write(repr(t.n)) - self.write(")") + if isinstance(t.n, float): + # A float literal should be nonnegative, and not a nan. + # It could be an infinity, though; in that case we + # substitute an overflowing decimal value. + assert not math.isnan(t.n) + assert math.copysign(1.0, t.n) > 0.0 + if math.isinf(t.n): + self.write("1e" + repr(sys.float_info.max_10_exp + 1)) + else: + self.write(repr(t.n)) + else: + # Parenthesize integer literals to avoid turning + # "3 .__abs__()" into "3.__abs__()". + self.write("(") + self.write(repr(t.n)) + self.write(")") def _List(self, t): self.write("[") @@ -539,10 +545,12 @@ class Unparser: self.dispatch(t.value) def _Lambda(self, t): + self.write("(") self.write("lambda ") self.dispatch(t.args) self.write(": ") self.dispatch(t.body) + self.write(")") def _alias(self, t): self.write(t.name) |