Skip to content

Commit

Permalink
Split _cominterface_meta._patch_to_ptr_type. (#625)
Browse files Browse the repository at this point in the history
* Split `_patch_to_ptr_type`.

* Change indentations.

* Add `type: ignore` comments.
  • Loading branch information
junkmd committed Sep 27, 2024
1 parent 07a3b83 commit 621ec95
Showing 1 changed file with 31 additions and 32 deletions.
63 changes: 31 additions & 32 deletions comtypes/_post_coinit/unknwn.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,41 +101,40 @@ def __new__(cls, name, bases, namespace):
_pointer_type_cache[new_cls] = p

if new_cls._case_insensitive_:
new_cls._patch_to_ptr_type(p, True)
else:
new_cls._patch_to_ptr_type(p, False)
new_cls._patch_case_insensitive_to_ptr_type(p)
new_cls._patch_reference_fix_to_ptrptr_type(p)

return new_cls

@staticmethod
def _patch_to_ptr_type(p, case_insensitive) -> None:
if case_insensitive:

@patcher.Patch(p)
class CaseInsensitive(object):
# case insensitive attributes for COM methods and properties
def __getattr__(self, name):
"""Implement case insensitive access to methods and properties"""
try:
fixed_name = self.__map_case__[name.lower()]
except KeyError:
raise AttributeError(name)
if fixed_name != name: # prevent unbounded recursion
return getattr(self, fixed_name)
raise AttributeError(name)

# __setattr__ is pretty heavy-weight, because it is called for
# EVERY attribute assignment. Settings a non-com attribute
# through this function takes 8.6 usec, while without this
# function it takes 0.7 sec - 12 times slower.
#
# How much faster would this be if implemented in C?
def __setattr__(self, name, value):
"""Implement case insensitive access to methods and properties"""
object.__setattr__(
self, self.__map_case__.get(name.lower(), name), value
)
def _patch_case_insensitive_to_ptr_type(p: Type) -> None:
@patcher.Patch(p)
class CaseInsensitive(object):
# case insensitive attributes for COM methods and properties
def __getattr__(self, name):
"""Implement case insensitive access to methods and properties"""
try:
fixed_name = self.__map_case__[name.lower()]
except KeyError:
raise AttributeError(name) # Should we use exception-chaining?
if fixed_name != name: # prevent unbounded recursion
return getattr(self, fixed_name)
raise AttributeError(name)

# __setattr__ is pretty heavy-weight, because it is called for
# EVERY attribute assignment. Settings a non-com attribute
# through this function takes 8.6 usec, while without this
# function it takes 0.7 sec - 12 times slower.
#
# How much faster would this be if implemented in C?
def __setattr__(self, name, value):
"""Implement case insensitive access to methods and properties"""
object.__setattr__(
self, self.__map_case__.get(name.lower(), name), value
)

@staticmethod
def _patch_reference_fix_to_ptrptr_type(p: Type) -> None:
@patcher.Patch(POINTER(p))
class ReferenceFix(object):
def __setitem__(self, index, value):
Expand All @@ -158,11 +157,11 @@ def __setitem__(self, index, value):
# CopyComPointer should do if index != 0.
if bool(value):
value.AddRef()
super(POINTER(p), self).__setitem__(index, value)
super(POINTER(p), self).__setitem__(index, value) # type: ignore
return
from _ctypes import CopyComPointer

CopyComPointer(value, self)
CopyComPointer(value, self) # type: ignore

def __setattr__(self, name, value):
if name == "_methods_":
Expand Down

0 comments on commit 621ec95

Please sign in to comment.