summaryrefslogtreecommitdiffstats
path: root/Demo/parser
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2010-06-29 10:01:48 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2010-06-29 10:01:48 (GMT)
commit8042e2819227af0653f4e5b172a3bd372dde4a92 (patch)
tree368d38189c1e254883be9bd3bb4379f95785369d /Demo/parser
parent3eb0290346199a850bc0b001c3e15ea75fdfff8f (diff)
downloadcpython-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/parser')
-rw-r--r--Demo/parser/test_unparse.py7
-rw-r--r--Demo/parser/unparse.py30
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)