diff -r 8773e59530c2 Lib/test/test_peepholer.py --- a/Lib/test/test_peepholer.py Thu Mar 10 15:51:11 2011 -0500 +++ b/Lib/test/test_peepholer.py Thu Mar 10 16:11:51 2011 -0500 @@ -3,6 +3,7 @@ import sys from io import StringIO import unittest +from math import copysign def disassemble(func): f = StringIO() @@ -198,6 +199,8 @@ def test_folding_of_unaryops_on_constants(self): for line, elem in ( ('-0.5', '(-0.5)'), # unary negative + ('-0.0', '(-0.0)'), # -0.0 + ('-(1.0-1.0)','(-0.0)'), # -0.0 after folding ('~-2', '(1)'), # unary invert ('+1', '(1)'), # unary positive ): @@ -205,6 +208,12 @@ self.assertIn(elem, asm, asm) self.assertNotIn('UNARY_', asm) + # Check that -0.0 works after marshaling + def negzero(): return -(1.0-1.0) + + self.assertNotIn('UNARY_', disassemble(negzero)) + self.assertTrue(copysign(1.0, negzero()) < 0) + # Verify that unfoldables are skipped for line, elem in ( ('-"abc"', "('abc')"), # unary negative diff -r 8773e59530c2 Python/peephole.c --- a/Python/peephole.c Thu Mar 10 15:51:11 2011 -0500 +++ b/Python/peephole.c Thu Mar 10 16:11:51 2011 -0500 @@ -189,7 +189,7 @@ static int fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts) { - PyObject *newconst=NULL, *v; + PyObject *newconst, *v; Py_ssize_t len_consts; int opcode; @@ -202,9 +202,7 @@ opcode = codestr[3]; switch (opcode) { case UNARY_NEGATIVE: - /* Preserve the sign of -0.0 */ - if (PyObject_IsTrue(v) == 1) - newconst = PyNumber_Negative(v); + newconst = PyNumber_Negative(v); break; case UNARY_INVERT: newconst = PyNumber_Invert(v);