Feature or enhancement
Proposal:
There were breaking changes to ctypes in Python 3.13.
Projects like comtypes and pyglet, which implement functionality by combining ctypes and metaclasses, no longer work unless their codebases are updated.
We discussed what changes such projects need to make to their codebases in gh-124520.
I believe the easiest and most effective way to prevent regressions from happening again is to add tests on the cpython side.
I wrote a simple test like the one below.
# Lib/test/test_ctypes/test_c_simple_type_meta.py?importunittestimportctypesfromctypesimportPOINTER, c_void_pfrom ._supportimportPyCSimpleType, _CData, _SimpleCDataclassPyCSimpleTypeAsMetaclassTest(unittest.TestCase):
deftearDown(self):
# to not leak references, we must clean _pointer_type_cachectypes._reset_cache()
deftest_early_return_in_dunder_new_1(self):
# this implementation is used in `IUnknown` of comtypes.class_ct_meta(type):
def__new__(cls, name, bases, namespace):
self=super().__new__(cls, name, bases, namespace)
ifbases== (c_void_p,):
returnselfifissubclass(self, _PtrBase):
returnselfifbases== (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] =preturnselfclass_p_meta(PyCSimpleType, _ct_meta):
passclass_PtrBase(c_void_p, metaclass=_p_meta):
passclass_CtBase(object, metaclass=_ct_meta):
passclass_Sub(_CtBase):
passclass_Sub2(_Sub):
passdeftest_early_return_in_dunder_new_2(self):
# this implementation is used in `CoClass` of comtypes.class_ct_meta(type):
def__new__(cls, name, bases, namespace):
self=super().__new__(cls, name, bases, namespace)
ifisinstance(self, _p_meta):
returnselfp=_p_meta(
f"POINTER({self.__name__})", (self, c_void_p), {}
)
ctypes._pointer_type_cache[self] =preturnselfclass_p_meta(PyCSimpleType, _ct_meta):
passclass_Base(object):
passclass_Sub(_Base, metaclass=_ct_meta):
passclass_Sub2(_Sub):
passIf no errors occur when this test is executed, we can assume that no regressions have occurred with the combination of ctypes and metaclasses.
However, I feel that this may not be enough. What should we specify as the target for the assert?
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
#124520
Linked PRs
Feature or enhancement
Proposal:
There were breaking changes to
ctypesin Python 3.13.Projects like
comtypesandpyglet, which implement functionality by combiningctypesand metaclasses, no longer work unless their codebases are updated.We discussed what changes such projects need to make to their codebases in gh-124520.
I believe the easiest and most effective way to prevent regressions from happening again is to add tests on the
cpythonside.I wrote a simple test like the one below.
If no errors occur when this test is executed, we can assume that no regressions have occurred with the combination of
ctypesand metaclasses.However, I feel that this may not be enough. What should we specify as the target for the
assert?Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
#124520
Linked PRs
ctypesand metaclasses. #125881ctypesand metaclasses. (GH-125881) #125987ctypesand metaclasses. (GH-125881) #125988