Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 14 additions & 18 deletions comtypes/_post_coinit/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,24 +142,20 @@ def CoCreateInstance(
return p # type: ignore


if TYPE_CHECKING:

@overload
def CoGetClassObject(
clsid: GUID,
clsctx: Optional[int] = None,
pServerInfo: "Optional[COSERVERINFO]" = None,
interface: None = None,
) -> hints.IClassFactory: ...
@overload
def CoGetClassObject(
clsid: GUID,
clsctx: Optional[int] = None,
pServerInfo: "Optional[COSERVERINFO]" = None,
interface: type[_T_IUnknown] = hints.IClassFactory,
) -> _T_IUnknown: ...


@overload
def CoGetClassObject(
clsid: GUID,
clsctx: Optional[int] = None,
pServerInfo: "Optional[COSERVERINFO]" = None,
interface: None = None,
) -> "hints.IClassFactory": ...
@overload
def CoGetClassObject(
clsid: GUID,
clsctx: Optional[int] = None,
pServerInfo: "Optional[COSERVERINFO]" = None,
interface: type[_T_IUnknown] = IUnknown,
) -> _T_IUnknown: ...
def CoGetClassObject(
clsid: GUID,
clsctx: Optional[int] = None,
Expand Down
40 changes: 20 additions & 20 deletions comtypes/client/_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@
#
# Object creation
#
if TYPE_CHECKING:

@overload
def GetClassObject(
progid: _UnionT[str, type[CoClass], GUID],
clsctx: Optional[int] = None,
pServerInfo: Optional[COSERVERINFO] = None,
interface: None = None,
) -> hints.IClassFactory: ...
@overload
def GetClassObject(
progid: _UnionT[str, type[CoClass], GUID],
clsctx: Optional[int] = None,
pServerInfo: Optional[COSERVERINFO] = None,
interface: type[_T_IUnknown] = hints.IClassFactory,
) -> _T_IUnknown: ...


def GetClassObject(progid, clsctx=None, pServerInfo=None, interface=None):
# type: (_UnionT[str, type[CoClass], GUID], Optional[int], Optional[COSERVERINFO], Optional[type[IUnknown]]) -> IUnknown
@overload
def GetClassObject(
progid: _UnionT[str, type[CoClass], GUID],
clsctx: Optional[int] = None,
pServerInfo: Optional[COSERVERINFO] = None,
interface: None = None,
) -> "hints.IClassFactory": ...
@overload
def GetClassObject(
progid: _UnionT[str, type[CoClass], GUID],
clsctx: Optional[int] = None,
pServerInfo: Optional[COSERVERINFO] = None,
interface: type[_T_IUnknown] = IUnknown,
) -> _T_IUnknown: ...
def GetClassObject(
progid: _UnionT[str, type[CoClass], GUID],
clsctx: Optional[int] = None,
pServerInfo: Optional[COSERVERINFO] = None,
interface: Optional[type[IUnknown]] = None,
) -> IUnknown:
"""Create and return the class factory for a COM object.

'clsctx' specifies how to create the object, use the CLSCTX_... constants.
Expand Down
21 changes: 21 additions & 0 deletions comtypes/test/test_classfactory.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import unittest as ut

import comtypes.client
from comtypes import GUID, CoGetClassObject, IUnknown, shelllink
from comtypes.server import IClassFactory

CLSID_ShellLink = GUID("{00021401-0000-0000-C000-000000000046}")

REGDB_E_CLASSNOTREG = -2147221164 # 0x80040154
HKCU = 1 # HKEY_CURRENT_USER


class Test_CreateInstance(ut.TestCase):
Expand All @@ -27,6 +29,25 @@ def test_returns_iunknown_type_instance(self):
shlnk.SetDescription("sample")
self.assertEqual(shlnk.GetDescription(), "sample")

def test_returns_lazybind_dynamic_dispatch_if_typeinfo_is_available(self):
# When `dynamic=True`, objects providing type information will return a
# `lazybind.Dispatch` instance.
class_factory = comtypes.client.GetClassObject("Scripting.Dictionary")
self.assertIsInstance(class_factory, IClassFactory)
dic = class_factory.CreateInstance(dynamic=True)
self.assertIsInstance(dic, comtypes.client.lazybind.Dispatch)
dic.Item["key"] = "value"
self.assertEqual(dic.Item["key"], "value")

def test_returns_fully_dynamic_dispatch_if_typeinfo_is_unavailable(self):
# When `dynamic=True`, objects that do NOT provide type information (or
# fail to provide it) will return a `dynamic._Dispatch` instance.
class_factory = comtypes.client.GetClassObject("WindowsInstaller.Installer")
self.assertIsInstance(class_factory, IClassFactory)
inst = class_factory.CreateInstance(dynamic=True)
self.assertIsInstance(inst, comtypes.client.dynamic._Dispatch)
self.assertTrue(inst.RegistryValue(HKCU, r"Control Panel\Desktop"))

def test_raises_valueerror_if_takes_dynamic_true_and_interface_explicitly(self):
class_factory = CoGetClassObject(CLSID_ShellLink)
self.assertIsInstance(class_factory, IClassFactory)
Expand Down