[Python-checkins] r45256 - python/trunk/Lib/ctypes/test/test_prototypes.py

tim.peters python-checkins at python.org
Tue Apr 11 04:59:48 CEST 2006


Author: tim.peters
Date: Tue Apr 11 04:59:48 2006
New Revision: 45256

Modified:
   python/trunk/Lib/ctypes/test/test_prototypes.py
Log:
Try to repair what may be the last new test failure on the
"x86 OpenBSD trunk" buildbot due to changing Python so that
Python-exposed addresses are always non-negative.

test_int_pointer_arg():  This line failed now whenever the
box happened to assign an address to `ci` "with the sign
bit set":

    self.failUnlessEqual(addressof(ci), func(byref(ci)))

The problem is that the ctypes addressof() inherited "all
addresses are non-negative now" from changes to
PyLong_FromVoidPtr(), but byref() did not inherit that
change and can still return a negative int.

I don't know whether, or what, the ctypes implementation wants
to do about that (possibly nothing), but in the meantime
the test fails frequently.

So, introduced a Python positive_address() function in
the test module, that takes a purported machine address and,
if negative, converts it to a non-negative value "with the
same bits".  This should leave the test passing under all
versions of Python.

Belated thanks to Armin Rigo for teaching me the sick trick ;-)
for determining the # of bits in a machine pointer via abuse
of the struct module.


Modified: python/trunk/Lib/ctypes/test/test_prototypes.py
==============================================================================
--- python/trunk/Lib/ctypes/test/test_prototypes.py	(original)
+++ python/trunk/Lib/ctypes/test/test_prototypes.py	Tue Apr 11 04:59:48 2006
@@ -24,6 +24,19 @@
 import _ctypes_test
 testdll = cdll.load(_ctypes_test.__file__)
 
+# Return machine address `a` as a (possibly long) non-negative integer.
+# Starting with Python 2.5, id(anything) is always non-negative, and
+# the ctypes addressof() inherits that via PyLong_FromVoidPtr().
+def positive_address(a):
+    if a >= 0:
+        return a
+    # View the bits in `a` as unsigned instead.
+    import struct
+    num_bits = struct.calcsize("P") * 8 # num bits in native machine address
+    a += 1L << num_bits
+    assert a >= 0
+    return a
+
 def c_wbuffer(init):
     n = len(init) + 1
     return (c_wchar * n)(*init)
@@ -43,7 +56,8 @@
         ci = c_int(0)
 
         func.argtypes = POINTER(c_int),
-        self.failUnlessEqual(addressof(ci), func(byref(ci)))
+        self.failUnlessEqual(positive_address(addressof(ci)),
+                             positive_address(func(byref(ci))))
 
         func.argtypes = c_char_p,
         self.assertRaises(ArgumentError, func, byref(ci))


More information about the Python-checkins mailing list