@@ -51,6 +51,9 @@ def _shutdown(
51
51
# The metaclasses...
52
52
53
53
54
+ _initializing_cominterface_meta = False
55
+
56
+
54
57
class _cominterface_meta (type ):
55
58
"""Metaclass for COM interfaces. Automatically creates high level
56
59
methods from COMMETHOD lists.
@@ -66,35 +69,45 @@ class _cominterface_meta(type):
66
69
_com_shutting_down = False
67
70
68
71
# Creates also a POINTER type for the newly created class.
69
- def __new__ (cls , name , bases , namespace ):
70
- methods = namespace .pop ("_methods_" , None )
71
- dispmethods = namespace .pop ("_disp_methods_" , None )
72
- self = type .__new__ (cls , name , bases , namespace )
72
+ def __init (self , name , bases , namespace ):
73
+ methods = namespace .get ("_methods_" , None )
74
+ dispmethods = namespace .get ("_disp_methods_" , None )
73
75
74
76
if methods is not None :
75
- self ._methods_ = methods
77
+ self ._make_methods (methods )
78
+ self ._make_specials ()
76
79
if dispmethods is not None :
77
- self ._disp_methods_ = dispmethods
80
+ self ._make_dispmethods (dispmethods )
81
+ self ._make_specials ()
78
82
79
- # If we sublass a COM interface, for example:
80
- #
81
- # class IDispatch(IUnknown):
82
- # ....
83
- #
84
- # then we need to make sure that POINTER(IDispatch) is a
85
- # subclass of POINTER(IUnknown) because of the way ctypes
86
- # typechecks work.
87
- if bases == (object ,):
88
- _ptr_bases = (self , _compointer_base )
89
- else :
90
- _ptr_bases = (self , POINTER (bases [0 ]))
83
+ global _initializing_cominterface_meta
91
84
92
- # The interface 'self' is used as a mixin.
93
- p = type (_compointer_base )(
94
- f"POINTER({ self .__name__ } )" ,
95
- _ptr_bases ,
96
- {"__com_interface__" : self , "_needs_com_addref_" : None },
97
- )
85
+ if _initializing_cominterface_meta :
86
+ return
87
+
88
+ try :
89
+ _initializing_cominterface_meta = True
90
+ # If we sublass a COM interface, for example:
91
+ #
92
+ # class IDispatch(IUnknown):
93
+ # ....
94
+ #
95
+ # then we need to make sure that POINTER(IDispatch) is a
96
+ # subclass of POINTER(IUnknown) because of the way ctypes
97
+ # typechecks work.
98
+ if bases == (object ,):
99
+ _ptr_bases = (self , _compointer_base )
100
+ else :
101
+ _ptr_bases = (self , POINTER (bases [0 ]))
102
+
103
+ # The interface 'self' is used as a mixin.
104
+ p = type (_compointer_base )(
105
+ f"POINTER({ self .__name__ } )" ,
106
+ _ptr_bases ,
107
+ {"__com_interface__" : self , "_needs_com_addref_" : None },
108
+ )
109
+ finally :
110
+ _initializing_cominterface_meta = False
98
111
99
112
from ctypes import _pointer_type_cache # type: ignore
100
113
@@ -104,7 +117,14 @@ def __new__(cls, name, bases, namespace):
104
117
self ._patch_case_insensitive_to_ptr_type (p )
105
118
self ._patch_reference_fix_to_ptrptr_type (POINTER (p )) # type: ignore
106
119
107
- return self
120
+ if sys .version_info >= (3 , 13 ):
121
+ __init__ = __init
122
+ else :
123
+
124
+ def __new__ (cls , name , bases , namespace ):
125
+ self = type .__new__ (cls , name , bases , namespace )
126
+ self .__init (name , bases , namespace )
127
+ return self
108
128
109
129
@staticmethod
110
130
def _patch_case_insensitive_to_ptr_type (p : Type ) -> None :
0 commit comments