[Python-Dev] builtin_id() returns negative numbers

Troels Walsted Hansen troels at thule.no
Mon Feb 14 15:03:22 CET 2005


Hi all,

The Python binding in libxml2 uses the following code for __repr__():

class xmlNode(xmlCore):
     def __init__(self, _obj=None):
         self._o = None
         xmlCore.__init__(self, _obj=_obj)

     def __repr__(self):
         return "<xmlNode (%s) object at 0x%x>" % (self.name, id (self))

With Python 2.3.4 I'm seeing warnings like the one below:
<frozen module libxml2>:2357: FutureWarning: %u/%o/%x/%X of negative int 
will return a signed string in Python 2.4 and up

I believe this is caused by the memory address having the sign bit set, 
causing builtin_id() to return a negative integer.

I grepped around in the Python standard library and found a rather 
awkward work-around that seems to be slowly propagating to various 
module using the "'%x' % id(self)" idiom:

Lib/asyncore.py:
         # On some systems (RH10) id() can be a negative number.
         # work around this.
         MAX = 2L*sys.maxint+1
         return '<%s at %#x>' % (' '.join(status), id(self)&MAX)


$ grep -r 'can be a negative number' *
Lib/asyncore.py:        # On some systems (RH10) id() can be a negative 
number.
Lib/repr.py:            # On some systems (RH10) id() can be a negative 
number.
Lib/tarfile.py:        # On some systems (RH10) id() can be a negative 
number.
Lib/test/test_repr.py:        # On some systems (RH10) id() can be a 
negative number.
Lib/xml/dom/minidom.py:        # On some systems (RH10) id() can be a 
negative number.

There are many modules that do not have this work-around in Python 2.3.4.

Wouldn't it be more elegant to make builtin_id() return an unsigned 
long integer? Is the performance impact too great?

A long integer is used on platforms where SIZEOF_VOID_P > SIZEOF_LONG 
(most 64 bit platforms?), so all Python code must be prepared to handle 
it already...

Troels


More information about the Python-Dev mailing list