Skip to content
4 changes: 0 additions & 4 deletions stubs/pywin32/@tests/stubtest_allowlist_win32.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@ win32com.client.combrowse
win32com.client.tlbrowse

# Utilities to generate python bindings
win32com.client.build.*
win32com.client.CLSIDToClass
win32com.client.connect
# "dynamic.CDipatch" is necessary for mypy to not throw AssertionError
win32com.client.dynamic.*
win32com.client.gencache.*
win32com.client.genpy
win32com.client.makepy
win32com.client.selecttlb
Expand Down
49 changes: 24 additions & 25 deletions stubs/pywin32/win32com/client/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,30 @@ from typing_extensions import TypeAlias

import _win32typing
from pythoncom import com_record
from win32.lib.pywintypes import IIDType
from win32com.client import dynamic

_Stringifiable: TypeAlias = object

def GetObject(Pathname: str | None = ..., Class: Incomplete | None = ..., clsctx: Incomplete | None = ...) -> CDispatch: ...
def GetActiveObject(Class, clsctx=...): ...
def Moniker(Pathname, clsctx=...): ...
def GetObject(Pathname: str | None = None, Class=None, clsctx=None) -> CDispatch: ...
def GetActiveObject(Class: str, clsctx=...): ...
def Moniker(Pathname: str, clsctx=...): ...
def Dispatch(
dispatch: str | dynamic.PyIDispatchType | dynamic._GoodDispatchTypes | dynamic.PyIUnknownType,
userName: str | None = ...,
resultCLSID: _Stringifiable | None = ...,
typeinfo: _win32typing.PyITypeInfo | None = ...,
dispatch: str | dynamic.PyIDispatchType | IIDType | dynamic.PyIUnknownType,
userName: str | None = None,
resultCLSID: _Stringifiable | None = None,
typeinfo: _win32typing.PyITypeInfo | None = None,
clsctx: int = ...,
) -> dynamic.CDispatch: ...
def DispatchEx(
clsid,
machine: Incomplete | None = ...,
userName: Incomplete | None = ...,
resultCLSID: Incomplete | None = ...,
typeinfo: Incomplete | None = ...,
clsctx: Incomplete | None = ...,
): ...
def DispatchEx(clsid, machine=None, userName=None, resultCLSID=None, typeinfo=None, clsctx=None): ...

class CDispatch(dynamic.CDispatch):
def __dir__(self): ...
def __dir__(self) -> list[str]: ...

def CastTo(ob, target, typelib: Incomplete | None = ...): ...
def CastTo(ob, target, typelib=None): ...

class Constants:
__dicts__: Incomplete
__dicts__: list[Incomplete]
def __getattr__(self, a: str): ...

constants: Final[Constants]
Expand All @@ -45,22 +39,22 @@ class EventsProxy:
def __getattr__(self, attr: str): ...
def __setattr__(self, attr: str, val) -> None: ...

def DispatchWithEvents(clsid, user_event_class): ...
def DispatchWithEvents(clsid, user_event_class) -> EventsProxy: ...
def WithEvents(disp, user_event_class): ...
def getevents(clsid): ...
def Record(name, object) -> com_record: ...
def register_record_class(cls) -> None: ...

class DispatchBaseClass:
def __init__(self, oobj: Incomplete | None = ...) -> None: ...
def __dir__(self): ...
def __eq__(self, other): ...
def __ne__(self, other): ...
def __init__(self, oobj=None) -> None: ...
def __dir__(self) -> list[str]: ...
def __eq__(self, other) -> bool: ...
def __ne__(self, other) -> bool: ...
def __getattr__(self, attr: str): ...
def __setattr__(self, attr: str, value) -> None: ...

class CoClassBaseClass:
def __init__(self, oobj: Incomplete | None = ...) -> None: ...
def __init__(self, oobj=None) -> None: ...
def __getattr__(self, attr: str): ...
def __setattr__(self, attr: str, value) -> None: ...
def __call__(self, *args, **kwargs): ...
Expand All @@ -73,4 +67,9 @@ class CoClassBaseClass:
class VARIANT:
varianttype: Incomplete
def __init__(self, vt, value) -> None: ...
value: Incomplete
@property
def value(self): ...
@value.setter
def value(self, newval) -> None: ...
@value.deleter
def value(self) -> None: ...
84 changes: 59 additions & 25 deletions stubs/pywin32/win32com/client/build.pyi
Original file line number Diff line number Diff line change
@@ -1,36 +1,70 @@
from _typeshed import Incomplete
from collections.abc import Iterable
from typing import ClassVar, Final, Literal

