Skip to content

Commit

Permalink
Add a python version bridge to _post_coinit.unknwn.
Browse files Browse the repository at this point in the history
  • Loading branch information
junkmd committed Sep 28, 2024
1 parent d68f53a commit ddaa28d
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions comtypes/_post_coinit/unknwn.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import logging
import sys
import types
from typing import ClassVar, TYPE_CHECKING, TypeVar
from typing import Any, ClassVar, TYPE_CHECKING, TypeVar
from typing import Optional
from typing import List, Type
from typing import Dict, List, Tuple, Type

from comtypes import GUID, patcher, _ole32_nohresult, com_interface_registry
from comtypes._idl_stuff import STDMETHOD
Expand Down Expand Up @@ -65,17 +65,36 @@ class _cominterface_meta(type):
# CoUninitialize.
_com_shutting_down = False

if sys.version_info >= (3, 13):

def __new__(cls, name, bases, namespace):
return cls._new(name, bases, namespace)

def __init__(self, name, bases, namespace):
self._init(name, bases, namespace)

else:

def __new__(cls, name, bases, namespace):
self = cls._new(name, bases, namespace)
self._init(name, bases, namespace)
return self

# Creates also a POINTER type for the newly created class.
def __new__(cls, name, bases, namespace):
methods = namespace.pop("_methods_", None)
dispmethods = namespace.pop("_disp_methods_", None)
new_cls = type.__new__(cls, name, bases, namespace)
@classmethod
def _new(cls, name: str, bases: Tuple[Type, ...], ns: Dict[str, Any]):
methods = ns.pop("_methods_", None)
dispmethods = ns.pop("_disp_methods_", None)
new_cls = type.__new__(cls, name, bases, ns)

if methods is not None:
new_cls._methods_ = methods
if dispmethods is not None:
new_cls._disp_methods_ = dispmethods

return new_cls

def _init(self, name: str, bases: Tuple[Type, ...], ns: Dict[str, Any]) -> None:
# If we sublass a COM interface, for example:
#
# class IDispatch(IUnknown):
Expand All @@ -85,26 +104,24 @@ def __new__(cls, name, bases, namespace):
# subclass of POINTER(IUnknown) because of the way ctypes
# typechecks work.
if bases == (object,):
_ptr_bases = (new_cls, _compointer_base)
_ptr_bases = (self, _compointer_base)
else:
_ptr_bases = (new_cls, POINTER(bases[0]))
_ptr_bases = (self, POINTER(bases[0]))

# The interface 'new_cls' is used as a mixin.
# The interface is used as a mixin.
p = type(_compointer_base)(
"POINTER(%s)" % new_cls.__name__,
f"POINTER({self.__name__})",
_ptr_bases,
{"__com_interface__": new_cls, "_needs_com_addref_": None},
{"__com_interface__": self, "_needs_com_addref_": None},
)

from ctypes import _pointer_type_cache # type: ignore

_pointer_type_cache[new_cls] = p
_pointer_type_cache[self] = p

if new_cls._case_insensitive_:
new_cls._patch_case_insensitive_to_ptr_type(p)
new_cls._patch_reference_fix_to_ptrptr_type(p)

return new_cls
if self._case_insensitive_:
self._patch_case_insensitive_to_ptr_type(p)
self._patch_reference_fix_to_ptrptr_type(p)

@staticmethod
def _patch_case_insensitive_to_ptr_type(p: Type) -> None:
Expand Down

0 comments on commit ddaa28d

Please sign in to comment.