comtypes 1.4.6__zip → 1.4.7__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. {comtypes-1.4.6 → comtypes-1.4.7}/CHANGES.txt +18 -0
  2. {comtypes-1.4.6/comtypes.egg-info → comtypes-1.4.7}/PKG-INFO +28 -36
  3. {comtypes-1.4.6 → comtypes-1.4.7}/README.md +26 -34
  4. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/__init__.py +1 -1
  5. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_post_coinit/bstr.py +13 -6
  6. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/automation.py +9 -15
  7. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/hints.pyi +2 -0
  8. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/persist.py +19 -3
  9. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/shelllink.py +72 -21
  10. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_client.py +9 -0
  11. comtypes-1.4.7/comtypes/test/test_monikers.py +70 -0
  12. comtypes-1.4.7/comtypes/test/test_persist.py +40 -0
  13. comtypes-1.4.7/comtypes/test/test_shelllink.py +133 -0
  14. comtypes-1.4.7/comtypes/test/test_storage.py +127 -0
  15. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/typeinfo.py +25 -22
  16. {comtypes-1.4.6 → comtypes-1.4.7/comtypes.egg-info}/PKG-INFO +28 -36
  17. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes.egg-info/SOURCES.txt +5 -1
  18. {comtypes-1.4.6 → comtypes-1.4.7}/setup.cfg +1 -1
  19. {comtypes-1.4.6 → comtypes-1.4.7}/LICENSE.txt +0 -0
  20. {comtypes-1.4.6 → comtypes-1.4.7}/MANIFEST.in +0 -0
  21. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/GUID.py +0 -0
  22. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_comobject.py +0 -0
  23. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_idl_stuff.py +0 -0
  24. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_memberspec.py +0 -0
  25. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_meta.py +0 -0
  26. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_npsupport.py +0 -0
  27. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_post_coinit/__init__.py +0 -0
  28. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_post_coinit/misc.py +0 -0
  29. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_post_coinit/unknwn.py +0 -0
  30. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_py_instance_method.py +0 -0
  31. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_safearray.py +0 -0
  32. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/_tlib_version_checker.py +0 -0
  33. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/clear_cache.py +0 -0
  34. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/client/__init__.py +0 -0
  35. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/client/_code_cache.py +0 -0
  36. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/client/_constants.py +0 -0
  37. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/client/_events.py +0 -0
  38. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/client/_generate.py +0 -0
  39. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/client/dynamic.py +0 -0
  40. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/client/lazybind.py +0 -0
  41. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/connectionpoints.py +0 -0
  42. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/errorinfo.py +0 -0
  43. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/git.py +0 -0
  44. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/hresult.py +0 -0
  45. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/logutil.py +0 -0
  46. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/messageloop.py +0 -0
  47. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/patcher.py +0 -0
  48. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/safearray.py +0 -0
  49. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/server/__init__.py +0 -0
  50. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/server/automation.py +0 -0
  51. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/server/connectionpoints.py +0 -0
  52. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/server/inprocserver.py +0 -0
  53. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/server/localserver.py +0 -0
  54. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/server/register.py +0 -0
  55. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/server/w_getopt.py +0 -0
  56. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/stream.py +0 -0
  57. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/TestComServer.idl +0 -0
  58. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/TestComServer.py +0 -0
  59. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/TestComServer.tlb +0 -0
  60. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/TestDispServer.idl +0 -0
  61. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/TestDispServer.py +0 -0
  62. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/TestDispServer.tlb +0 -0
  63. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/__init__.py +0 -0
  64. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/find_memleak.py +0 -0
  65. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/mylib.idl +0 -0
  66. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/mylib.tlb +0 -0
  67. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/mytypelib.idl +0 -0
  68. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/runtests.py +0 -0
  69. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/setup.py +0 -0
  70. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_BSTR.py +0 -0
  71. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_DISPPARAMS.py +0 -0
  72. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_GUID.py +0 -0
  73. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_QueryService.py +0 -0
  74. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_agilent.py +0 -0
  75. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_avmc.py +0 -0
  76. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_basic.py +0 -0
  77. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_casesensitivity.py +0 -0
  78. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_clear_cache.py +0 -0
  79. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_client_dynamic.py +0 -0
  80. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_client_regenerate_modules.py +0 -0
  81. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_collections.py +0 -0
  82. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_comserver.py +0 -0
  83. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_createwrappers.py +0 -0
  84. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_dict.py +0 -0
  85. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_dispifc_records.py +0 -0
  86. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_dispifc_safearrays.py +0 -0
  87. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_dispinterface.py +0 -0
  88. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_dyndispatch.py +0 -0
  89. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_excel.py +0 -0
  90. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_findgendir.py +0 -0
  91. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_getactiveobj.py +0 -0
  92. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_ie.py +0 -0
  93. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_ienum.py +0 -0
  94. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_imfattributes.py +0 -0
  95. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_inout_args.py +0 -0
  96. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_jscript.js +0 -0
  97. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_midl_safearray_create.py +0 -0
  98. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_msscript.py +0 -0
  99. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_npsupport.py +0 -0
  100. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_outparam.py +0 -0
  101. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_propputref.py +0 -0
  102. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_pump_events.py +0 -0
  103. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_recordinfo.py +0 -0
  104. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_safearray.py +0 -0
  105. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_sapi.py +0 -0
  106. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_server.py +0 -0
  107. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_showevents.py +0 -0
  108. /comtypes-1.4.6/comtypes/test/test_istream.py → /comtypes-1.4.7/comtypes/test/test_stream.py +0 -0
  109. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_subinterface.py +0 -0
  110. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_typeannotator.py +0 -0
  111. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_typeinfo.py +0 -0
  112. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_urlhistory.py +0 -0
  113. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_variant.py +0 -0
  114. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_win32com_interop.py +0 -0
  115. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_wmi.py +0 -0
  116. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/test_word.py +0 -0
  117. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/test/urlhist.tlb +0 -0
  118. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/__init__.py +0 -0
  119. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/codegenerator/__init__.py +0 -0
  120. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/codegenerator/codegenerator.py +0 -0
  121. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/codegenerator/helpers.py +0 -0
  122. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  123. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/codegenerator/namespaces.py +0 -0
  124. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/codegenerator/packing.py +0 -0
  125. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/codegenerator/typeannotator.py +0 -0
  126. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/tlbparser.py +0 -0
  127. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/typedesc.py +0 -0
  128. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/tools/typedesc_base.py +0 -0
  129. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/util.py +0 -0
  130. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes/viewobject.py +0 -0
  131. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes.egg-info/dependency_links.txt +0 -0
  132. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes.egg-info/entry_points.txt +0 -0
  133. {comtypes-1.4.6 → comtypes-1.4.7}/comtypes.egg-info/top_level.txt +0 -0
  134. {comtypes-1.4.6 → comtypes-1.4.7}/pyproject.toml +0 -0
  135. {comtypes-1.4.6 → comtypes-1.4.7}/setup.py +0 -0
