On Nov 20, 2004, at 2:38 AM, Terry Reedy wrote:
"James Y Knight"
wrote in message news:582E4A36-3A6C-11D9-AA57-000A95A50FB2@fuhm.net... [snip] I propose that id() always return a positive value ... Comments?
1. CPython intentionally searches builtins afters globals and pre-imports the former as __builtins__ just so one can wrap a builtin to modify its apparent behavior for personal needs.
def id(o, max = 2**32): ... i = __builtins__.id(o) ... return (i < 0) and (max - i) or i ... id(a) 9158224 # only semi-tested because I don't have negatives to test and can't force
2. Given that, why bother changing the language for what must be an esoteric need (to formattedly print and view ids)?
The id of an object is constant and unique with respect to contemporaneous objects but, for CPython, definitely not with respect to objects with non-overlapping lifetimes. (Newbies often get tripped by the last fact.).
From the viewpoint of Python, ids have no meaning and are only useful for identity comparision. For this purpose, arbitrary strings would have worked as well as integers.
For convenience, CPython uses the apparent address stored as an int. But this is strictly an implementation detail. On modern systems, that 'address' is, I believe, a process-specific virtual address which the hardware memory management system maps the hidden real address -- which is the only reason why systems with less than 2**31 memory can have addresses at or above 2**31 to become negative ints.
The problem, more than anything else, is the following behavior that can happen during a random __repr__ or repr-like-function if the object happens to have a certain address range: - (Python 2.3) You get an unexpected and unwanted warning but expected output anyway - (Python 2.4) You get a repr with a strange looking negative hex number (0x-FF0102) Neither of these are fatal, of course, it's just annoying.. I find the Python 2.3 behavior more obnoxious than Python 2.4's, personally. FYI, I have also encountered this "problem" this week on a Powerbook G4 w/ only 1GB physical memory on both Python 2.3 and 2.4. I'm at the PyPy sprint, and a lot of the tools we are using make use of repr. Fortunately we have control over all of this code, so I checked in a workaround that makes sure a sane value was passed to the hex formatter: import sys HUGEINT = (sys.maxint + 1L) * 2L def uid(obj): """ Return the id of an object as an unsigned number so that its hex representation makes sense """ rval = id(obj) if rval < 0: rval += HUGEINT return rval -bob