comtypes 1.4.8__zip → 1.4.9__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 (146) hide show
  1. {comtypes-1.4.8 → comtypes-1.4.9}/CHANGES.txt +21 -0
  2. {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.9}/PKG-INFO +2 -2
  3. {comtypes-1.4.8 → comtypes-1.4.9}/README.md +1 -1
  4. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/GUID.py +6 -5
  5. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/__init__.py +16 -5
  6. comtypes-1.4.9/comtypes/_comobject.py +507 -0
  7. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_memberspec.py +80 -8
  8. comtypes-1.4.9/comtypes/_post_coinit/_cominterface_meta_patcher.py +153 -0
  9. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/misc.py +1 -1
  10. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/unknwn.py +25 -171
  11. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_safearray.py +1 -2
  12. comtypes-1.4.9/comtypes/_vtbl.py +448 -0
  13. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/automation.py +36 -45
  14. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_code_cache.py +4 -4
  15. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_constants.py +1 -1
  16. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_events.py +1 -1
  17. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_generate.py +4 -8
  18. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/lazybind.py +2 -2
  19. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/errorinfo.py +3 -3
  20. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/git.py +1 -2
  21. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hints.pyi +7 -15
  22. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/safearray.py +10 -0
  23. comtypes-1.4.9/comtypes/server/__init__.py +86 -0
  24. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/inprocserver.py +22 -17
  25. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/localserver.py +28 -16
  26. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/register.py +61 -73
  27. comtypes-1.4.9/comtypes/server/w_getopt.py +48 -0
  28. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/shelllink.py +3 -26
  29. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/__init__.py +9 -11
  30. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_BSTR.py +4 -7
  31. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_avmc.py +1 -1
  32. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_casesensitivity.py +3 -5
  33. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_collections.py +3 -3
  34. comtypes-1.4.9/comtypes/test/test_comobject.py +146 -0
  35. comtypes-1.4.9/comtypes/test/test_comserver.py +319 -0
  36. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_createwrappers.py +2 -4
  37. comtypes-1.4.9/comtypes/test/test_dispinterface.py +153 -0
  38. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_excel.py +22 -12
  39. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ie.py +2 -5
  40. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_inout_args.py +7 -4
  41. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_midl_safearray_create.py +9 -1
  42. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_outparam.py +17 -10
  43. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_safearray.py +1 -90
  44. comtypes-1.4.9/comtypes/test/test_server.py +350 -0
  45. comtypes-1.4.9/comtypes/test/test_server_register.py +536 -0
  46. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_showevents.py +7 -17
  47. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_variant.py +0 -17
  48. comtypes-1.4.9/comtypes/test/test_w_getopt.py +29 -0
  49. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_win32com_interop.py +80 -36
  50. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_wmi.py +0 -3
  51. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/codegenerator.py +62 -68
  52. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/helpers.py +8 -8
  53. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/packing.py +4 -4
  54. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/typeannotator.py +7 -7
  55. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc.py +1 -6
  56. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/typeinfo.py +11 -22
  57. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/viewobject.py +1 -5
  58. {comtypes-1.4.8 → comtypes-1.4.9/comtypes.egg-info}/PKG-INFO +2 -2
  59. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/SOURCES.txt +6 -3
  60. {comtypes-1.4.8 → comtypes-1.4.9}/pyproject.toml +1 -0
  61. comtypes-1.4.8/comtypes/_comobject.py +0 -833
  62. comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
  63. comtypes-1.4.8/comtypes/server/__init__.py +0 -70
  64. comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
  65. comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
  66. comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
  67. comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
  68. comtypes-1.4.8/comtypes/test/test_server.py +0 -354
  69. {comtypes-1.4.8 → comtypes-1.4.9}/LICENSE.txt +0 -0
  70. {comtypes-1.4.8 → comtypes-1.4.9}/MANIFEST.in +0 -0
  71. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_meta.py +0 -0
  72. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_npsupport.py +0 -0
  73. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/__init__.py +0 -0
  74. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/bstr.py +0 -0
  75. /comtypes-1.4.8/comtypes/_py_instance_method.py → /comtypes-1.4.9/comtypes/_post_coinit/instancemethod.py +0 -0
  76. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_tlib_version_checker.py +0 -0
  77. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/clear_cache.py +0 -0
  78. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/__init__.py +0 -0
  79. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/dynamic.py +0 -0
  80. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/connectionpoints.py +0 -0
  81. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hresult.py +0 -0
  82. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/logutil.py +0 -0
  83. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/messageloop.py +0 -0
  84. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/patcher.py +0 -0
  85. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/persist.py +0 -0
  86. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/automation.py +0 -0
  87. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/connectionpoints.py +0 -0
  88. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/stream.py +0 -0
  89. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.idl +0 -0
  90. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.py +0 -0
  91. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.tlb +0 -0
  92. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.idl +0 -0
  93. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.py +0 -0
  94. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.tlb +0 -0
  95. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/find_memleak.py +0 -0
  96. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.idl +0 -0
  97. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.tlb +0 -0
  98. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mytypelib.idl +0 -0
  99. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/runtests.py +0 -0
  100. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/setup.py +0 -0
  101. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_DISPPARAMS.py +0 -0
  102. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_GUID.py +0 -0
  103. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_QueryService.py +0 -0
  104. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_agilent.py +0 -0
  105. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_basic.py +0 -0
  106. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_clear_cache.py +0 -0
  107. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client.py +0 -0
  108. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_dynamic.py +0 -0
  109. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_regenerate_modules.py +0 -0
  110. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dict.py +0 -0
  111. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_records.py +0 -0
  112. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_safearrays.py +0 -0
  113. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dyndispatch.py +0 -0
  114. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_findgendir.py +0 -0
  115. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_getactiveobj.py +0 -0
  116. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ienum.py +0 -0
  117. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_imfattributes.py +0 -0
  118. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_jscript.js +0 -0
  119. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_monikers.py +0 -0
  120. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_msscript.py +0 -0
  121. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_npsupport.py +0 -0
  122. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_persist.py +0 -0
  123. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_pump_events.py +0 -0
  124. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_recordinfo.py +0 -0
  125. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_sapi.py +0 -0
  126. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_shelllink.py +0 -0
  127. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_storage.py +0 -0
  128. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_stream.py +0 -0
  129. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_subinterface.py +0 -0
  130. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeannotator.py +0 -0
  131. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeinfo.py +0 -0
  132. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_urlhistory.py +0 -0
  133. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_word.py +0 -0
  134. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/urlhist.tlb +0 -0
  135. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/__init__.py +0 -0
  136. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/__init__.py +0 -0
  137. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  138. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/namespaces.py +0 -0
  139. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/tlbparser.py +0 -0
  140. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc_base.py +0 -0
  141. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/util.py +0 -0
  142. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/dependency_links.txt +0 -0
  143. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/entry_points.txt +0 -0
  144. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/top_level.txt +0 -0
  145. {comtypes-1.4.8 → comtypes-1.4.9}/setup.cfg +0 -0
  146. {comtypes-1.4.8 → comtypes-1.4.9}/setup.py +0 -0
@@ -0,0 +1,536 @@
1
+ import _ctypes
2
+ import ctypes
3
+ import os
4
+ import sys
5
+ import unittest as ut
6
+ import winreg
7
+ from unittest import mock
8
+
9
+ import comtypes
10
+ import comtypes.server.inprocserver
11
+ from comtypes import GUID
12
+ from comtypes.server import register
13
+ from comtypes.server.register import Registrar, RegistryEntries, _get_serverdll
14
+
15
+ HKCR = winreg.HKEY_CLASSES_ROOT
16
+ MULTI_SZ = winreg.REG_MULTI_SZ
17
+ SZ = winreg.REG_SZ
18
+
19
+
20
+ class Test_Registrar_nodebug(ut.TestCase):
21
+ @mock.patch.object(register, "winreg")
22
+ def test_calls_openkey_and_deletekey(self, _winreg):
23
+ _winreg.HKEY_CLASSES_ROOT = HKCR
24
+ hkey = mock.Mock(spec=winreg.HKEYType)
25
+ _winreg.OpenKey.return_value = hkey
26
+ reg_clsid = GUID.create_new()
27
+ registrar = Registrar()
28
+
29
+ class Cls:
30
+ _reg_clsid_ = reg_clsid
31
+
32
+ registrar.nodebug(Cls)
33
+ _winreg.OpenKey.assert_called_once_with(HKCR, rf"CLSID\{reg_clsid}")
34
+ _winreg.DeleteKey.assert_called_once_with(hkey, "Logging")
35
+
36
+ @mock.patch.object(register, "winreg")
37
+ def test_ignores_winerror(self, _winreg):
38
+ _winreg.HKEY_CLASSES_ROOT = HKCR
39
+ ERROR_FILE_NOT_FOUND = 2
40
+ err = OSError(ERROR_FILE_NOT_FOUND, "msg", "filename", ERROR_FILE_NOT_FOUND)
41
+ _winreg.OpenKey.side_effect = err
42
+ reg_clsid = GUID.create_new()
43
+ registrar = Registrar()
44
+
45
+ class Cls:
46
+ _reg_clsid_ = reg_clsid
47
+
48
+ registrar.nodebug(Cls)
49
+ _winreg.OpenKey.assert_called_once_with(HKCR, rf"CLSID\{reg_clsid}")
50
+ _winreg.DeleteKey.assert_not_called()
51
+
52
+ @mock.patch.object(register, "winreg")
53
+ def test_not_ignores_winerror(self, _winreg):
54
+ _winreg.HKEY_CLASSES_ROOT = HKCR
55
+ hkey = mock.Mock(spec=winreg.HKEYType)
56
+ _winreg.OpenKey.return_value = hkey
57
+ ERROR_ACCESS_DENIED = 5
58
+ err = OSError(ERROR_ACCESS_DENIED, "msg", "filename", ERROR_ACCESS_DENIED)
59
+ _winreg.OpenKey.return_value = hkey
60
+ _winreg.DeleteKey.side_effect = err
61
+ reg_clsid = GUID.create_new()
62
+ registrar = Registrar()
63
+
64
+ class Cls:
65
+ _reg_clsid_ = reg_clsid
66
+
67
+ with self.assertRaises(OSError) as e:
68
+ registrar.nodebug(Cls)
69
+ self.assertEqual(e.exception.winerror, ERROR_ACCESS_DENIED)
70
+ _winreg.OpenKey.assert_called_once_with(HKCR, rf"CLSID\{reg_clsid}")
71
+ _winreg.DeleteKey.assert_called_once_with(hkey, "Logging")
72
+
73
+
74
+ class Test_Registrar_debug(ut.TestCase):
75
+ @mock.patch.object(register, "winreg")
76
+ def test_calls_createkey_and_sets_format(self, _winreg):
77
+ _winreg.HKEY_CLASSES_ROOT = HKCR
78
+ _winreg.REG_MULTI_SZ = MULTI_SZ
79
+ _winreg.REG_SZ = SZ
80
+ hkey = mock.Mock(spec=winreg.HKEYType)
81
+ _winreg.CreateKey.return_value = hkey
82
+ levels = ["lv=DEBUG"]
83
+ format = "FMT"
84
+ reg_clsid = GUID.create_new()
85
+ registrar = Registrar()
86
+
87
+ class Cls:
88
+ _reg_clsid_ = reg_clsid
89
+
90
+ registrar.debug(Cls, levels, format)
91
+ _winreg.CreateKey.assert_called_once_with(HKCR, rf"CLSID\{reg_clsid}\Logging")
92
+ self.assertEqual(
93
+ _winreg.SetValueEx.call_args_list,
94
+ [
95
+ mock.call(hkey, "levels", None, MULTI_SZ, levels),
96
+ mock.call(hkey, "format", None, SZ, format),
97
+ ],
98
+ )
99
+
100
+ @mock.patch.object(register, "winreg")
101
+ def test_calls_createkey_and_deletes_format(self, _winreg):
102
+ _winreg.HKEY_CLASSES_ROOT = HKCR
103
+ _winreg.REG_MULTI_SZ = MULTI_SZ
104
+ hkey = mock.Mock(spec=winreg.HKEYType)
105
+ _winreg.CreateKey.return_value = hkey
106
+ levels = ["lv=DEBUG"]
107
+ reg_clsid = GUID.create_new()
108
+ registrar = Registrar()
109
+
110
+ class Cls:
111
+ _reg_clsid_ = reg_clsid
112
+
113
+ registrar.debug(Cls, levels, None)
114
+ _winreg.CreateKey.assert_called_once_with(HKCR, rf"CLSID\{reg_clsid}\Logging")
115
+ _winreg.SetValueEx.assert_called_once_with(
116
+ hkey, "levels", None, MULTI_SZ, levels
117
+ )
118
+ _winreg.DeleteValue.assert_called_once_with(hkey, "format")
119
+
120
+ @mock.patch.object(register, "winreg")
121
+ def test_calls_createkey_and_ignores_errors_on_deleting(self, _winreg):
122
+ _winreg.HKEY_CLASSES_ROOT = HKCR
123
+ _winreg.REG_MULTI_SZ = MULTI_SZ
124
+ hkey = mock.Mock(spec=winreg.HKEYType)
125
+ _winreg.CreateKey.return_value = hkey
126
+ ERROR_FILE_NOT_FOUND = 2
127
+ err = OSError(ERROR_FILE_NOT_FOUND, "msg", "filename", ERROR_FILE_NOT_FOUND)
128
+ _winreg.DeleteValue.side_effect = err
129
+ levels = ["lv=DEBUG"]
130
+ reg_clsid = GUID.create_new()
131
+ registrar = Registrar()
132
+
133
+ class Cls:
134
+ _reg_clsid_ = reg_clsid
135
+
136
+ registrar.debug(Cls, levels, None)
137
+ _winreg.CreateKey.assert_called_once_with(HKCR, rf"CLSID\{reg_clsid}\Logging")
138
+ _winreg.SetValueEx.assert_called_once_with(
139
+ hkey, "levels", None, MULTI_SZ, levels
140
+ )
141
+ _winreg.DeleteValue.assert_called_once_with(hkey, "format")
142
+
143
+ @mock.patch.object(register, "winreg")
144
+ def test_calls_createkey_and_not_ignores_errors_on_deleting(self, _winreg):
145
+ _winreg.HKEY_CLASSES_ROOT = HKCR
146
+ _winreg.REG_MULTI_SZ = MULTI_SZ
147
+ hkey = mock.Mock(spec=winreg.HKEYType)
148
+ _winreg.CreateKey.return_value = hkey
149
+ ERROR_ACCESS_DENIED = 5
150
+ err = OSError(ERROR_ACCESS_DENIED, "msg", "filename", ERROR_ACCESS_DENIED)
151
+ _winreg.DeleteValue.side_effect = err
152
+ levels = ["lv=DEBUG"]
153
+ reg_clsid = GUID.create_new()
154
+ registrar = Registrar()
155
+
156
+ class Cls:
157
+ _reg_clsid_ = reg_clsid
158
+
159
+ with self.assertRaises(OSError) as e:
160
+ registrar.debug(Cls, levels, None)
161
+ self.assertEqual(e.exception.winerror, ERROR_ACCESS_DENIED)
162
+ _winreg.CreateKey.assert_called_once_with(HKCR, rf"CLSID\{reg_clsid}\Logging")
163
+ _winreg.SetValueEx.assert_called_once_with(
164
+ hkey, "levels", None, MULTI_SZ, levels
165
+ )
166
+ _winreg.DeleteValue.assert_called_once_with(hkey, "format")
167
+
168
+
169
+ class Test_Registrar_register(ut.TestCase):
170
+ def test_calls_cls_register(self):
171
+ cls = mock.Mock(spec=["_register"])
172
+ registrar = Registrar()
173
+ registrar.register(cls)
174
+ cls._register.assert_called_once_with(registrar)
175
+
176
+ # The coverage for COM server registration is ensured by the setup
177
+ # of `test_comserver` and `test_dispinterface`, so no additional tests
178
+ # are performed here now.
179
+
180
+
181
+ class Test_Registrar_unregister(ut.TestCase):
182
+ def test_calls_cls_unregister(self):
183
+ cls = mock.Mock(spec=["_unregister"])
184
+ registrar = Registrar()
185
+ registrar.unregister(cls)
186
+ cls._unregister.assert_called_once_with(registrar)
187
+
188
+ # The coverage for COM server unregistration is ensured by the teardown
189
+ # of `test_comserver` and `test_dispinterface`, so no additional tests
190
+ # are performed here now.
191
+
192
+
193
+ class Test_get_serverdll(ut.TestCase):
194
+ def test_nonfrozen(self):
195
+ self.assertEqual(_ctypes.__file__, _get_serverdll())
196
+
197
+ def test_frozen(self):
198
+ with mock.patch.object(register, "sys") as _sys:
199
+ with mock.patch.object(register, "windll") as _windll:
200
+ handle = 1234
201
+ _sys.frozendllhandle = handle
202
+ self.assertEqual(b"\x00" * 260, _get_serverdll())
203
+ GetModuleFileName = _windll.kernel32.GetModuleFileNameA
204
+ (((hModule, lpFilename, nSize), _),) = GetModuleFileName.call_args_list
205
+ self.assertEqual(handle, hModule)
206
+ buf_type = type(ctypes.create_string_buffer(260))
207
+ self.assertIsInstance(lpFilename, buf_type)
208
+ self.assertEqual(260, nSize)
209
+
210
+
211
+ class Test_NonFrozen_RegistryEntries(ut.TestCase):
212
+ def test_reg_clsid(self):
213
+ reg_clsid = GUID.create_new()
214
+
215
+ class Cls:
216
+ _reg_clsid_ = reg_clsid
217
+
218
+ expected = [(HKCR, rf"CLSID\{reg_clsid}", "", "")]
219
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
220
+
221
+ def test_reg_desc(self):
222
+ reg_clsid = GUID.create_new()
223
+ reg_desc = "description for testing"
224
+
225
+ class Cls:
226
+ _reg_clsid_ = reg_clsid
227
+ _reg_desc_ = reg_desc
228
+
229
+ expected = [(HKCR, rf"CLSID\{reg_clsid}", "", reg_desc)]
230
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
231
+
232
+ def test_reg_novers_progid(self):
233
+ reg_clsid = GUID.create_new()
234
+ reg_novers_progid = "Lib.Server"
235
+
236
+ class Cls:
237
+ _reg_clsid_ = reg_clsid
238
+ _reg_novers_progid_ = reg_novers_progid
239
+
240
+ expected = [(HKCR, rf"CLSID\{reg_clsid}", "", "Lib Server")]
241
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
242
+
243
+ def test_progid(self):
244
+ reg_clsid = GUID.create_new()
245
+ reg_progid = "Lib.Server.1"
246
+
247
+ class Cls:
248
+ _reg_clsid_ = reg_clsid
249
+ _reg_progid_ = reg_progid
250
+
251
+ expected = [
252
+ (HKCR, rf"CLSID\{reg_clsid}", "", "Lib Server 1"),
253
+ (HKCR, rf"CLSID\{reg_clsid}\ProgID", "", reg_progid),
254
+ (HKCR, reg_progid, "", "Lib Server 1"),
255
+ (HKCR, rf"{reg_progid}\CLSID", "", str(reg_clsid)),
256
+ ]
257
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
258
+
259
+ def test_reg_progid_reg_desc(self):
260
+ reg_clsid = GUID.create_new()
261
+ reg_progid = "Lib.Server.1"
262
+ reg_desc = "description for testing"
263
+
264
+ class Cls:
265
+ _reg_clsid_ = reg_clsid
266
+ _reg_progid_ = reg_progid
267
+ _reg_desc_ = reg_desc
268
+
269
+ expected = [
270
+ (HKCR, rf"CLSID\{reg_clsid}", "", reg_desc),
271
+ (HKCR, rf"CLSID\{reg_clsid}\ProgID", "", reg_progid),
272
+ (HKCR, reg_progid, "", "description for testing"),
273
+ (HKCR, rf"{reg_progid}\CLSID", "", str(reg_clsid)),
274
+ ]
275
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
276
+
277
+ def test_reg_progid_reg_novers_progid(self):
278
+ reg_clsid = GUID.create_new()
279
+ reg_progid = "Lib.Server.1"
280
+ reg_novers_progid = "Lib.Server"
281
+
282
+ class Cls:
283
+ _reg_clsid_ = reg_clsid
284
+ _reg_progid_ = reg_progid
285
+ _reg_novers_progid_ = reg_novers_progid
286
+
287
+ clsid_sub = rf"CLSID\{reg_clsid}"
288
+ expected = [
289
+ (HKCR, clsid_sub, "", "Lib Server"),
290
+ (HKCR, rf"{clsid_sub}\ProgID", "", reg_progid),
291
+ (HKCR, reg_progid, "", "Lib Server"),
292
+ (HKCR, rf"{reg_progid}\CLSID", "", str(reg_clsid)),
293
+ (HKCR, rf"{clsid_sub}\VersionIndependentProgID", "", reg_novers_progid),
294
+ (HKCR, reg_novers_progid, "", "Lib Server"),
295
+ (HKCR, rf"{reg_novers_progid}\CurVer", "", "Lib.Server.1"),
296
+ (HKCR, rf"{reg_novers_progid}\CLSID", "", str(reg_clsid)),
297
+ ]
298
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
299
+
300
+ def test_local_server(self):
301
+ reg_clsid = GUID.create_new()
302
+ reg_clsctx = comtypes.CLSCTX_LOCAL_SERVER
303
+
304
+ class Cls:
305
+ _reg_clsid_ = reg_clsid
306
+ _reg_clsctx_ = reg_clsctx
307
+
308
+ clsid_sub = rf"CLSID\{reg_clsid}"
309
+ local_srv_sub = rf"{clsid_sub}\LocalServer32"
310
+ expected = [
311
+ (HKCR, clsid_sub, "", ""),
312
+ (HKCR, local_srv_sub, "", f"{sys.executable} {__file__}"),
313
+ ]
314
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
315
+
316
+ def test_inproc_server(self):
317
+ reg_clsid = GUID.create_new()
318
+ reg_clsctx = comtypes.CLSCTX_INPROC_SERVER
319
+
320
+ class Cls:
321
+ _reg_clsid_ = reg_clsid
322
+ _reg_clsctx_ = reg_clsctx
323
+
324
+ clsid_sub = rf"CLSID\{reg_clsid}"
325
+ inproc_srv_sub = rf"{clsid_sub}\InprocServer32"
326
+ full_classname = f"{__name__}.Cls"
327
+ expected = [
328
+ (HKCR, clsid_sub, "", ""),
329
+ (HKCR, inproc_srv_sub, "", _ctypes.__file__),
330
+ (HKCR, inproc_srv_sub, "PythonClass", full_classname),
331
+ (HKCR, inproc_srv_sub, "PythonPath", os.path.dirname(__file__)),
332
+ ]
333
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
334
+
335
+ def test_inproc_server_reg_threading(self):
336
+ reg_clsid = GUID.create_new()
337
+ reg_threading = "Both"
338
+ reg_clsctx = comtypes.CLSCTX_INPROC_SERVER
339
+
340
+ class Cls:
341
+ _reg_clsid_ = reg_clsid
342
+ _reg_threading_ = reg_threading
343
+ _reg_clsctx_ = reg_clsctx
344
+
345
+ clsid_sub = rf"CLSID\{reg_clsid}"
346
+ inproc_srv_sub = rf"{clsid_sub}\InprocServer32"
347
+ full_classname = f"{__name__}.Cls"
348
+ expected = [
349
+ (HKCR, clsid_sub, "", ""),
350
+ (HKCR, inproc_srv_sub, "", _ctypes.__file__),
351
+ (HKCR, inproc_srv_sub, "PythonClass", full_classname),
352
+ (HKCR, inproc_srv_sub, "PythonPath", os.path.dirname(__file__)),
353
+ (HKCR, inproc_srv_sub, "ThreadingModel", reg_threading),
354
+ ]
355
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
356
+
357
+ def test_reg_typelib(self):
358
+ reg_clsid = GUID.create_new()
359
+ libid = str(GUID.create_new())
360
+ reg_typelib = (libid, 1, 0)
361
+
362
+ class Cls:
363
+ _reg_clsid_ = reg_clsid
364
+ _reg_typelib_ = reg_typelib
365
+
366
+ expected = [
367
+ (HKCR, rf"CLSID\{reg_clsid}", "", ""),
368
+ (HKCR, rf"CLSID\{reg_clsid}\Typelib", "", libid),
369
+ ]
370
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
371
+
372
+ def test_all_entries(self):
373
+ reg_clsid = GUID.create_new()
374
+ libid = str(GUID.create_new())
375
+ reg_typelib = (libid, 1, 0)
376
+ reg_threading = "Both"
377
+ reg_progid = "Lib.Server.1"
378
+ reg_novers_progid = "Lib.Server"
379
+ reg_desc = "description for testing"
380
+ reg_clsctx = comtypes.CLSCTX_INPROC_SERVER | comtypes.CLSCTX_LOCAL_SERVER
381
+
382
+ class Cls:
383
+ _reg_clsid_ = reg_clsid
384
+ _reg_typelib_ = reg_typelib
385
+ _reg_threading_ = reg_threading
386
+ _reg_progid_ = reg_progid
387
+ _reg_novers_progid_ = reg_novers_progid
388
+ _reg_desc_ = reg_desc
389
+ _reg_clsctx_ = reg_clsctx
390
+
391
+ clsid_sub = rf"CLSID\{reg_clsid}"
392
+ inproc_srv_sub = rf"{clsid_sub}\InprocServer32"
393
+ local_srv_sub = rf"{clsid_sub}\LocalServer32"
394
+ full_classname = f"{__name__}.Cls"
395
+ expected = [
396
+ (HKCR, clsid_sub, "", reg_desc),
397
+ (HKCR, rf"{clsid_sub}\ProgID", "", reg_progid),
398
+ (HKCR, reg_progid, "", reg_desc),
399
+ (HKCR, rf"{reg_progid}\CLSID", "", str(reg_clsid)),
400
+ (HKCR, rf"{clsid_sub}\VersionIndependentProgID", "", reg_novers_progid),
401
+ (HKCR, reg_novers_progid, "", reg_desc),
402
+ (HKCR, rf"{reg_novers_progid}\CurVer", "", reg_progid),
403
+ (HKCR, rf"{reg_novers_progid}\CLSID", "", str(reg_clsid)),
404
+ (HKCR, local_srv_sub, "", f"{sys.executable} {__file__}"),
405
+ (HKCR, inproc_srv_sub, "", _ctypes.__file__),
406
+ (HKCR, inproc_srv_sub, "PythonClass", full_classname),
407
+ (HKCR, inproc_srv_sub, "PythonPath", os.path.dirname(__file__)),
408
+ (HKCR, inproc_srv_sub, "ThreadingModel", reg_threading),
409
+ (HKCR, rf"{clsid_sub}\Typelib", "", libid),
410
+ ]
411
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
412
+
413
+
414
+ class Test_Frozen_RegistryEntries(ut.TestCase):
415
+ @mock.patch.object(register, "sys")
416
+ def test_local_dll(self, _sys):
417
+ _sys.mock_add_spec(["executable", "frozen"])
418
+ _sys.executable = sys.executable
419
+ _sys.frozen = "dll"
420
+ reg_clsid = GUID.create_new()
421
+ reg_clsctx = comtypes.CLSCTX_LOCAL_SERVER
422
+
423
+ class Cls:
424
+ _reg_clsid_ = reg_clsid
425
+ _reg_clsctx_ = reg_clsctx
426
+
427
+ clsid_sub = rf"CLSID\{reg_clsid}"
428
+ expected = [
429
+ (HKCR, clsid_sub, "", ""),
430
+ (HKCR, rf"{clsid_sub}\LocalServer32", "", sys.executable),
431
+ ]
432
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
433
+
434
+ @mock.patch.object(register, "sys")
435
+ def test_local_frozendllhandle(self, _sys):
436
+ _sys.mock_add_spec(["frozen", "frozendllhandle"])
437
+ _sys.frozen = "dll"
438
+ _sys.frozendllhandle = 1234
439
+ reg_clsid = GUID.create_new()
440
+ reg_clsctx = comtypes.CLSCTX_LOCAL_SERVER
441
+
442
+ class Cls:
443
+ _reg_clsid_ = reg_clsid
444
+ _reg_clsctx_ = reg_clsctx
445
+
446
+ expected = [(HKCR, rf"CLSID\{reg_clsid}", "", "")]
447
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
448
+
449
+ @mock.patch.object(register, "sys")
450
+ def test_inproc_windows_exe(self, _sys):
451
+ _sys.mock_add_spec(["frozen"])
452
+ _sys.frozen = "windows_exe"
453
+ reg_clsid = GUID.create_new()
454
+ reg_clsctx = comtypes.CLSCTX_INPROC_SERVER
455
+
456
+ class Cls:
457
+ _reg_clsid_ = reg_clsid
458
+ _reg_clsctx_ = reg_clsctx
459
+
460
+ expected = [(HKCR, rf"CLSID\{reg_clsid}", "", "")]
461
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
462
+
463
+ @mock.patch.object(register, "_get_serverdll", lambda: r"my\target\server.dll")
464
+ @mock.patch.object(register, "sys")
465
+ def test_inproc_dll_frozendllhandle_clsid_to_class(self, _sys):
466
+ _sys.mock_add_spec(["frozen", "frozendllhandle"])
467
+ _sys.frozen = "dll"
468
+ _sys.frozendllhandle = 1234
469
+ reg_clsid = GUID.create_new()
470
+ reg_clsctx = comtypes.CLSCTX_INPROC_SERVER
471
+
472
+ class Cls:
473
+ _reg_clsid_ = reg_clsid
474
+ _reg_clsctx_ = reg_clsctx
475
+
476
+ clsid_sub = rf"CLSID\{reg_clsid}"
477
+ inproc_srv_sub = rf"{clsid_sub}\InprocServer32"
478
+ expected = [
479
+ (HKCR, clsid_sub, "", ""),
480
+ (HKCR, inproc_srv_sub, "", r"my\target\server.dll"),
481
+ ]
482
+
483
+ with mock.patch.dict(comtypes.server.inprocserver._clsid_to_class):
484
+ comtypes.server.inprocserver._clsid_to_class.update({5678: Cls})
485
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
486
+
487
+ @mock.patch.object(register, "_get_serverdll", lambda: r"my\target\server.dll")
488
+ @mock.patch.object(register, "sys")
489
+ def test_inproc_dll(self, _sys):
490
+ _sys.mock_add_spec(["frozen", "modules"])
491
+ _sys.frozen = "dll"
492
+ _sys.modules = sys.modules
493
+ reg_clsid = GUID.create_new()
494
+ reg_clsctx = comtypes.CLSCTX_INPROC_SERVER
495
+
496
+ class Cls:
497
+ _reg_clsid_ = reg_clsid
498
+ _reg_clsctx_ = reg_clsctx
499
+
500
+ clsid_sub = rf"CLSID\{reg_clsid}"
501
+ inproc_srv_sub = rf"{clsid_sub}\InprocServer32"
502
+ full_classname = f"{__name__}.Cls"
503
+ expected = [
504
+ (HKCR, clsid_sub, "", ""),
505
+ (HKCR, inproc_srv_sub, "", r"my\target\server.dll"),
506
+ (HKCR, inproc_srv_sub, "PythonClass", full_classname),
507
+ (HKCR, inproc_srv_sub, "PythonPath", os.path.dirname(__file__)),
508
+ ]
509
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
510
+
511
+ @mock.patch.object(register, "_get_serverdll", lambda: r"my\target\server.dll")
512
+ @mock.patch.object(register, "sys")
513
+ def test_inproc_dll_reg_threading(self, _sys):
514
+ _sys.mock_add_spec(["frozen", "modules"])
515
+ _sys.frozen = "dll"
516
+ _sys.modules = sys.modules
517
+ reg_clsid = GUID.create_new()
518
+ reg_threading = "Both"
519
+ reg_clsctx = comtypes.CLSCTX_INPROC_SERVER
520
+
521
+ class Cls:
522
+ _reg_clsid_ = reg_clsid
523
+ _reg_threading_ = reg_threading
524
+ _reg_clsctx_ = reg_clsctx
525
+
526
+ clsid_sub = rf"CLSID\{reg_clsid}"
527
+ inproc_srv_sub = rf"{clsid_sub}\InprocServer32"
528
+ full_classname = f"{__name__}.Cls"
529
+ expected = [
530
+ (HKCR, clsid_sub, "", ""),
531
+ (HKCR, inproc_srv_sub, "", r"my\target\server.dll"),
532
+ (HKCR, inproc_srv_sub, "PythonClass", full_classname),
533
+ (HKCR, inproc_srv_sub, "PythonPath", os.path.dirname(__file__)),
534
+ (HKCR, inproc_srv_sub, "ThreadingModel", reg_threading),
535
+ ]
536
+ self.assertEqual(expected, list(RegistryEntries(Cls)))
@@ -1,24 +1,14 @@
1
1
  import doctest
