I am not really sure whether this is a bug or a feature. The attached code attempts to demonstrate the problem. I had some code that was trying to change -0.0 to 0.0 so that the accountants I work with don't panic. The code was something like this: if n == -0.0: n = 0.0 Regardless of whether n is -0.0 or 0.0 the test passes (which is good). However after the assignment n is actually -0.0 It looks like python is creating a single object for both -0.0 and 0.0. Whichever appears first within the local scope seems to be the value that actually gets stored. Eg changing the code to if n == 0.0: n = 0.0 gets me the behaviour I wanted.
This is a regression from 2.4. This seems to always have been undefined behaviour. It looks like it was the result of the compiler changes (code is the same in both versions, but co_consts is diff): Python 2.4.4c1 (#2, Oct 11 2006, 20:00:03) >>> def r(n): ... if n == -0.0: n = 0.0 ... return n ... >>> r.func_code.co_consts (None, 0.0) Python 2.6a0 (trunk, May 30 2007, 21:02:18) >>> def r(n): ... if n == -0.0: n = 0.0 ... return n ... >>> r.func_code.co_consts (None, -0.0)
I don't see an easy way to make this a defined behavior. FWIW, the OP's code suggests that it makes a more specific test than it does (since -0.0 == 0.0) so the test succeed when n is either -0.0 or 0.0. A quick fix in his code would be to eliminate the -0.0 from the code. def r(n): if n == 0.0: return 0.0 return n or more succinctly: def r(n): return n or 0.0
I'm happy to flag this as undefined behaviour. I have worked around it in my code, the only issue is that the code is brittle, since I think it relies on the scope of constants -- I'm guessing that is what has changed between 2.4 and 2.5 and could well change in the future. John