Index: Python/ast.c =================================================================== --- Python/ast.c (revision 81991) +++ Python/ast.c (working copy) @@ -1749,13 +1749,22 @@ TYPE((patom = CHILD(ppower, 0))) == atom && TYPE((pnum = CHILD(patom, 0))) == NUMBER) { char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2); + char *str_pnum_orig; + expr_ty result; if (s == NULL) return NULL; s[0] = '-'; + /* Replace STR(pnum) with a negated string. This (temporarily) leaves + the CST incorrect, so we restore the old value of STR(pnum) after + converting pnum to AST. See issue #9011. + */ strcpy(s + 1, STR(pnum)); - PyObject_FREE(STR(pnum)); + str_pnum_orig = STR(pnum); STR(pnum) = s; - return ast_for_atom(c, patom); + result = ast_for_atom(c, patom); + STR(pnum) = str_pnum_orig; + PyObject_FREE(s); + return result; } expression = ast_for_expr(c, CHILD(n, 1)); Index: Lib/test/test_parser.py =================================================================== --- Lib/test/test_parser.py (revision 81991) +++ Lib/test/test_parser.py (working copy) @@ -532,8 +532,18 @@ st = parser.suite('a = u"\u1"') self.assertRaises(SyntaxError, parser.compilest, st) + def test_issue_9011(self): + # Issue 9011: compilation of an unary minus expression changed + # the meaning of the ST, so that a second compilation produced + # incorrect results. + st = parser.expr('-3') + code1 = parser.compilest(st) + self.assertEqual(eval(code1), -3) + code2 = parser.compilest(st) + self.assertEqual(eval(code2), -3) + class ParserStackLimitTestCase(unittest.TestCase): - """try to push the parser to/over it's limits. + """try to push the parser to/over its limits. see http://bugs.python.org/issue1881 for a discussion """ def _nested_expression(self, level):