class NotSupportedException(Exception): ...

DropIndirection: Final = "DropIndirection"
NoTranslateTypes: Final[list[int]]
NoTranslateMap: Final[set[int]]

class MapEntry:
dispid: Incomplete
desc: Incomplete | None
names: Incomplete
doc: Incomplete
resultCLSID: Incomplete
resultDocumentation: Incomplete | None
wasProperty: Incomplete
hidden: bool | Literal[0, 1]
def __init__(
self, desc_or_id, names=None, doc=None, resultCLSID=..., resultDoc=None, hidden: bool | Literal[0, 1] = 0
) -> None: ...
def GetResultCLSID(self) -> Incomplete | None: ...
def GetResultCLSIDStr(self) -> str: ...
def GetResultName(self) -> Incomplete | None: ...

class OleItem:
typename: str
typename: ClassVar[str]
doc: Incomplete
python_name: Incomplete
bWritten: int
bIsDispatch: int
bIsSink: int
clsid: Incomplete
co_class: Incomplete
def __init__(self, doc: Incomplete | None = ...) -> None: ...
python_name: Incomplete | None
bWritten: bool | Literal[0, 1]
bIsDispatch: bool | Literal[0, 1]
bIsSink: bool | Literal[0, 1]
clsid: Incomplete | None
co_class: Incomplete | None
def __init__(self, doc=None) -> None: ...

class DispatchItem(OleItem):
typename: str
propMap: Incomplete
propMapGet: Incomplete
propMapPut: Incomplete
mapFuncs: Incomplete
defaultDispatchName: Incomplete
hidden: int
def __init__(
self, typeinfo: Incomplete | None = ..., attr: Incomplete | None = ..., doc: Incomplete | None = ..., bForUser: int = ...
) -> None: ...
typename: ClassVar[str]
propMap: dict[Incomplete, Incomplete]
propMapGet: dict[Incomplete, Incomplete]
propMapPut: dict[Incomplete, Incomplete]
mapFuncs: dict[Incomplete, Incomplete]
defaultDispatchName: Incomplete | None
hidden: bool | Literal[0, 1]
def __init__(self, typeinfo=None, attr=None, doc=None, bForUser: bool | Literal[0, 1] = 1) -> None: ...
clsid: Incomplete
bIsDispatch: Incomplete
def Build(self, typeinfo, attr, bForUser: int = ...) -> None: ...
def CountInOutOptArgs(self, argTuple): ...
def MakeFuncMethod(self, entry, name, bMakeClass: int = ...): ...
def MakeDispatchFuncMethod(self, entry, name, bMakeClass: int = ...): ...
def MakeVarArgsFuncMethod(self, entry, name, bMakeClass: int = ...): ...
bIsDispatch: bool | Literal[0, 1]
def Build(self, typeinfo, attr, bForUser: bool | Literal[0, 1] = 1) -> None: ...
def CountInOutOptArgs(self, argTuple: Iterable[Incomplete]) -> tuple[int, int, int]: ...
def MakeFuncMethod(self, entry, name: str, bMakeClass: bool | Literal[0, 1] = 1) -> list[str]: ...
def MakeDispatchFuncMethod(self, entry, name: str, bMakeClass: bool | Literal[0, 1] = 1) -> list[str]: ...
def MakeVarArgsFuncMethod(self, entry, name: str, bMakeClass: bool | Literal[0, 1] = 1) -> list[str]: ...

class VTableItem(DispatchItem):
vtableFuncs: list[tuple[Incomplete, Incomplete, Incomplete]]
def Build(self, typeinfo, attr, bForUser: bool | Literal[0, 1] = 1) -> None: ...

class LazyDispatchItem(DispatchItem):
typename: str
typename: ClassVar[str]
clsid: Incomplete
def __init__(self, attr, doc) -> None: ...