@@ -0,0 +1,70 @@
1
+ from _ctypes import COMError
2
+ from ctypes import byref, POINTER
3
+ import contextlib
4
+ import unittest
5
+
6
+ import comtypes
7
+ from comtypes.client import GetModule, CreateObject
8
+ from comtypes import hresult, GUID
9
+
10
+ with contextlib.redirect_stdout(None): # supress warnings
11
+ GetModule("msvidctl.dll")
12
+ from comtypes.gen import MSVidCtlLib as msvidctl
13
+ from comtypes.gen.MSVidCtlLib import IBindCtx, IMoniker, IRunningObjectTable
14
+
15
+
16
+ MKSYS_ITEMMONIKER = 4
17
+ ROTFLAGS_ALLOWANYCLIENT = 1
18
+
19
+
20
+ def _create_item_moniker(delim: str, item: str) -> IMoniker:
21
+ mon = POINTER(IMoniker)()
22
+ comtypes._ole32.CreateItemMoniker(delim, item, byref(mon))
23
+ return mon # type: ignore
24
+
25
+
26
+ def _create_bctx() -> IBindCtx:
27
+ bctx = POINTER(IBindCtx)()
28
+ # The first parameter is reserved and must be 0.
29
+ comtypes._ole32.CreateBindCtx(0, byref(bctx))
30
+ return bctx # type: ignore
31
+
32
+
33
+ def _create_rot() -> IRunningObjectTable:
34
+ rot = POINTER(IRunningObjectTable)()
35
+ # The first parameter is reserved and must be 0.
36
+ comtypes._ole32.GetRunningObjectTable(0, byref(rot))
37
+ return rot # type: ignore
38
+
39
+
40
+ class Test_IMoniker(unittest.TestCase):
41
+ def test_IsSystemMoniker(self):
42
+ item_id = str(GUID.create_new())
43
+ mon = _create_item_moniker("!", item_id)
44
+ self.assertEqual(mon.IsSystemMoniker(), MKSYS_ITEMMONIKER)
45
+
46
+
47
+ class Test_IBindCtx(unittest.TestCase):
48
+ def test_EnumObjectParam(self):
49
+ bctx = _create_bctx()
50
+ with self.assertRaises(COMError) as err_ctx:
51
+ # calling `EnumObjectParam` results in a return value of E_NOTIMPL.
52
+ # https://learn.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-ibindctx-enumobjectparam#notes-to-callers
53
+ bctx.EnumObjectParam()
54
+ self.assertEqual(err_ctx.exception.hresult, hresult.E_NOTIMPL)
55
+
56
+
57
+ class Test_IRunningObjectTable(unittest.TestCase):
58
+ def test_register_and_revoke_item_moniker(self):
59
+ vidctl = CreateObject(msvidctl.MSVidCtl, interface=msvidctl.IMSVidCtl)
60
+ item_id = str(GUID.create_new())
61
+ mon = _create_item_moniker("!", item_id)
62
+ rot = _create_rot()
63
+ bctx = _create_bctx()
64
+ self.assertEqual(mon.IsRunning(bctx, None, None), hresult.S_FALSE)
65
+ dw_reg = rot.Register(ROTFLAGS_ALLOWANYCLIENT, vidctl, mon)
66
+ self.assertEqual(mon.IsRunning(bctx, None, None), hresult.S_OK)
67
+ self.assertEqual(f"!{item_id}", mon.GetDisplayName(bctx, None))
68
+ self.assertEqual(rot.GetObject(mon).QueryInterface(msvidctl.IMSVidCtl), vidctl)
69
+ rot.Revoke(dw_reg)
70
+ self.assertEqual(mon.IsRunning(bctx, None, None), hresult.S_FALSE)
@@ -0,0 +1,40 @@
1
+ from pathlib import Path
2
+ import tempfile
3
+ import unittest as ut
4
+
5
+ from comtypes import CoCreateInstance, GUID, IPersist
6
+ from comtypes import persist
7
+
8
+
9
+ CLSID_ShellLink = GUID("{00021401-0000-0000-C000-000000000046}")
10
+
11
+
12
+ class Test_IPersist(ut.TestCase):
13
+ def test_GetClassID(self):
14
+ p = CoCreateInstance(CLSID_ShellLink).QueryInterface(IPersist)
15
+ self.assertEqual(p.GetClassID(), CLSID_ShellLink)
16
+
17
+
18
+ class Test_IPersistFile(ut.TestCase):
19
+ def setUp(self):
20
+ td = tempfile.TemporaryDirectory()
21
+ self.addCleanup(td.cleanup)
22
+ self.tmp_dir = Path(td.name)
23
+
24
+ def _create_pf(self) -> persist.IPersistFile:
25
+ return CoCreateInstance(CLSID_ShellLink).QueryInterface(persist.IPersistFile)
26
+
27
+ def test_load(self):
28
+ pf = self._create_pf()
29
+ tgt_file = (self.tmp_dir / "tgt.txt").resolve()
30
+ tgt_file.touch()
31
+ pf.Load(str(tgt_file), persist.STGM_DIRECT)
32
+ self.assertEqual(pf.GetCurFile(), str(tgt_file))
33
+
34
+ def test_save(self):
35
+ pf = self._create_pf()
36
+ tgt_file = self.tmp_dir / "tgt.txt"
37
+ self.assertFalse(tgt_file.exists())
38
+ pf.Save(str(tgt_file), True)
39
+ self.assertEqual(pf.GetCurFile(), str(tgt_file))
40
+ self.assertTrue(tgt_file.exists())
@@ -0,0 +1,133 @@
1
+ from pathlib import Path
2
+ import tempfile
3
+ import unittest as ut
4
+
5
+ from comtypes import CoCreateInstance, GUID, shelllink
6
+ import comtypes.hresult
7
+ from comtypes.persist import IPersistFile
8
+
9
+
10
+ CLSID_ShellLink = GUID("{00021401-0000-0000-C000-000000000046}")
11
+
12
+
13
+ class Test_IShellLinkA(ut.TestCase):
14
+ def setUp(self):
15
+ td = tempfile.TemporaryDirectory()
16
+ self.addCleanup(td.cleanup)
17
+ self.tmp_dir = Path(td.name)
18
+ self.src_file = (self.tmp_dir / "src.txt").resolve()
19
+ self.src_file.touch()
20
+
21
+ def _create_shortcut(self) -> shelllink.IShellLinkA:
22
+ return CoCreateInstance(CLSID_ShellLink, interface=shelllink.IShellLinkA)
23
+
24
+ def test_set_and_get_path(self):
25
+ shortcut = self._create_shortcut()
26
+ pf = shortcut.QueryInterface(IPersistFile)
27
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_FALSE)
28
+ shortcut.SetPath(str(self.src_file).encode("utf-8"))
29
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_OK)
30
+ self.assertEqual(
31
+ shortcut.GetPath(shelllink.SLGP_UNCPRIORITY),
32
+ str(self.src_file).encode("utf-8"),
33
+ )
34
+ lnk_file = (self.tmp_dir / "new.lnk").resolve()
35
+ self.assertFalse(lnk_file.exists())
36
+ pf.Save(str(lnk_file), True)
37
+ self.assertTrue(lnk_file.exists())
38
+ self.assertEqual(pf.GetCurFile(), str(lnk_file))
39
+
40
+ def test_set_and_get_working_directory(self):
41
+ shortcut = self._create_shortcut()
42
+ shortcut.SetWorkingDirectory(str(self.tmp_dir).encode("utf-8"))
43
+ self.assertEqual(
44
+ shortcut.GetWorkingDirectory(), str(self.tmp_dir).encode("utf-8")
45
+ )
46
+
47
+ def test_set_and_get_arguments(self):
48
+ shortcut = self._create_shortcut()
49
+ shortcut.SetArguments(b"-f")
50
+ self.assertEqual(shortcut.GetArguments(), b"-f")
51
+
52
+ def test_set_and_get_hotkey(self):
53
+ HOTKEYF_ALT = 0x04
54
+ HOTKEYF_CONTROL = 0x02
55
+ shortcut = self._create_shortcut()
56
+ shortcut.Hotkey = HOTKEYF_ALT | HOTKEYF_CONTROL
57
+ self.assertEqual(shortcut.Hotkey, HOTKEYF_ALT | HOTKEYF_CONTROL)
58
+
59
+ def test_set_and_get_showcmd(self):
60
+ SW_SHOWMAXIMIZED = 0x03
61
+ shortcut = self._create_shortcut()
62
+ shortcut.ShowCmd = SW_SHOWMAXIMIZED
63
+ self.assertEqual(shortcut.ShowCmd, SW_SHOWMAXIMIZED)
64
+
65
+ def test_set_and_get_icon_location(self):
66
+ shortcut = self._create_shortcut()
67
+ shortcut.SetIconLocation(str(self.src_file).encode("utf-8"), 1)
68
+ icon_path, index = shortcut.GetIconLocation()
69
+ self.assertEqual(icon_path, str(self.src_file).encode("utf-8"))
70
+ self.assertEqual(index, 1)
71
+
72
+
73
+ class Test_IShellLinkW(ut.TestCase):
74
+ def setUp(self):
75
+ td = tempfile.TemporaryDirectory()
76
+ self.addCleanup(td.cleanup)
77
+ self.tmp_dir = Path(td.name)
78
+ self.src_file = (self.tmp_dir / "src.txt").resolve()
79
+ self.src_file.touch()
80
+
81
+ def _create_shortcut(self) -> shelllink.IShellLinkW:
82
+ return CoCreateInstance(CLSID_ShellLink, interface=shelllink.IShellLinkW)
83
+
84
+ def test_set_and_get_path(self):
85
+ shortcut = self._create_shortcut()
86
+ pf = shortcut.QueryInterface(IPersistFile)
87
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_FALSE)
88
+ shortcut.SetPath(str(self.src_file))
89
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_OK)
90
+ self.assertEqual(
91
+ shortcut.GetPath(shelllink.SLGP_UNCPRIORITY),
92
+ str(self.src_file),
93
+ )
94
+ lnk_file = (self.tmp_dir / "new.lnk").resolve()
95
+ self.assertFalse(lnk_file.exists())
96
+ pf.Save(str(lnk_file), True)
97
+ self.assertTrue(lnk_file.exists())
98
+ self.assertEqual(pf.GetCurFile(), str(lnk_file))
99
+
100
+ def test_set_and_get_description(self):
101
+ shortcut = self._create_shortcut()
102
+ shortcut.SetDescription("sample")
103
+ self.assertEqual(shortcut.GetDescription(), "sample")
104
+
105
+ def test_set_and_get_working_directory(self):
106
+ shortcut = self._create_shortcut()
107
+ shortcut.SetWorkingDirectory(str(self.tmp_dir))
108
+ self.assertEqual(shortcut.GetWorkingDirectory(), str(self.tmp_dir))
109
+
110
+ def test_set_and_get_arguments(self):
111
+ shortcut = self._create_shortcut()
112
+ shortcut.SetArguments("-f")
113
+ self.assertEqual(shortcut.GetArguments(), "-f")
114
+
115
+ def test_set_and_get_hotkey(self):
116
+ HOTKEYF_ALT = 0x04
117
+ HOTKEYF_CONTROL = 0x02
118
+ shortcut = self._create_shortcut()
119
+ shortcut.Hotkey = HOTKEYF_ALT | HOTKEYF_CONTROL
120
+ self.assertEqual(shortcut.Hotkey, HOTKEYF_ALT | HOTKEYF_CONTROL)
121
+
122
+ def test_set_and_get_showcmd(self):
123
+ SW_SHOWMAXIMIZED = 0x03
124
+ shortcut = self._create_shortcut()
125
+ shortcut.ShowCmd = SW_SHOWMAXIMIZED
126
+ self.assertEqual(shortcut.ShowCmd, SW_SHOWMAXIMIZED)
127
+
128
+ def test_set_and_get_icon_location(self):
129
+ shortcut = self._create_shortcut()
130
+ shortcut.SetIconLocation(str(self.src_file), 1)
131
+ icon_path, index = shortcut.GetIconLocation()
132
+ self.assertEqual(icon_path, str(self.src_file))
133
+ self.assertEqual(index, 1)
@@ -0,0 +1,127 @@
1
+ from _ctypes import COMError
2
+ from ctypes import byref, c_ubyte, POINTER
3
+ import contextlib
4
+ from pathlib import Path
5
+ import unittest
6
+
7
+ import comtypes
8
+ import comtypes.client
9
+
10
+
11
+ with contextlib.redirect_stdout(None): # supress warnings
12
+ mod = comtypes.client.GetModule("msvidctl.dll")
13
+
14
+ from comtypes.gen.MSVidCtlLib import IStorage
15
+
16
+
17
+ STATFLAG_DEFAULT = 0
18
+ STGC_DEFAULT = 0
19
+ STGM_CREATE = 0x00001000
20
+ STGM_DIRECT = 0x00000000
21
+ STGM_DELETEONRELEASE = 0x04000000
22
+ STGM_READ = 0x00000000
23
+ STGM_READWRITE = 0x00000002
24
+ STGM_SHARE_EXCLUSIVE = 0x00000010
25
+ STGM_TRANSACTED = 0x00010000
26
+ STGMOVE_MOVE = 0
27
+ STREAM_SEEK_SET = 0
28
+
29
+ STG_E_PATHNOTFOUND = -2147287038
30
+
31
+
32
+ class Test_IStorage(unittest.TestCase):
33
+ CREATE_DOC_FLAG = (
34
+ STGM_DIRECT
35
+ | STGM_READWRITE
36
+ | STGM_CREATE
37
+ | STGM_SHARE_EXCLUSIVE
38
+ | STGM_DELETEONRELEASE
39
+ )
40
+ CREATE_STM_FLAG = STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE
41
+ OPEN_STM_FLAG = STGM_READ | STGM_SHARE_EXCLUSIVE
42
+ CREATE_STG_FLAG = STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE
43
+ OPEN_STG_FLAG = STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE
44
+
45
+ def _create_docfile(self) -> IStorage:
46
+ stg = POINTER(IStorage)()
47
+ comtypes._ole32.StgCreateDocfile(None, self.CREATE_DOC_FLAG, 0, byref(stg))
48
+ return stg # type: ignore
49
+
50
+ def test_CreateStream(self):
51
+ storage = self._create_docfile()
52
+ filepath = Path(storage.Stat(STATFLAG_DEFAULT).pwcsName)
53
+ self.assertTrue(filepath.exists())
54
+ stream = storage.CreateStream("example", self.CREATE_STM_FLAG, 0, 0)
55
+ test_data = "Some data".encode("utf-8")
56
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
57
+ stream.RemoteWrite(pv, len(test_data))
58
+ stream.Commit(STGC_DEFAULT)
59
+ stream.RemoteSeek(0, STREAM_SEEK_SET)
60
+ read_buffer, data_read = stream.RemoteRead(1024)
61
+ self.assertEqual(bytearray(read_buffer)[0:data_read], test_data)
62
+ storage.Commit(STGC_DEFAULT)
63
+ self.assertTrue(filepath.exists())
64
+ del storage
65
+ self.assertFalse(filepath.exists())
66
+
67
+ def test_CreateStorage(self):
68
+ parent = self._create_docfile()
69
+ child = parent.CreateStorage("child", self.CREATE_STG_FLAG, 0, 0)
70
+ self.assertEqual("child", child.Stat(STATFLAG_DEFAULT).pwcsName)
71
+
72
+ def test_OpenStorage(self):
73
+ parent = self._create_docfile()
74
+ created_child = parent.CreateStorage("child", self.CREATE_STG_FLAG, 0, 0)
75
+ del created_child
76
+ opened_child = parent.OpenStorage("child", None, self.OPEN_STG_FLAG, None, 0)
77
+ self.assertEqual("child", opened_child.Stat(STATFLAG_DEFAULT).pwcsName)
78
+
79
+ def test_RemoteCopyTo(self):
80
+ src_stg = self._create_docfile()
81
+ src_stg.CreateStorage("child", self.CREATE_STG_FLAG, 0, 0)
82
+ dst_stg = self._create_docfile()
83
+ src_stg.RemoteCopyTo(0, None, None, dst_stg)
84
+ src_stg.Commit(STGC_DEFAULT)
85
+ del src_stg
86
+ opened_stg = dst_stg.OpenStorage("child", None, self.OPEN_STG_FLAG, None, 0)
87
+ self.assertEqual("child", opened_stg.Stat(STATFLAG_DEFAULT).pwcsName)
88
+
89
+ def test_MoveElementTo(self):
90
+ src_stg = self._create_docfile()
91
+ src_stg.CreateStorage("foo", self.CREATE_STG_FLAG, 0, 0)
92
+ dst_stg = self._create_docfile()
93
+ src_stg.MoveElementTo("foo", dst_stg, "bar", STGMOVE_MOVE)
94
+ opened_stg = dst_stg.OpenStorage("bar", None, self.OPEN_STG_FLAG, None, 0)
95
+ self.assertEqual("bar", opened_stg.Stat(STATFLAG_DEFAULT).pwcsName)
96
+ with self.assertRaises(COMError) as ctx:
97
+ src_stg.OpenStorage("foo", None, self.OPEN_STG_FLAG, None, 0)
98
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
99
+
100
+ def test_Revert(self):
101
+ storage = self._create_docfile()
102
+ foo = storage.CreateStorage("foo", self.CREATE_STG_FLAG, 0, 0)
103
+ foo.CreateStorage("bar", self.CREATE_STG_FLAG, 0, 0)
104
+ bar = foo.OpenStorage("bar", None, self.OPEN_STG_FLAG, None, 0)
105
+ self.assertEqual("bar", bar.Stat(STATFLAG_DEFAULT).pwcsName)
106
+ foo.Revert()
107
+ with self.assertRaises(COMError) as ctx:
108
+ foo.OpenStorage("bar", None, self.OPEN_STG_FLAG, None, 0)
109
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
110
+
111
+ def test_DestroyElement(self):
112
+ storage = self._create_docfile()
113
+ storage.CreateStorage("example", self.CREATE_STG_FLAG, 0, 0)
114
+ storage.DestroyElement("example")
115
+ with self.assertRaises(COMError) as ctx:
116
+ storage.OpenStorage("example", None, self.OPEN_STG_FLAG, None, 0)
117
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
118
+
119
+ def test_RenameElement(self):
120
+ storage = self._create_docfile()
121
+ storage.CreateStorage("example", self.CREATE_STG_FLAG, 0, 0)
122
+ storage.RenameElement("example", "sample")
123
+ sample = storage.OpenStorage("sample", None, self.OPEN_STG_FLAG, None, 0)
124
+ self.assertEqual("sample", sample.Stat(STATFLAG_DEFAULT).pwcsName)
125
+ with self.assertRaises(COMError) as ctx:
126
+ storage.OpenStorage("example", None, self.OPEN_STG_FLAG, None, 0)
127
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
@@ -3,7 +3,6 @@
3
3
  # generated by 'xml2py'
