This looks like a quirk of memory reuse rather than a NumPy bug.
The line
id(numpy.float64(100)) == id(numpy.float64(10))
first creates a float numpy.float64(100)
and then calls the id
function on it. This memory is then immediately freed by Python's garbage collector because there are no more references to it. The memory slot is free to be reused by any new objects that are created.
When numpy.float64(10)
is created, it occupies the same memory location, hence the memory addresses returned by id
compare equal.
This chain of events is perhaps clearer when you look at the bytecode:
>>> dis.dis('id(numpy.float64(100)) == id(numpy.float64(10))')
0 LOAD_NAME 0 (id)
3 LOAD_NAME 1 (numpy)
6 LOAD_ATTR 2 (float64)
9 LOAD_CONST 0 (100)
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # call numpy.float64(100)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # get id of object
# gc runs and frees memory occupied by numpy.float64(100)
18 LOAD_NAME 0 (id)
21 LOAD_NAME 1 (numpy)
24 LOAD_ATTR 2 (float64)
27 LOAD_CONST 1 (10)
30 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # call numpy.float64(10)
33 CALL_FUNCTION 1 (1 positional, 0 keyword pair) # get id of object
36 COMPARE_OP 2 (==) # compare the two ids
39 RETURN_VALUE