Commit f7b96aea authored by Tim Peters's avatar Tim Peters

ZODB.utils grows a new function positive_id(), which returns the id() of

an object as a non-negative integer.  Code trying to pass addresses to
an %x format uses positive_id(), and this avoids a Python FutureWarning
about applying %x to negative ints.  The primary difference between this
and the last stab is that positive_id() should work OK on 64-bit boxes
too.  What we really want here is C's %p format code, but in Python we
can't even reliably know the width of native addresses.
parent fb213a2d
......@@ -39,6 +39,8 @@ from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
from ZODB.utils import positive_id
TYPE_UNKNOWN, TYPE_BTREE, TYPE_BUCKET = range(3)
_type2kind = {IOBTree: (TYPE_BTREE, True),
......@@ -198,9 +200,7 @@ def crack_bucket(b, is_mapping):
return keys, values
def type_and_adr(obj):
# Force the address to look positive. A negative address will
# show up as signed in Python 2.4, and in 2.3 raises FutureWarning.
return "%s (0x%x)" % (type(obj).__name__, id(obj) & 0xffffffffL)
return "%s (0x%x)" % (type(obj).__name__, positive_id(obj))
# Walker implements a depth-first search of a BTree (or TreeSet or Set or
# Bucket). Subclasses must implement the visit_btree() and visit_bucket()
......
......@@ -13,7 +13,7 @@
##############################################################################
"""Database connection support
$Id: Connection.py,v 1.143 2004/04/06 20:21:55 tim_one Exp $"""
$Id: Connection.py,v 1.144 2004/04/06 21:47:12 tim_one Exp $"""
import logging
import sys
......@@ -33,7 +33,7 @@ from ZODB.ExportImport import ExportImport
from ZODB.POSException \
import ConflictError, ReadConflictError, InvalidObjectReference
from ZODB.TmpStore import TmpStore
from ZODB.utils import oid_repr, z64
from ZODB.utils import oid_repr, z64, positive_id
from ZODB.serialize import ObjectWriter, ConnectionObjectReader, myhasattr
global_reset_counter = 0
......@@ -223,9 +223,7 @@ class Connection(ExportImport, object):
ver = ' (in version %s)' % `self._version`
else:
ver = ''
# Force the address to look positive. A negative address will
# show up as signed in Python 2.4, and in 2.3 raises FutureWarning.
return '<Connection at %08x%s>' % (id(self) & 0xffffffffL, ver)
return '<Connection at %08x%s>' % (positive_id(self), ver)
def get(self, oid):
"""Return the persistent object with oid 'oid'.
......
......@@ -36,11 +36,12 @@ TODO
add in tests for objects which are modified multiple times,
for example an object that gets modified in multiple sub txns.
$Id: testTransaction.py,v 1.23 2004/04/06 01:06:41 tim_one Exp $
$Id: testTransaction.py,v 1.24 2004/04/06 21:47:12 tim_one Exp $
"""
import unittest
import transaction
from ZODB.utils import positive_id
class TransactionTests(unittest.TestCase):
......@@ -532,7 +533,9 @@ class BasicJar:
self.ccommit_sub = 0
def __repr__(self):
return "<%s %X %s>" % (self.__class__.__name__, id(self), self.errors)
return "<%s %X %s>" % (self.__class__.__name__,
positive_id(self),
self.errors)
def sortKey(self):
# All these jars use the same sort key, and Python's list.sort()
......
......@@ -69,3 +69,26 @@ def oid_repr(oid):
return repr(oid)
serial_repr = oid_repr
# Addresses can "look negative" on some boxes, some of the time. If you
# feed a "negative address" to an %x format, Python 2.3 displays it as
# unsigned, but produces a FutureWarning, because Python 2.4 will display
# it as signed. So when you want to prodce an address, use positive_id() to
# obtain it.
def positive_id(obj):
"""Return id(obj) as a non-negative integer."""
result = id(obj)
if result < 0:
# This is a puzzle: there's no way to know the natural width of
# addresses on this box (in particular, there's no necessary
# relation to sys.maxint). Try 32 bits first (and on a 32-bit
# box, adding 2**32 gives a positive number with the same hex
# representation as the original result).
result += 1L << 32
if result < 0:
# Undo that, and try 64 bits.
result -= 1L << 32
result += 1L << 64
assert result >= 0 # else addresses are fatter than 64 bits
return result
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment