Skip to content

Commit

Permalink
Add comments to metaclasses. (enthought#635)
Browse files Browse the repository at this point in the history
* Add a comment and `pass` to `_compointer_meta`.

* Add comments to `_coclass_pointer_meta`.

* Add a `HACK` comment
to `_coclass_meta.__new__`.

* Add a `HACK` comment
to `_cominterface_meta.__new__`.

* Add comments for `_ptr_bases`.

* Small fixes for comments.
  • Loading branch information
junkmd authored Oct 7, 2024
1 parent 99f8900 commit 07e0664
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
15 changes: 14 additions & 1 deletion comtypes/_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ class _coclass_meta(type):
def __new__(cls, name, bases, namespace):
self = type.__new__(cls, name, bases, namespace)
if bases == (object,):
# HACK: Could this conditional branch be removed since it is never reached?
# Since definition is `class CoClass(COMObject, metaclass=_coclass_meta)`,
# the `bases` parameter passed to the `_coclass_meta.__new__` would be
# `(COMObject,)`.
# Moreover, since the `COMObject` derives from `object` and does not specify
# a metaclass, `(object,)` will not be passed as the `bases` parameter
# to the `_coclass_meta.__new__`.
# The reason for this implementation might be a remnant of the differences
# in how metaclasses work between Python 3.x and Python 2.x.
# If there are no problems with the versions of Python that `comtypes`
# supports, this removal could make the process flow easier to understand.
return self
# XXX We should insist that a _reg_clsid_ is present.
if "_reg_clsid_" in namespace:
Expand All @@ -67,4 +78,6 @@ def __new__(cls, name, bases, namespace):

# will not work if we change the order of the two base classes!
class _coclass_pointer_meta(type(c_void_p), _coclass_meta):
pass
# metaclass for CoClass pointer

pass # no functionality, but needed to avoid a metaclass conflict
15 changes: 13 additions & 2 deletions comtypes/_post_coinit/unknwn.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,21 @@ def __new__(cls, name, bases, namespace):
# subclass of POINTER(IUnknown) because of the way ctypes
# typechecks work.
if bases == (object,):
# `self` is the `IUnknown` type.
_ptr_bases = (self, _compointer_base)
else:
# `self` is an interface type derived from `IUnknown`.
_ptr_bases = (self, POINTER(bases[0]))

# The interface 'self' is used as a mixin.
# HACK: Could `type(_compointer_base)` be replaced with `_compointer_meta`?
# `type(klass)` returns its metaclass.
# Since this specification, `type(_compointer_base)` will return the
# `_compointer_meta` type as per the class definition.
# The reason for this implementation might be a remnant of the differences in
# how metaclasses work between Python 3.x and Python 2.x.
# If there are no problems with the versions of Python that `comtypes`
# supports, this replacement could make the process flow easier to understand.
p = type(_compointer_base)(
f"POINTER({self.__name__})",
_ptr_bases,
Expand Down Expand Up @@ -369,10 +379,11 @@ def _make_methods(self, methods: List[_ComMemberSpec]) -> None:
################################################################


# will not work if we change the order of the two base classes!
class _compointer_meta(type(c_void_p), _cominterface_meta):
"metaclass for COM interface pointer classes"
"""metaclass for COM interface pointer classes"""

# no functionality, but needed to avoid a metaclass conflict
pass # no functionality, but needed to avoid a metaclass conflict


class _compointer_base(c_void_p, metaclass=_compointer_meta):
Expand Down

0 comments on commit 07e0664

Please sign in to comment.