Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
WIP
  • Loading branch information
ambv committed Aug 24, 2023
commit d2ff7a4cc9a85cedb3db4a8c405fac157936c720
29 changes: 29 additions & 0 deletions Lib/test/test_ctypes/test_cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,35 @@ class StructWithPointers(Structure):
self.assertEqual(obj[0].contents.a, 10)
self.assertEqual(obj[1].contents.a, 20)

def test_pointer_set_contents(self):
class Struct(Structure):
_fields_ = [('a', c_int16)]
p = pointer(Struct(a=23))
self.assertEqual(p.contents.a, 23)
self.assertIs(p._type_, Struct)
cp = cast(p, POINTER(c_int16))
self.assertEqual(cp.contents._type_, 'h')
cp.contents = c_int16(24)
self.assertEqual(cp.contents.value, 24)
self.assertEqual(p.contents.a, 24)

pp = pointer(p)
self.assertIs(pp._type_, POINTER(Struct))

from code import interact; interact(local=locals())

cast(pp, POINTER(POINTER(c_int16))).contents.contents = c_int16(32)

# self.assertIs(p.contents, pp.contents.contents)

self.assertEqual(cast(p, POINTER(c_int16)).contents.value, 32)
self.assertEqual(p[0].a, 32) # works
self.assertEqual(pp[0].contents.a, 32) # works
self.assertEqual(pp.contents[0].a, 32) # works

self.assertEqual(p.contents.a, 32) # fails, wat, holds 23
self.assertEqual(pp.contents.contents.a, 32) # fails, wat, holds 23


if __name__ == "__main__":
unittest.main()
12 changes: 8 additions & 4 deletions Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -5172,11 +5172,15 @@ Pointer_get_contents(CDataObject *self, void *closure)
// It's not a cast: don't construct a new object,
// return existing one instead to preserve refcount
p2p = (CDataObject*) ptr2ptr;
printf("self->b_ptr=%lu\n", *(void**) self->b_ptr);
printf("p2p->b_ptr=%lu\n", *(void**) p2p->b_ptr);
printf("self->b_value.c=%lu\n", *(void**) self->b_value.c);
printf("p2p->b_value.c=%lu\n", *(void**) p2p->b_value.c);
assert(
*(void**) self->b_ptr == p2p->b_ptr ||
*(void**) self->b_value.c == p2p->b_ptr ||
*(void**) self->b_ptr == p2p->b_value.c ||
*(void**) self->b_value.c == p2p->b_value.c
*(void**) self->b_ptr == *(void**) p2p->b_ptr ||
*(void**) self->b_value.c == *(void**) p2p->b_ptr ||
*(void**) self->b_ptr == *(void**) p2p->b_value.c ||
*(void**) self->b_value.c == *(void**) p2p->b_value.c
); // double-check that we are returning the same thing
Py_INCREF(ptr2ptr);
return ptr2ptr;
Expand Down