typeSubstMap: Final[dict[int, int]]
valid_identifier_chars: Final[str]

def demunge_leading_underscores(className: str) -> str: ...
def MakePublicAttributeName(className: str, is_global: bool = False) -> str: ...
def MakeDefaultArgRepr(defArgVal) -> str | None: ...
def BuildCallList(fdesc, names, defNamedOptArg, defNamedNotOptArg, defUnnamedArg, defOutArg, is_comment: bool = False) -> str: ...
46 changes: 22 additions & 24 deletions stubs/pywin32/win32com/client/dynamic.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from _typeshed import Incomplete
from typing import Any, Protocol, TypeVar, overload
from typing_extensions import TypeAlias
from typing import Any, Final, Literal, Protocol, TypeVar, overload, type_check_only

import _win32typing
from win32.lib.pywintypes import IIDType
Expand All @@ -9,60 +8,59 @@ from win32com.client import build
_T_co = TypeVar("_T_co", covariant=True)
_T = TypeVar("_T")

@type_check_only
class _DispatchCreateClass(Protocol[_T_co]):
Comment on lines +11 to 12
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @brianschubert I didn’t find any occurrences of this name in the source code (via grep), so I thought this case might also be interesting for your stubtest patch.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is covered by an allowlist entry, which is why it hasn't been flagged yet:

# "dynamic.CDipatch" is necessary for mypy to not throw AssertionError
win32com.client.dynamic.*

Maybe you can refine that while we're here?

@staticmethod
def __call__(
IDispatch: str | PyIDispatchType | _GoodDispatchTypes | PyIUnknownType,
IDispatch: str | PyIDispatchType | IIDType | PyIUnknownType,
olerepr: build.DispatchItem | build.LazyDispatchItem,
userName: str | None = ...,
lazydata: Incomplete | None = ...,
userName: str | None = None,
lazydata=None,
) -> _T_co: ...

debugging: int
debugging_attr: int
LCID: int
ERRORS_BAD_CONTEXT: Incomplete
ALL_INVOKE_TYPES: Incomplete
LCID: Final = 0x0
ERRORS_BAD_CONTEXT: Final[list[int]]
ALL_INVOKE_TYPES: Final[list[int]]

def debug_print(*args) -> None: ...
def debug_attr_print(*args) -> None: ...
def debug_print(*args: object) -> None: ...
def debug_attr_print(*args: object) -> None: ...

PyIDispatchType = _win32typing.PyIDispatch
PyIUnknownType = _win32typing.PyIUnknown

_GoodDispatchTypes: TypeAlias = tuple[type[str], type[IIDType]]

@overload
def Dispatch(
IDispatch: str | PyIDispatchType | _GoodDispatchTypes | PyIUnknownType,
IDispatch: str | PyIDispatchType | IIDType | PyIUnknownType,
userName: str | None,
createClass: _DispatchCreateClass[_T],
typeinfo: _win32typing.PyITypeInfo | None = ...,
typeinfo: _win32typing.PyITypeInfo | None = None,
clsctx: int = ...,
) -> _T: ...
@overload
def Dispatch(
IDispatch: str | PyIDispatchType | _GoodDispatchTypes | PyIUnknownType,
userName: str | None = ...,
IDispatch: str | PyIDispatchType | IIDType | PyIUnknownType,
userName: str | None = None,
createClass: None = None,
typeinfo: _win32typing.PyITypeInfo | None = ...,
typeinfo: _win32typing.PyITypeInfo | None = None,
clsctx: int = ...,
) -> CDispatch: ...
def MakeOleRepr(IDispatch, typeinfo, typecomp): ...
def DumbDispatch(IDispatch, userName: Incomplete | None = ..., createClass: Incomplete | None = ..., clsctx=...): ...
def MakeOleRepr(IDispatch, typeinfo, typecomp) -> build.DispatchItem | build.LazyDispatchItem: ...
def DumbDispatch(IDispatch, userName=None, createClass=None, clsctx=...): ...

