Skip to content

Commit

Permalink
[3.13] pythongh-125783: Add more tests to prevent regressions with th…
Browse files Browse the repository at this point in the history
…e combination of ctypes and metaclasses. (pythonGH-126126) (pythonGH-126275)

pythongh-125783: Add more tests to prevent regressions with the combination of ctypes and metaclasses. (pythonGH-126126)
(cherry picked from commit 6c67446)

Co-authored-by: Jun Komoda <[email protected]>
  • Loading branch information
miss-islington and junkmd authored Nov 4, 2024
1 parent 6245ee2 commit cddecf2
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions Lib/test/test_ctypes/test_c_simple_type_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,68 @@ class Sub(CtBase):

self.assertIsInstance(POINTER(Sub), p_meta)
self.assertTrue(issubclass(POINTER(Sub), Sub))

def test_creating_pointer_in_dunder_init_1(self):
class ct_meta(type):
def __init__(self, name, bases, namespace):
super().__init__(name, bases, namespace)

# Avoid recursion.
# (See test_creating_pointer_in_dunder_new_1)
if bases == (c_void_p,):
return
if issubclass(self, PtrBase):
return
if bases == (object,):
ptr_bases = (self, PtrBase)
else:
ptr_bases = (self, POINTER(bases[0]))
p = p_meta(f"POINTER({self.__name__})", ptr_bases, {})
ctypes._pointer_type_cache[self] = p

class p_meta(PyCSimpleType, ct_meta):
pass

class PtrBase(c_void_p, metaclass=p_meta):
pass

class CtBase(object, metaclass=ct_meta):
pass

class Sub(CtBase):
pass

class Sub2(Sub):
pass

self.assertIsInstance(POINTER(Sub2), p_meta)
self.assertTrue(issubclass(POINTER(Sub2), Sub2))
self.assertTrue(issubclass(POINTER(Sub2), POINTER(Sub)))
self.assertTrue(issubclass(POINTER(Sub), POINTER(CtBase)))

def test_creating_pointer_in_dunder_init_2(self):
class ct_meta(type):
def __init__(self, name, bases, namespace):
super().__init__(name, bases, namespace)

# Avoid recursion.
# (See test_creating_pointer_in_dunder_new_2)
if isinstance(self, p_meta):
return
p = p_meta(f"POINTER({self.__name__})", (self, c_void_p), {})
ctypes._pointer_type_cache[self] = p

class p_meta(PyCSimpleType, ct_meta):
pass

class Core(object):
pass

class CtBase(Core, metaclass=ct_meta):
pass

class Sub(CtBase):
pass

self.assertIsInstance(POINTER(Sub), p_meta)
self.assertTrue(issubclass(POINTER(Sub), Sub))

0 comments on commit cddecf2

Please sign in to comment.