Add ast.Constant

Issue #26146: Add a new kind of AST node: ast.Constant. It can be used by
external AST optimizers, but the compiler does not emit directly such node.

An optimizer can replace the following AST nodes with ast.Constant:

* ast.NameConstant: None, False, True
* ast.Num: int, float, complex
* ast.Str: str
* ast.Bytes: bytes
* ast.Tuple if items are constants too: tuple
* frozenset

Update code to accept ast.Constant instead of ast.Num and/or ast.Str:

* compiler
* docstrings
* ast.literal_eval()
* Tools/parser/unparse.py
This commit is contained in:
Victor Stinner 2016-01-26 00:40:57 +01:00
parent 0dceb91866
commit f2c1aa1661
14 changed files with 401 additions and 44 deletions

View file

@ -343,6 +343,11 @@ class Unparser:
value = t.s.replace("{", "{{").replace("}", "}}")
write(value)
def _fstring_Constant(self, t, write):
assert isinstance(t.value, str)
value = t.value.replace("{", "{{").replace("}", "}}")
write(value)
def _fstring_FormattedValue(self, t, write):
write("{")
expr = io.StringIO()
@ -364,6 +369,25 @@ class Unparser:
def _Name(self, t):
self.write(t.id)
def _write_constant(self, value):
if isinstance(value, (float, complex)):
self.write(repr(value).replace("inf", INFSTR))
else:
self.write(repr(value))
def _Constant(self, t):
value = t.value
if isinstance(value, tuple):
self.write("(")
if len(value) == 1:
self._write_constant(value[0])
self.write(",")
else:
interleave(lambda: self.write(", "), self._write_constant, value)
self.write(")")
else:
self._write_constant(t.value)
def _NameConstant(self, t):
self.write(repr(t.value))
@ -443,7 +467,7 @@ class Unparser:
def _Tuple(self, t):
self.write("(")
if len(t.elts) == 1:
(elt,) = t.elts
elt = t.elts[0]
self.dispatch(elt)
self.write(",")
else:
@ -490,7 +514,8 @@ class Unparser:
# Special case: 3.__abs__() is a syntax error, so if t.value
# is an integer literal then we need to either parenthesize
# it or add an extra space to get 3 .__abs__().
if isinstance(t.value, ast.Num) and isinstance(t.value.n, int):
if ((isinstance(t.value, ast.Num) and isinstance(t.value.n, int))
or (isinstance(t.value, ast.Constant) and isinstance(t.value.value, int))):
self.write(" ")
self.write(".")
self.write(t.attr)