4
4
  # flags '..\tools\windows.xml -m comtypes -m comtypes.automation -w -r .*TypeLibEx -r .*TypeLib -o typeinfo.py'
5
5
  # then hacked manually
6
- import os
7
6
  import sys
8
7
  from typing import Any, overload, TypeVar, TYPE_CHECKING
9
8
  from typing import List, Type, Tuple
@@ -14,7 +13,7 @@ import weakref
14
13
  import ctypes
15
14
  from ctypes import HRESULT, POINTER, _Pointer, byref, c_int, c_void_p, c_wchar_p
16
15
  from ctypes.wintypes import DWORD, LONG, UINT, ULONG, WCHAR, WORD
17
- from comtypes import BSTR, _CData, COMMETHOD, _GUID, GUID, IID, IUnknown, STDMETHOD
16
+ from comtypes import BSTR, _CData, COMMETHOD, GUID, IID, IUnknown, STDMETHOD
18
17
  from comtypes.automation import DISPID, LCID, SCODE
19
18
  from comtypes.automation import DISPPARAMS, EXCEPINFO, VARIANT, VARIANTARG, VARTYPE
20
19
 
@@ -219,7 +218,9 @@ class ITypeLib(IUnknown):
219
218
  """Return an ITypeComp pointer."""
220
219
  ...
