Skip to content

Commit

Permalink
add static typing for when a CoClass is assigned as the return valu…
Browse files Browse the repository at this point in the history
…e type (#542)

* add `Annotated` to `hints`

* add coclass interpretations to `typeannotator._to_outtype`
junkmd authored May 11, 2024
1 parent 3c613d6 commit 78a298c
Showing 2 changed files with 20 additions and 0 deletions.
15 changes: 15 additions & 0 deletions comtypes/hints.pyi
Original file line number Diff line number Diff line change
@@ -21,6 +21,10 @@ if sys.version_info >= (3, 8):
from typing import Protocol
else:
from typing_extensions import Protocol
if sys.version_info >= (3, 9):
from typing import Annotated as Annotated
else:
from typing_extensions import Annotated as Annotated
if sys.version_info >= (3, 10):
from typing import Concatenate, ParamSpec, TypeAlias
from typing import TypeGuard as TypeGuard
@@ -32,6 +36,7 @@ if sys.version_info >= (3, 11):
else:
from typing_extensions import Self

import comtypes
from comtypes.automation import IDispatch as IDispatch, VARIANT as VARIANT
from comtypes.server import IClassFactory as IClassFactory
from comtypes.typeinfo import ITypeInfo as ITypeInfo
@@ -46,6 +51,16 @@ Hresult: TypeAlias = int
arguments and with `HRESULT` as its return type in its COM method definition.
"""

_T_coclass = TypeVar("_T_coclass", bound=comtypes.CoClass)

class FirstComItfOf(Generic[_T_coclass]):
"""When the type assigned to the parameter marked as `'out'` is `CoClass`,
the return type of that method at runtime becomes `_com_interface_[0]`
due to the metaclass.
This is used as `Annotated` metadata for such parameters, taking `CoClass`
as an argument.
"""

class _MethodTypeDesc(Protocol):
arguments: List[Tuple[Any, str, List[str], Optional[Any]]]
idlflags: List[str]
5 changes: 5 additions & 0 deletions comtypes/tools/typeannotator.py
Original file line number Diff line number Diff line change
@@ -223,6 +223,11 @@ def _to_outtype(typ: Any) -> str:
return f"'{typ.name}'"
elif isinstance(typ, typedesc.ComInterface):
return f"'{typ.name}'"
elif isinstance(typ, typedesc.CoClass):
impl, _ = typedesc.groupby_impltypeflags(typ.interfaces)
if impl:
meta = f"hints.FirstComItfOf['{typ.name}']"
return f"hints.Annotated[{_to_outtype(impl[0])}, {meta}]"
return "hints.Incomplete"


0 comments on commit 78a298c

Please sign in to comment.