2
- import sys
3
- import re
4
2
  import unittest
3
+ from typing import Optional
5
4
 
6
5
 
7
- class SixDocChecker(doctest.OutputChecker):
8
- # see https://dirkjan.ochtman.nl/writing/2014/07/06/single-source-python-23-doctests.html
9
- def check_output(self, want, got, optionflags):
10
- if sys.version_info >= (3, 0):
11
- want = re.sub(r"u'(.*?)'", r"'\1'", want)
12
- want = re.sub(r'u"(.*?)"', r'"\1"', want)
13
- return doctest.OutputChecker.check_output(self, want, got, optionflags)
14
-
15
-
16
- def load_tests(loader, tests, ignore):
6
+ def load_tests(
7
+ loader: unittest.TestLoader, tests: unittest.TestSuite, pattern: Optional[str]
8
+ ) -> unittest.TestSuite:
17
9
  import comtypes.test.test_showevents
18
10
 
19
- tests.addTests(
20
- doctest.DocTestSuite(comtypes.test.test_showevents, checker=SixDocChecker())
21
- )
11
+ tests.addTests(doctest.DocTestSuite(comtypes.test.test_showevents))
22
12
  return tests
23
13
 
24
14
 
@@ -32,9 +22,9 @@ class ShowEventsExamples:
32
22
  >>> conn = ShowEvents(font)
