From 319c47fcdb3b8196cc580c4fab409b0ee58119fe Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Tue, 11 Apr 2006 02:59:48 +0000 Subject: 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. --- Lib/ctypes/test/test_prototypes.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py index 2c3d75b..47f5da1 100644 --- a/Lib/ctypes/test/test_prototypes.py +++ b/Lib/ctypes/test/test_prototypes.py @@ -24,6 +24,19 @@ import unittest 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 @@ class CharPointersTestCase(unittest.TestCase): 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)) -- cgit v0.12