jez
jez

Reputation: 15349

Unexpected reference count for unnamed integer literal

I understand that, in CPython 2.x and 3.x, some integers are singletons:

>>> a = 256; a is 256    # or any integer from -5 to 256
True

>>> a = 257; a is 257    # or any other integer outside the magic range
False

Accordingly, if I run sys.getrefcount on an integer in the range -5 to 256, I find that a lot of my imported packages have referenced that integer:

>>> sys.getrefcount(1)
1470

I also understand that sys.getrefcount returns 1 more than you might expect, because of its own reference to the argument:

>>> a = 257; sys.getrefcount(a)
2

What I don't get is this:

>>> sys.getrefcount(257)
3

Why 3, not 2? I could understand that I might have created a temporary variable in my own scope (count 1), and clearly sys.getrefcount would add another reference of its own to that (count 2) but where does the third one come from, and why didn't happen in the previous example? And more importantly: are there other contexts in which this might occur, leading to possible misinterpretation of sys.getrefcount outputs?

All of the above are replicable for me on 64-bit Python 2.7.12 and 3.5.1 by Anaconda, running on OSX, and also on a 32-bit Python 2.7.5 distribution running on Windows. However, on an older Python version (32-bit Python 2.5.4 on Windows), sys.getrefcount(257) returns 2 which is (to me) more expected.

Upvotes: 2

Views: 278

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122222

You are running into an implementation detail here. The compiler can often cache immutable literal values:

>>> import dis
>>> compile("sys.getrefcount(257)", '', 'single').co_consts
(257, None)
>>> dis.dis(compile("sys.getrefcount(257)", '', 'single'))
  1           0 LOAD_NAME                0 (sys)
              2 LOAD_ATTR                1 (getrefcount)
              4 LOAD_CONST               0 (257)
              6 CALL_FUNCTION            1
              8 PRINT_EXPR
             10 LOAD_CONST               1 (None)
             12 RETURN_VALUE

('single' is the mode used by the interactive interpreter).

We see 3 references here; one from the co_consts tuple on the code object, one on the stack (from the LOAD_CONST instruction), and one for the sys.getrefcount() method itself.

Upvotes: 3

Related Questions