Index: Lib/ctypes/test/test_bitfields.py =================================================================== --- Lib/ctypes/test/test_bitfields.py (revision 85202) +++ Lib/ctypes/test/test_bitfields.py (working copy) @@ -240,5 +240,25 @@ _anonymous_ = ["_"] _fields_ = [("_", X)] + @unittest.skipUnless(hasattr(ctypes, "c_uint32"), "c_int32 is required") + def test_uint32(self): + class X(Structure): + _fields_ = [("a", c_uint32, 32)] + x = X() + x.a = 10 + self.assertEquals(x.a, 10) + x.a = 0xFDCBA987 + self.assertEquals(x.a, 0xFDCBA987) + + @unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required") + def test_uint64(self): + class X(Structure): + _fields_ = [("a", c_uint64, 64)] + x = X() + x.a = 10 + self.assertEquals(x.a, 10) + x.a = 0xFEDCBA9876543211 + self.assertEquals(x.a, 0xFEDCBA9876543211) + if __name__ == "__main__": unittest.main() Index: Modules/_ctypes/cfield.c =================================================================== --- Modules/_ctypes/cfield.c (revision 85202) +++ Modules/_ctypes/cfield.c (working copy) @@ -428,13 +428,15 @@ #define LOW_BIT(x) ((x) & 0xFFFF) #define NUM_BITS(x) ((x) >> 16) -/* This seems nore a compiler issue than a Windows/non-Windows one */ -#ifdef MS_WIN32 -# define BIT_MASK(size) ((1 << NUM_BITS(size))-1) +#ifdef HAVE_LONG_LONG +# define MAX_SIZE_INT(n) Py_ULL(n) #else -# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1) +# define MAX_SIZE_INT(n) n##UL #endif +/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */ +#define BIT_MASK(size) ((((MAX_SIZE_INT(1) << (NUM_BITS(size) - 1)) - 1) << 1) + 1) + /* This macro CHANGES the first parameter IN PLACE. For proper sign handling, we must first shift left, then right. */