The unary negative optimization in ast_for_factor() seems to modify the ST in a way changes its meaning.
In Python 3.1.2, the ST is no longer compilable:
$ cat exprbug.py
import parser
st = parser.expr("-3")
print(st.totuple())
compiled = st.compile()
print(eval(compiled))
print(st.totuple())
print(eval(st.compile()))
$ ~/sw/Python-3.1.2/bin/python3 exprbug.py
(258, (326, (301, (305, (306, (307, (308, (310, (311, (312, (313, (314, (315, (316, (317, (15, '-'), (317, (318, (319, (2, '3')))))))))))))))))), (4, ''), (0, ''))
-3
(258, (326, (301, (305, (306, (307, (308, (310, (311, (312, (313, (314, (315, (316, (317, (15, '-'), (317, (318, (319, (2, '-3')))))))))))))))))), (4, ''), (0, ''))
Traceback (most recent call last):
File "exprbug.py", line 8, in <module>
print(eval(st.compile()))
ValueError: could not convert string to float: --3
In earlier versions of Python (I have confirmed 2.5 and 2.6), it is compiled to incorrect code and produces wrong results when evaluated:
$ ~/sw/Python-2.6.2/bin/python exprbug.py
(258, (327, (304, (305, (306, (307, (308, (310, (311, (312, (313, (314, (315, (316, (15, '-'), (316, (317, (318, (2, '3'))))))))))))))))), (4, ''), (0, ''))
-3
(258, (327, (304, (305, (306, (307, (308, (310, (311, (312, (313, (314, (315, (316, (15, '-'), (316, (317, (318, (2, '-3'))))))))))))))))), (4, ''), (0, ''))
-1.0
If I remove the big if statement from the front of ast_to_factor(), the code behaves correctly. I think this is because STR(pnum) is changed in place and never restored to its previous value. |