221
220
 
222
- def GetDocumentation(self, index: int) -> Tuple[str, str, int, Optional[str]]:
221
+ def GetDocumentation(
222
+ self, index: int
223
+ ) -> Tuple[str, Optional[str], int, Optional[str]]:
223
224
  """Return documentation for a type description."""
224
225
  ...
225
226
 
@@ -227,11 +228,11 @@ class ITypeLib(IUnknown):
227
228
  """Release TLIBATTR"""
228
229
  ...
229
230
 
230
- _GetLibAttr: Callable[[], "_Pointer[TLIBATTR]"]
231
-
232
231
  def GetLibAttr(self) -> "TLIBATTR":
233
232
  """Return type library attributes"""
234
- return _deref_with_release(self._GetLibAttr(), self.ReleaseTLibAttr)
233
+ return _deref_with_release(
234
+ self._GetLibAttr(), self.ReleaseTLibAttr # type: ignore
235
+ )
235
236
 
236
237
  def IsName(self, name: str, lHashVal: int = 0) -> Optional[str]:
237
238
  """Check if there is type information for this name.
@@ -341,27 +342,30 @@ class ITypeInfo(IUnknown):
341
342
  """Releases a VARDESC previously returned by VarDesc"""
342
343
  ...
343
344
 
344
- _GetTypeAttr: Callable[[], "_Pointer[TYPEATTR]"]
345
- _GetFuncDesc: Callable[[int], "_Pointer[FUNCDESC]"]
346
- _GetVarDesc: Callable[[int], "_Pointer[VARDESC]"]
347
- _GetDocumentation: Callable[[int], Tuple[str, str, int, Optional[str]]]
348
-
349
- def GetTypeAttr(self):
345
+ def GetTypeAttr(self) -> "TYPEATTR":
350
346
  """Return the TYPEATTR for this type"""
351
- return _deref_with_release(self._GetTypeAttr(), self.ReleaseTypeAttr)
347
+ return _deref_with_release(
348
+ self._GetTypeAttr(), self.ReleaseTypeAttr # type: ignore
349
+ )
352
350
 
353
- def GetDocumentation(self, memid):
351
+ def GetDocumentation(
352
+ self, memid: int
353
+ ) -> Tuple[str, Optional[str], int, Optional[str]]:
354
354
  """Return name, docstring, helpcontext, and helpfile for 'memid'."""
355
- name, doc, helpcontext, helpfile = self._GetDocumentation(memid)
356
- return fix_name(name), fix_name(doc), helpcontext, fix_name(helpfile)
355
+ name, doc, helpctx, helpfile = self._GetDocumentation(memid) # type: ignore
356
+ return fix_name(name), fix_name(doc), helpctx, fix_name(helpfile)
357
357
 
358
- def GetFuncDesc(self, index):
358
+ def GetFuncDesc(self, index: int) -> "FUNCDESC":
359
359
  """Return FUNCDESC for index"""
360
- return _deref_with_release(self._GetFuncDesc(index), self.ReleaseFuncDesc)
360
+ return _deref_with_release(
361
+ self._GetFuncDesc(index), self.ReleaseFuncDesc # type: ignore
362
+ )
361
363
 
362
- def GetVarDesc(self, index):
364
+ def GetVarDesc(self, index: int) -> "VARDESC":
363
365
  """Return VARDESC for index"""
364
- return _deref_with_release(self._GetVarDesc(index), self.ReleaseVarDesc)
366
+ return _deref_with_release(
367
+ self._GetVarDesc(index), self.ReleaseVarDesc # type: ignore
368
+ )
365
369
 
366
370
  def GetNames(self, memid: int, count: int = 1) -> List[str]:
367
371
  """Return names for memid"""
@@ -455,13 +459,12 @@ class ICreateTypeLib2(ICreateTypeLib):
455
459
  class ICreateTypeInfo(IUnknown):
456
460
  _iid_ = GUID("{00020405-0000-0000-C000-000000000046}")
457
461
  # C:/Programme/gccxml/bin/Vc71/PlatformSDK/oaidl.h 915
458
- _SetFuncAndParamNames: Callable[[int, "ctypes.Array[c_wchar_p]", int], int]
459
462
 
460
463
  def SetFuncAndParamNames(self, index: int, *names: str) -> int:
461
464
  rgszNames = (c_wchar_p * len(names))()
462
465
  for i, n in enumerate(names):
463
466
  rgszNames[i] = n
464
- return self._SetFuncAndParamNames(index, rgszNames, len(names))
467
+ return self._SetFuncAndParamNames(index, rgszNames, len(names)) # type: ignore
465
468
 
466
469
 
467
470
  class IRecordInfo(IUnknown):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: comtypes
3
- Version: 1.4.6
3
+ Version: 1.4.7
4
4
  Summary: Pure Python COM package
5
5
  Home-page: https://github.com/enthought/comtypes
6
6
  Download-URL: https://github.com/enthought/comtypes/releases
@@ -13,7 +13,7 @@ Classifier: Operating System :: Microsoft :: Windows
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
- Requires-Python: >=3.7
16
+ Requires-Python: >=3.8
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE.txt
19
19
 
@@ -24,47 +24,40 @@ License-File: LICENSE.txt
24
24
  [![GitHub Repo stars](https://img.shields.io/github/stars/enthought/comtypes?style=social)](https://github.com/enthought/comtypes/stargazers) [![GitHub forks](https://img.shields.io/github/forks/enthought/comtypes?style=social)](https://github.com/enthought/comtypes/network/members)
25
25
  [![Tidelift Subscription](https://tidelift.com/badges/package/pypi/comtypes)](https://tidelift.com/subscription/pkg/pypi-comtypes?utm_source=pypi-comtypes&utm_medium=readme)
26
26
 
27
- ## About
28
27
 
29
- `comtypes` is a lightweight `Python` [COM](https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal) package, based on the [`ctypes`](https://docs.python.org/library/ctypes.html) FFI library.
28
+ `comtypes` is a lightweight pure Python [COM](https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal) package based on the [`ctypes`](https://docs.python.org/library/ctypes.html) foreign function interface library.
30
29
 
31
- `comtypes` allows to define, call, and implement custom and dispatch-based COM interfaces in pure `Python`.
30
+ `comtypes` allows you to define, call, and implement custom and dispatch-based COM interfaces in pure Python.
32
31
 
33
- This package works on Windows only.
32
+ `comtypes` requires Windows and Python 3.8 or later.
33
+ - Version [1.4.6](https://pypi.org/project/comtypes/1.4.6/) is the last version to support Python 3.7.
34
+ - Version [1.2.1](https://pypi.org/project/comtypes/1.2.1/) is the last version to support Python 2.7 and 3.3–3.6.
35
+ - `comtypes` does not work with Python 3.8.1 as reported in [GH-202](https://github.com/enthought/comtypes/issues/202). This bug has been fixed in Python >= 3.8.2.
36
+ - Certain `comtypes` functions may not work correctly in Python 3.8 and 3.9 as reported in [GH-212](https://github.com/enthought/comtypes/issues/212). This bug has been fixed in Python >= 3.10.10 and >= 3.11.2.
34
37
 
35
- Available on `Python` 3.7-3.12.
36
- - [`comtypes==1.2.1`](https://pypi.org/project/comtypes/1.2.1/) is the last version supporting `Python` 2.7 and 3.3-3.6.
37
- - In `Python` 3.7.6 and 3.8.1, `comtypes` would not work as reported in [GH-202](https://github.com/enthought/comtypes/issues/202).
38
- This bug has been fixed in `Python` >= 3.7.7 and >= 3.8.2.
39
- - In `Python` 3.8 and 3.9, some of `comtypes` functionalities may not work correctly as reported in [GH-212](https://github.com/enthought/comtypes/issues/212).
40
- This bug has been fixed in `Python` >= 3.10.10 and >= 3.11.2.
41
-
42
- ## Where to get it
43
-
44
- The source code is currently hosted on GitHub at:
45
- https://github.com/enthought/comtypes
46
-
47
- An installer for the latest released version is available at the [Python Package Index (PyPI)](https://pypi.org/project/comtypes).
38
+ ## Installation
48
39
 
40
+ `comtypes` is available on [PyPI](https://pypi.org/project/comtypes) and can be installed with `pip`:
49
41
  ```sh
50
42
  # PyPI
51
43
  pip install comtypes
52
44
  ```
53
45
 
54
- ## Dependencies
46
+ The source code is currently hosted [here](https://github.com/enthought/comtypes) on GitHub.
47
+
48
+ ### Dependencies
55
49
 
56
- `comtypes` requires no third-party packages to run - this is truly **pure** `Python` package.
50
+ `comtypes` is a pure Python package — it has no additional required dependencies.
57
51
 
58
- Optional features include the follows...
59
- - to process arrays as `numpy`'s `ndarray`
60
- - type hints be interpreted by `mypy` or several static type checkers
52
+ Optional functionalities can be enabled by installing:
53
+ - `numpy`, in order to process arrays as `numpy`'s `ndarray`.
54
+ - `mypy` or other static type checkers, in order to interpret type hints.
61
55
 
62
- But these third-parties are not required as a prerequisite for runtime.
56
+ None of these packages, however, are required in order to run `comtypes`.
63
57
 
64
- ## Community of the developers
58
+ ## Community
65
59
 
66
- Tracking issues, reporting bugs and contributing to the codebase and documentation are on GitHub at:
67
- https://github.com/enthought/comtypes
60
+ The [GitHub repository](https://github.com/enthought/comtypes) is used for tracking issues, reporting bugs, and contributing to the codebase and documentation.
68
61
 
69
62
  ## For Enterprise
70
63
 
@@ -77,17 +70,17 @@ This project and the maintainers of thousands of other packages are working with
77
70
  ## Frequently Asked Questions
78
71
 
79
72
  ### Q: Why does this package not support platforms other than Windows?
80
- **A:** [The Microsoft Component Object Model (COM)](https://learn.microsoft.com/en-us/windows/win32/com/com-technical-overview) is a technology that is unique to Windows and is not supported on other platforms.
73
+ **A:** The [Microsoft Component Object Model (COM)](https://learn.microsoft.com/en-us/windows/win32/com/com-technical-overview) is a technology that is unique to Windows and is not supported on other platforms.
81
74
 
82
75
  [The phrase _"COM is a platform-independent"_ in the MS documentation](https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal) means that COM maintains compatibility across different versions of Windows, and does NOT imply that it is supported on Linux or Mac.
83
76
 
84
- As long as COM is not supported outside of Windows, this project does not plan to port to other platforms.
77
+ For as long as COM is not supported outside of Windows, there is no plan to port `comtypes` to other platforms.
85
78
 
86
79
  ### Q: Why does `cannot import name 'COMError' from '_ctypes'` error occur when using this package on platforms other than Windows?
87
- **A:** The [`_ctypes`](https://github.com/python/cpython/blob/main/Modules/_ctypes/_ctypes.c) is part of the internal implementation of the [`ctypes`](https://github.com/python/cpython/blob/main/Lib/ctypes/) standard library that exists for Python on all platforms.
88
- However, `COMError` and COM-related features are implemented only in Python for Windows.
80
+ **A:** The [`_ctypes`](https://github.com/python/cpython/blob/main/Modules/_ctypes/_ctypes.c) is part of the internal implementation of the [`ctypes`](https://github.com/python/cpython/blob/main/Lib/ctypes/) standard library that exists for Python on all platforms.
81
+ However, `COMError` and COM-related features are only implemented in Python for Windows.
89
82
 
90
- In cross-platform software development, care must be taken to ensure that codebase dependent on `comtypes` does not execute in environments other than Windows.
83
+ In cross-platform software development, care must be taken to ensure that codebases that depend on `comtypes` do not execute in environments other than Windows.
91
84
 
92
85
  ### Q: Despite a script that depends on `comtypes` having run successfully before, a error (`ImportError`, `NameError`, or `SyntaxError`) is raised now, and the same error occurs again and again.
93
86
 
@@ -102,7 +95,6 @@ After deleting these partial modules and running the script again, `comtypes.cli
102
95
 
103
96
  However, if the script implementation does not use `comtypes.client.GetModule` or processes generated files, it may not be a solution.
104
97
 
105
- ## Documentation:
98
+ ## Documentation
106
99
 
107
- The documentation is currently hosted on pythonhosted at:
108
- https://pythonhosted.org/comtypes
100
+ The documentation is currently hosted [here](https://pythonhosted.org/comtypes) on PythonHosted.
@@ -95,19 +95,23 @@ comtypes/test/test_ie.py
95
95
  comtypes/test/test_ienum.py
96
96
  comtypes/test/test_imfattributes.py
97
97
  comtypes/test/test_inout_args.py
98
- comtypes/test/test_istream.py
99
98
  comtypes/test/test_jscript.js
100
99
  comtypes/test/test_midl_safearray_create.py
100
+ comtypes/test/test_monikers.py
101
101
  comtypes/test/test_msscript.py
102
102
  comtypes/test/test_npsupport.py
103
103
  comtypes/test/test_outparam.py
104
+ comtypes/test/test_persist.py
104
105
  comtypes/test/test_propputref.py
105
106
  comtypes/test/test_pump_events.py
106
107
  comtypes/test/test_recordinfo.py
107
108
  comtypes/test/test_safearray.py
108
109
  comtypes/test/test_sapi.py
109
110
  comtypes/test/test_server.py
111
+ comtypes/test/test_shelllink.py
110
112
  comtypes/test/test_showevents.py
113
+ comtypes/test/test_storage.py
114
+ comtypes/test/test_stream.py
111
115
  comtypes/test/test_subinterface.py
112
116
  comtypes/test/test_typeannotator.py
113
117
  comtypes/test/test_typeinfo.py
@@ -18,7 +18,7 @@ classifiers =
18
18
  Topic :: Software Development :: Libraries :: Python Modules
19
19
 
20
20
  [options]
21
- python_requires = >=3.7
21
+ python_requires = >=3.8
22
22
  packages =
23
23
  comtypes
24
24
  comtypes._post_coinit
File without changes
File without changes
File without changes
File without changes