[Python-Dev] PyObject_RichCompareBool identity shortcut

Mark Dickinson dickinsm at gmail.com
Wed Apr 27 23:15:46 CEST 2011


On Wed, Apr 27, 2011 at 7:41 PM, Glenn Linderman <v+python at g.nevcal.com> wrote:
> One issue that I don't fully understand: I know there is only one instance
> of None in Python, but I'm not sure where to discover whether there is only
> a single, or whether there can be multiple, instances of NaN or Inf.  The
> IEEE 754 spec is clear that there are multiple bit sequences that can be
> used to represent these, so I would hope that there can be, in fact, more
> than one value containing NaN (and Inf).
>
> This would properly imply that a collection should correctly handle the case
> of storing multiple, different items using different NaN (and Inf)
> instances.  A dict, for example, should be able to hold hundreds of items
> with the index value of NaN.
>
> The distinction between "is" and "==" would permit proper operation, and I
> believe that Python's "rebinding" of names to values rather than the copying
> of values to variables makes such a distinction possible to use in a correct
> manner.

For infinities, there's no issue:  there are exactly two distinct
infinities (+inf and -inf), and they don't have any special properties
that affect membership tests.   Your float-keyed dict can contain both
+inf and -inf keys, or just one, or neither, in exactly the same way
that it can contain both +5.0 and -5.0 as keys, or just one, or
neither.

For nans, you *can* put multiple nans into a dictionary as separate
keys, but under the current rules the test for 'sameness' of two nan
keys becomes a test of object identity, not of bitwise equality.
Python takes no notice of the sign bits and 'payload' bits of a float
nan, except in operations like struct.pack and struct.unpack.  For
example:

>>> x, y = float('nan'), float('nan')
>>> d = {x: 1, y:2}
>>> x in d
True
>>> y in d
True
>>> d[x]
1
>>> d[y]
2

But using struct.pack, you can see that x and y are bitwise identical:

>>> struct.pack('<d', x) == struct.pack('<d', y)
True


Mark


More information about the Python-Dev mailing list