class CDispatch:
def __init__(self, IDispatch, olerepr, userName: Incomplete | None = ..., lazydata: Incomplete | None = ...) -> None: ...
def __init__(self, IDispatch, olerepr, userName=None, lazydata=None) -> None: ...
def __call__(self, *args): ...
def __bool__(self) -> bool: ...
def __dir__(self): ...
def __eq__(self, other): ...
def __ne__(self, other): ...
def __dir__(self) -> list[str]: ...
def __eq__(self, other) -> bool: ...
def __ne__(self, other) -> bool: ...
def __int__(self) -> int: ...
def __len__(self) -> int: ...
def __getitem__(self, index): ...
def __setitem__(self, index, *args) -> None: ...
def __LazyMap__(self, attr): ...
def __LazyMap__(self, attr) -> Literal[0, 1] | None: ...
def __AttrToID__(self, attr): ...
ob: Incomplete
# CDispatch objects are dynamically generated and too complex to type
Expand Down
60 changes: 59 additions & 1 deletion stubs/pywin32/win32com/client/gencache.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,63 @@
from _typeshed import Incomplete, Unused
from collections.abc import Generator
from contextlib import contextmanager
from types import ModuleType
from typing import Literal, NoReturn

from win32.lib.pywintypes import IIDType
from win32com.client import dynamic

bForDemandDefault: int
clsidToTypelib: dict[str, tuple[str, int, int, int]]
versionRedirectMap: dict[tuple[str, int, int, int], ModuleType | None]
is_readonly: bool
is_zip: bool
demandGeneratedTypeLibraries: dict[tuple[str, int, int, int], Incomplete]

def __init__() -> None: ...

pickleVersion: int

@contextmanager
def ModuleMutex(module_name: str) -> Generator[None]: ...
def GetGeneratedFileName(clsid, lcid, major, minor) -> str: ...
def SplitGeneratedFileName(fname: str) -> tuple[str, ...]: ...
def GetGeneratePath() -> str: ...
def GetClassForProgID(progid: str) -> type | None: ...
def GetClassForCLSID(clsid) -> type | None: ...
def GetModuleForProgID(progid: str) -> ModuleType | None: ...
def GetModuleForCLSID(clsid) -> ModuleType | None: ...
def GetModuleForTypelib(typelibCLSID, lcid, major, minor) -> ModuleType: ...
def MakeModuleForTypelib(
typelibCLSID,
lcid,
major,
minor,
progressInstance=None,
bForDemand: bool | Literal[0, 1] = ...,
bBuildHidden: bool | Literal[0, 1] = 1,
) -> ModuleType: ...
def MakeModuleForTypelibInterface(
typelib_ob, progressInstance=None, bForDemand: bool | Literal[0, 1] = ..., bBuildHidden: bool | Literal[0, 1] = 1
) -> ModuleType | None: ...
def EnsureModuleForTypelibInterface(
typelib_ob, progressInstance=None, bForDemand: bool | Literal[0, 1] = ..., bBuildHidden: bool | Literal[0, 1] = 1
) -> ModuleType | None: ...
def ForgetAboutTypelibInterface(typelib_ob) -> None: ...
def EnsureModule(
typelibCLSID,
lcid,
major,
minor,
progressInstance=None,
bValidateFile: bool | Literal[0, 1] = ...,
bForDemand: bool | Literal[0, 1] = ...,
bBuildHidden: bool | Literal[0, 1] = 1,
) -> ModuleType | None: ...
def EnsureDispatch(
prog_id: str | dynamic.PyIDispatchType | dynamic._GoodDispatchTypes | dynamic.PyIUnknownType, bForDemand: int = ...
prog_id: str | dynamic.PyIDispatchType | IIDType | dynamic.PyIUnknownType, bForDemand: bool | Literal[0, 1] = 1
) -> dynamic.CDispatch: ...
def AddModuleToCache(typelibclsid, lcid, major, minor, verbose: Unused = 1, bFlushNow: bool | Literal[0, 1] = ...) -> None: ...
def GetGeneratedInfos() -> list[tuple[Incomplete, Incomplete, Incomplete, Incomplete]]: ...
def Rebuild(verbose: bool | Literal[0, 1] = 1) -> None: ...
def usage() -> NoReturn: ...
Loading
Loading