Skip to content

Commit

Permalink
change _MemberSpecs to NamedTuples (enthought#484)
Browse files Browse the repository at this point in the history
* change `_MemberSpec` to `NamedTuple`

* `_ComMemberSpec` is no more `Generic`
for Py<3.11 backward compatibility.

* apply `black` style
  • Loading branch information
junkmd authored Jun 4, 2023
1 parent 9724dc0 commit 94b81af
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 53 deletions.
8 changes: 4 additions & 4 deletions comtypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,17 +720,17 @@ class dispid(int):
# instances with more methods or properties, and should not behave as an unpackable.


def STDMETHOD(restype, name, argtypes=()):
def STDMETHOD(restype, name, argtypes=()) -> _ComMemberSpec:
"Specifies a COM method slot without idlflags"
return _ComMemberSpec(restype, name, argtypes, None, (), None)


def DISPMETHOD(idlflags, restype, name, *argspec):
def DISPMETHOD(idlflags, restype, name, *argspec) -> _DispMemberSpec:
"Specifies a method of a dispinterface"
return _DispMemberSpec("DISPMETHOD", name, tuple(idlflags), restype, argspec)


def DISPPROPERTY(idlflags, proptype, name):
def DISPPROPERTY(idlflags, proptype, name) -> _DispMemberSpec:
"Specifies a property of a dispinterface"
return _DispMemberSpec("DISPPROPERTY", name, tuple(idlflags), proptype, ())

Expand All @@ -744,7 +744,7 @@ def DISPPROPERTY(idlflags, proptype, name):
# )


def COMMETHOD(idlflags, restype, methodname, *argspec):
def COMMETHOD(idlflags, restype, methodname, *argspec) -> _ComMemberSpec:
"""Specifies a COM method slot with idlflags.
XXX should explain the sematics of the arguments.
Expand Down
76 changes: 27 additions & 49 deletions comtypes/_memberspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Dict,
Iterator,
List,
NamedTuple,
Optional,
Tuple,
Type,
Expand Down Expand Up @@ -82,56 +83,28 @@ def _resolve_argspec(
return tuple(paramflags), tuple(argtypes)


class _MemberSpec(object):
"""Specifier of a slot of method or property."""

__slots__ = ("name", "idlflags", "restype")
class _ComMemberSpec(NamedTuple):
"""Specifier for a slot of COM method or property."""

def __init__(self, name, idlflags, restype):
self.name: str = name
self.idlflags: Tuple[_UnionT[str, int], ...] = idlflags
self.restype: Optional[Type[_CData]] = restype
restype: Optional[Type[_CData]]
name: str
argtypes: Tuple[Type[_CData], ...]
paramflags: Optional[Tuple[_ParamFlagType, ...]]
idlflags: Tuple[_UnionT[str, int], ...]
doc: Optional[str]

def is_prop(self) -> bool:
propflags = ("propget", "propput", "propputref")
return any(f in propflags for f in self.idlflags)
return _is_spec_prop(self)


class _ComMemberSpec(_MemberSpec):
"""Specifier for a slot of COM method or property."""

__slots__ = ("argtypes", "paramflags", "doc")

def __init__(self, restype, name, argtypes, paramflags, idlflags, doc):
self.argtypes: Tuple[Type[_CData], ...] = argtypes
self.paramflags: Optional[Tuple[_ParamFlagType, ...]] = paramflags
self.doc: Optional[str] = doc
super(_ComMemberSpec, self).__init__(name, idlflags, restype)

def __iter__(self):
# for backward compatibility:
# A function that returns this object used to return a `tuple`.
# So it is implemented as unpackable as well.
for item in (
self.restype,
self.name,
self.argtypes,
self.paramflags,
self.idlflags,
self.doc,
):
yield item


class _DispMemberSpec(_MemberSpec):
class _DispMemberSpec(NamedTuple):
"""Specifier for a slot of dispinterface method or property."""

__slots__ = ("what", "argspec")

def __init__(self, what, name, idlflags, restype, argspec):
self.what: str = what
self.argspec: Tuple[_ArgSpecElmType, ...] = argspec
super(_DispMemberSpec, self).__init__(name, idlflags, restype)
what: str
name: str
idlflags: Tuple[_UnionT[str, int], ...]
restype: Optional[Type[_CData]]
argspec: Tuple[_ArgSpecElmType, ...]

@property
def memid(self) -> int:
Expand All @@ -140,12 +113,17 @@ def memid(self) -> int:
except IndexError:
raise TypeError("no dispid found in idlflags")

def __iter__(self):
# for backward compatibility:
# A function that returns this object used to return a `tuple`.
# So it is implemented as unpackable as well.
for item in (self.what, self.name, self.idlflags, self.restype, self.argspec):
yield item
def is_prop(self) -> bool:
return _is_spec_prop(self)


# Specifier of a slot of method or property.
# This should be `typing.Protocol` if supporting Py3.8+ only.
_MemberSpec = _UnionT[_ComMemberSpec, _DispMemberSpec]


def _is_spec_prop(m: _MemberSpec):
return any(f in ("propget", "propput", "propputref") for f in m.idlflags)


_PropFunc = Optional[Callable[..., Any]]
Expand Down

0 comments on commit 94b81af

Please sign in to comment.