05.04.14 06:50, Chris Angelico написав(ла):
Currently, parsing a Python script into an AST discards a huge amount of information. Some of that (line and column information) is retained as metadata, but a lot isn't. One of the potentially-useful things that's currently dropped is the string form of numbers:
print(ast.dump(ast.parse("x = 1 + 2.000 + 3.0j"))) Module(body=[Assign(targets=[Name(id='x', ctx=Store())], value=BinOp(left=BinOp(left=Num(n=1), op=Add(), right=Num(n=2.0)), op=Add(), right=Num(n=3j)))])
The three Num nodes have an n with the already-constructed int/float/complex. At this point, it's impossible to return to the original string that was entered; any rounding will have already taken place.
If the Num nodes also had a .str member with the unparsed string ("1", "2.000", and "3.0j"), it would be possible to influence their interpretation with an AST transform - for instance, turning them into decimal.Decimal construction calls, or wrapping them in something that automatically keeps track of significant figures (which would mean that "2.000" is considered more precise than a mere "2.0" or "2.").
It shouldn't be too difficult to do, and it could simply be ignored in most cases; any sort of change to the actual number could leave the original string out of sync with it, which isn't a problem.
Thoughts?
What about strings?
print(ast.dump(ast.parse(r"x = '''\x0a\u000d''' r'x'"))) Module(body=[Assign(targets=[Name(id='x', ctx=Store())], value=Str(s='\n\rx'))])
Tuples?
print(ast.dump(ast.parse("x = (1, 2,)"))) Module(body=[Assign(targets=[Name(id='x', ctx=Store())], value=Tuple(elts=[Num(n=1), Num(n=2)], ctx=Load()))])