33
23
  # event found: FontEvents_FontChanged
34
24
  >>> font.Name = 'Arial'
35
- Event FontEvents_FontChanged(None, u'Name')
25
+ Event FontEvents_FontChanged(None, 'Name')
36
26
  >>> font.Italic = True
37
- Event FontEvents_FontChanged(None, u'Italic')
27
+ Event FontEvents_FontChanged(None, 'Italic')
38
28
  >>> PumpEvents(0.01) # just calling. assertion does in `test_pump_events.py`
39
29
  >>> conn.disconnect()
40
30
  """
@@ -194,23 +194,6 @@ class VariantTestCase(unittest.TestCase):
194
194
  v.value = ""
195
195
  self.assertEqual(v.vt, VT_BSTR)
196
196
 
197
- @unittest.skip(
198
- "Fails on creating `TestComServerLib.TestComServer`. Library not registered."
199
- )
200
- def test_UDT(self):
201
- from comtypes.gen.TestComServerLib import MYCOLOR
202
-
203
- v = VARIANT(MYCOLOR(red=1.0, green=2.0, blue=3.0))
204
- value = v.value
205
- self.assertEqual((1.0, 2.0, 3.0), (value.red, value.green, value.blue))
206
-
207
- def func():
208
- v = VARIANT(MYCOLOR(red=1.0, green=2.0, blue=3.0))
209
- return v.value
210
-
211
- bytes = find_memleak(func)
212
- self.assertFalse(bytes, "Leaks %d bytes" % bytes)
213
-
214
197
  def test_ctypes_in_variant(self):
215
198
  v = VARIANT()
216
199
  objs = [
@@ -0,0 +1,29 @@
1
+ import unittest
2
+
3
+ from comtypes.server.w_getopt import GetoptError, w_getopt
4
+
5
+
6
+ class TestCase(unittest.TestCase):
7
+ def test_1(self):
8
+ args = "-embedding spam /RegServer foo /UnregSERVER blabla".split()
9
+ opts, args = w_getopt(args, "regserver unregserver embedding".split())
10
+ self.assertEqual(
11
+ opts, [("embedding", ""), ("regserver", ""), ("unregserver", "")]
12
+ )
13
+ self.assertEqual(args, ["spam", "foo", "blabla"])
14
+
15
+ def test_2(self):
16
+ args = "/TLB Hello.Tlb HELLO.idl".split()
17
+ opts, args = w_getopt(args, ["tlb:"])
18
+ self.assertEqual(opts, [("tlb", "Hello.Tlb")])
19
+ self.assertEqual(args, ["HELLO.idl"])
20
+
21
+ def test_3(self):
22
+ # Invalid option
23
+ self.assertRaises(
24
+ GetoptError, w_getopt, "/TLIB hello.tlb hello.idl".split(), ["tlb:"]
25
+ )
26
+
27
+ def test_4(self):
28
+ # Missing argument
29
+ self.assertRaises(GetoptError, w_getopt, "/TLB".split(), ["tlb:"])