comtypes 1.4.11__zip → 1.4.13__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 (151) hide show
  1. {comtypes-1.4.11 → comtypes-1.4.13}/CHANGES.txt +33 -0
  2. {comtypes-1.4.11/comtypes.egg-info → comtypes-1.4.13}/PKG-INFO +5 -5
  3. {comtypes-1.4.11 → comtypes-1.4.13}/README.md +3 -3
  4. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/__init__.py +8 -2
  5. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_comobject.py +6 -6
  6. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_memberspec.py +7 -7
  7. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_meta.py +7 -3
  8. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_npsupport.py +12 -17
  9. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_post_coinit/_cominterface_meta_patcher.py +5 -5
  10. comtypes-1.4.13/comtypes/_post_coinit/activeobj.py +61 -0
  11. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_post_coinit/misc.py +1 -23
  12. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_post_coinit/unknwn.py +10 -8
  13. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_vtbl.py +3 -3
  14. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/automation.py +10 -13
  15. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/__init__.py +2 -1
  16. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/_activeobj.py +8 -0
  17. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/_code_cache.py +1 -1
  18. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/_constants.py +1 -1
  19. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/_events.py +6 -6
  20. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/_generate.py +1 -1
  21. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/dynamic.py +3 -3
  22. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/lazybind.py +3 -3
  23. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/errorinfo.py +1 -1
  24. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/hresult.py +68 -0
  25. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/messageloop.py +1 -1
  26. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/patcher.py +2 -2
  27. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/persist.py +9 -2
  28. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/safearray.py +10 -10
  29. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/server/__init__.py +5 -37
  30. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/server/automation.py +2 -2
  31. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/server/connectionpoints.py +3 -3
  32. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/server/inprocserver.py +2 -2
  33. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/server/localserver.py +3 -3
  34. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/server/register.py +5 -5
  35. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_agilent.py +1 -1
  36. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_client_dynamic.py +1 -1
  37. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_comserver.py +15 -2
  38. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_createwrappers.py +1 -1
  39. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_dispifc_records.py +0 -2
  40. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_dispifc_safearrays.py +0 -2
  41. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_dispinterface.py +1 -1
  42. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_excel.py +2 -5
  43. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_getactiveobj.py +19 -2
  44. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_hresult.py +39 -0
  45. comtypes-1.4.13/comtypes/test/test_messageloop.py +117 -0
  46. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_midl_safearray_create.py +0 -2
  47. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_msscript.py +1 -1
  48. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_npsupport.py +22 -11
  49. comtypes-1.4.13/comtypes/test/test_persist.py +71 -0
  50. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_recordinfo.py +0 -2
  51. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_server.py +6 -6
  52. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_storage.py +1 -1
  53. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_stream.py +22 -2
  54. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_urlhistory.py +1 -1
  55. comtypes-1.4.13/comtypes/test/test_util.py +227 -0
  56. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_variant.py +41 -24
  57. comtypes-1.4.13/comtypes/test/test_viewobject.py +78 -0
  58. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_word.py +1 -1
  59. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/codegenerator.py +1 -1
  60. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/comments.py +1 -1
  61. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/heads.py +5 -5
  62. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/helpers.py +7 -7
  63. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/namespaces.py +3 -3
  64. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/typeannotator.py +2 -2
  65. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/tlbparser.py +1 -1
  66. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/typedesc.py +14 -14
  67. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/typedesc_base.py +19 -19
  68. comtypes-1.4.13/comtypes/util.py +189 -0
  69. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/viewobject.py +29 -5
  70. {comtypes-1.4.11 → comtypes-1.4.13/comtypes.egg-info}/PKG-INFO +5 -5
  71. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes.egg-info/SOURCES.txt +4 -0
  72. {comtypes-1.4.11 → comtypes-1.4.13}/pyproject.toml +12 -1
  73. {comtypes-1.4.11 → comtypes-1.4.13}/setup.cfg +1 -1
  74. comtypes-1.4.11/comtypes/test/test_persist.py +0 -38
  75. comtypes-1.4.11/comtypes/util.py +0 -107
  76. {comtypes-1.4.11 → comtypes-1.4.13}/LICENSE.txt +0 -0
  77. {comtypes-1.4.11 → comtypes-1.4.13}/MANIFEST.in +0 -0
  78. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/GUID.py +0 -0
  79. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_post_coinit/__init__.py +0 -0
  80. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_post_coinit/bstr.py +0 -0
  81. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_post_coinit/instancemethod.py +0 -0
  82. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_safearray.py +0 -0
  83. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/_tlib_version_checker.py +0 -0
  84. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/clear_cache.py +0 -0
  85. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/_create.py +0 -0
  86. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/client/_managing.py +0 -0
  87. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/connectionpoints.py +0 -0
  88. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/git.py +0 -0
  89. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/hints.pyi +0 -0
  90. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/logutil.py +0 -0
  91. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/server/w_getopt.py +0 -0
  92. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/shelllink.py +0 -0
  93. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/stream.py +0 -0
  94. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/TestComServer.idl +0 -0
  95. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/TestComServer.py +0 -0
  96. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/TestComServer.tlb +0 -0
  97. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/TestDispServer.idl +0 -0
  98. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/TestDispServer.py +0 -0
  99. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/TestDispServer.tlb +0 -0
  100. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/__init__.py +0 -0
  101. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/find_memleak.py +0 -0
  102. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/mylib.idl +0 -0
  103. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/mylib.tlb +0 -0
  104. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/mytypelib.idl +0 -0
  105. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/runtests.py +0 -0
  106. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/setup.py +0 -0
  107. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_BSTR.py +0 -0
  108. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_DISPPARAMS.py +0 -0
  109. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_GUID.py +0 -0
  110. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_QueryService.py +0 -0
  111. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_avmc.py +0 -0
  112. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_basic.py +0 -0
  113. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_casesensitivity.py +0 -0
  114. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_clear_cache.py +0 -0
  115. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_client.py +0 -0
  116. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_client_regenerate_modules.py +0 -0
  117. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_collections.py +0 -0
  118. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_comobject.py +0 -0
  119. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_dict.py +0 -0
  120. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_dyndispatch.py +0 -0
  121. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_errorinfo.py +0 -0
  122. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_findgendir.py +0 -0
  123. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_ie.py +0 -0
  124. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_ienum.py +0 -0
  125. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_imfattributes.py +0 -0
  126. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_inout_args.py +0 -0
  127. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_jscript.js +0 -0
  128. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_monikers.py +0 -0
  129. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_outparam.py +0 -0
  130. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_pump_events.py +0 -0
  131. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_safearray.py +0 -0
  132. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_sapi.py +0 -0
  133. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_server_register.py +0 -0
  134. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_shelllink.py +0 -0
  135. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_showevents.py +0 -0
  136. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_subinterface.py +0 -0
  137. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_typeannotator.py +0 -0
  138. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_typeinfo.py +0 -0
  139. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_w_getopt.py +0 -0
  140. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_win32com_interop.py +0 -0
  141. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/test_wmi.py +0 -0
  142. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/test/urlhist.tlb +0 -0
  143. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/__init__.py +0 -0
  144. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/__init__.py +0 -0
  145. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  146. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/tools/codegenerator/packing.py +0 -0
  147. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes/typeinfo.py +0 -0
  148. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes.egg-info/dependency_links.txt +0 -0
  149. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes.egg-info/entry_points.txt +0 -0
  150. {comtypes-1.4.11 → comtypes-1.4.13}/comtypes.egg-info/top_level.txt +0 -0
  151. {comtypes-1.4.11 → comtypes-1.4.13}/setup.py +0 -0
@@ -5,7 +5,7 @@ from typing import Union as _UnionT
5
5
  import comtypes
6
6
 
7
7
 
8
- class Argument(object):
8
+ class Argument:
9
9
  "a Parameter in the argument list of a callable (Function, Method, ...)"
10
10
 
11
11
  def __init__(self, atype, name):
@@ -13,7 +13,7 @@ class Argument(object):
13
13
  self.name = name
14
14
 
15
15
 
16
- class _HasArgs(object):
16
+ class _HasArgs:
17
17
  def __init__(self):
18
18
  self.arguments = []
19
19
 
@@ -37,7 +37,7 @@ class _HasArgs(object):
37
37
  ################
38
38
 
39
39
 
40
- class Alias(object):
40
+ class Alias:
41
41
  # a C preprocessor alias, like #define A B
42
42
  def __init__(self, name, alias, typ=None):
43
43
  self.name = name
@@ -45,7 +45,7 @@ class Alias(object):
45
45
  self.typ = typ
46
46
 
47
47
 
48
- class Macro(object):
48
+ class Macro:
49
49
  # a C preprocessor definition with arguments
50
50
  def __init__(self, name, args, body):
51
51
  # all arguments are strings, args is the literal argument list
@@ -56,7 +56,7 @@ class Macro(object):
56
56
  self.body = body
57
57
 
58
58
 
59
- class File(object):
59
+ class File:
60
60
  def __init__(self, name):
61
61
  self.name = name
62
62
 
@@ -107,7 +107,7 @@ class Method(_HasArgs):
107
107
  self.returns = returns
108
108
 
109
109
 
110
- class FundamentalType(object):
110
+ class FundamentalType:
111
111
  location = None
112
112
 
113
113
  def __init__(self, name, size, align):
@@ -117,7 +117,7 @@ class FundamentalType(object):
117
117
  self.align = int(align)
118
118
 
119
119
 
120
- class PointerType(object):
120
+ class PointerType:
121
121
  location = None
122
122
 
123
123
  def __init__(self, typ, size, align):
@@ -126,7 +126,7 @@ class PointerType(object):
126
126
  self.align = int(align)
127
127
 
128
128
 
129
- class Typedef(object):
129
+ class Typedef:
130
130
  location = None
131
131
 
132
132
  def __init__(self, name, typ):
@@ -134,7 +134,7 @@ class Typedef(object):
134
134
  self.typ = typ
135
135
 
136
136
 
137
- class ArrayType(object):
137
+ class ArrayType:
138
138
  location = None
139
139
 
140
140
  def __init__(self, typ: Any, min: int, max: int) -> None:
@@ -143,21 +143,21 @@ class ArrayType(object):
143
143
  self.max = max
144
144
 
145
145
 
146
- class StructureHead(object):
146
+ class StructureHead:
147
147
  location = None
148
148
 
149
149
  def __init__(self, struct: "_Struct_Union_Base") -> None:
150
150
  self.struct = struct
151
151
 
152
152
 
153
- class StructureBody(object):
153
+ class StructureBody:
154
154
  location = None
155
155
 
156
156
  def __init__(self, struct: "_Struct_Union_Base") -> None:
157
157
  self.struct = struct
158
158
 
159
159
 
160
- class _Struct_Union_Base(object):
160
+ class _Struct_Union_Base:
161
161
  name: str
162
162
  align: int
163
163
  members: List[_UnionT["Field", Method, Constructor]]
@@ -198,7 +198,7 @@ class Structure(_Struct_Union_Base):
198
198
  self.size = int(size)
199
199
  else:
200
200
  self.size = None
201
- super(Structure, self).__init__()
201
+ super().__init__()
202
202
 
203
203
 
204
204
  class Union(_Struct_Union_Base):
@@ -220,10 +220,10 @@ class Union(_Struct_Union_Base):
220
220
  self.size = int(size)
221
221
  else:
222
222
  self.size = None
223
- super(Union, self).__init__()
223
+ super().__init__()
224
224
 
225
225
 
226
- class Field(object):
226
+ class Field:
227
227
  def __init__(
228
228
  self, name: str, typ: Any, bits: Optional[Any], offset: SupportsInt
229
229
  ) -> None:
@@ -233,14 +233,14 @@ class Field(object):
233
233
  self.offset = int(offset)
234
234
 
235
235
 
236
- class CvQualifiedType(object):
236
+ class CvQualifiedType:
237
237
  def __init__(self, typ, const, volatile):
238
238
  self.typ = typ
239
239
  self.const = const
240
240
  self.volatile = volatile
241
241
 
242
242
 
243
- class Enumeration(object):
243
+ class Enumeration:
244
244
  location = None
245
245
 
246
246
  def __init__(self, name: str, size: SupportsInt, align: SupportsInt) -> None:
@@ -253,14 +253,14 @@ class Enumeration(object):
253
253
  self.values.append(v)
254
254
 
255
255
 
256
- class EnumValue(object):
256
+ class EnumValue:
257
257
  def __init__(self, name: str, value: int, enumeration: Enumeration) -> None:
258
258
  self.name = name
259
259
  self.value = value
260
260
  self.enumeration = enumeration
261
261
 
262
262
 
263
- class Variable(object):
263
+ class Variable:
264
264
  location = None
265
265
 
266
266
  def __init__(self, name, typ, init=None):
@@ -0,0 +1,189 @@
1
+ """This module defines the funtions byref_at(cobj, offset)
2
+ and cast_field(struct, fieldname, fieldtype).
3
+ """
4
+
5
+ import sys
6
+ from ctypes import (
7
+ POINTER,
8
+ Structure,
9
+ Union,
10
+ _SimpleCData,
11
+ addressof,
12
+ byref,
13
+ c_byte,
14
+ c_char,
15
+ c_double,
16
+ c_float,
17
+ c_int,
18
+ c_long,
19
+ c_longdouble,
20
+ c_longlong,
21
+ c_short,
22
+ c_void_p,
23
+ cast,
24
+ sizeof,
25
+ )
26
+ from ctypes import Array as _CArrayType
27
+ from typing import TYPE_CHECKING, Type, TypeVar, overload
28
+
29
+ if TYPE_CHECKING:
30
+ from ctypes import _CArgObject, _CData
31
+
32
+ _T = TypeVar("_T")
33
+ _CT = TypeVar("_CT", bound="_CData")
34
+
35
+
36
+ def _calc_offset():
37
+ # Internal helper function that calculates where the object
38
+ # returned by a byref() call stores the pointer.
39
+
40
+ # The definition of PyCArgObject in C code (that is the type of
41
+ # object that a byref() call returns):
42
+ class PyCArgObject(Structure):
43
+ if sys.version_info >= (3, 14):
44
+ # While C compilers automatically determine appropriate
45
+ # alignment based on field data types, `ctypes` requires
46
+ # explicit control over memory layout.
47
+ #
48
+ # `_pack_ = 8` ensures 8-byte alignment for fields.
49
+ #
50
+ # This works on both 32-bit and 64-bit systems:
51
+ # - On 64-bit systems, this matches the natural alignment
52
+ # for pointers.
53
+ # - On 32-bit systems, this is more strict than necessary
54
+ # (4-byte would be enough), but still produces the
55
+ # correct memory layout with proper padding.
56
+ #
57
+ # With `_pack_`, `ctypes` will automatically add padding
58
+ # here to ensure proper alignment of the `value` field
59
+ # after the `tag` and after the `size`.
60
+ _pack_ = 8
61
+ else:
62
+ # No special packing needed for Python 3.13 and earlier
63
+ # because the default alignment works fine for the legacy
64
+ # structure.
65
+ pass
66
+
67
+ class value(Union):
68
+ if sys.version_info >= (3, 14):
69
+ # In Python 3.14, the tagPyCArgObject structure was
70
+ # modified to better support complex types.
71
+ _fields_ = [
72
+ ("c", c_char),
73
+ ("b", c_char),
74
+ ("h", c_short),
75
+ ("i", c_int),
76
+ ("l", c_long),
77
+ ("q", c_longlong),
78
+ ("g", c_longdouble),
79
+ ("d", c_double),
80
+ ("f", c_float),
81
+ ("p", c_void_p),
82
+ # arrays for real and imaginary of complex
83
+ ("D", c_double * 2),
84
+ ("F", c_float * 2),
85
+ ("G", c_longdouble * 2),
86
+ ]
87
+ else:
88
+ _fields_ = [
89
+ ("c", c_char),
90
+ ("h", c_short),
91
+ ("i", c_int),
92
+ ("l", c_long),
93
+ ("q", c_longlong),
94
+ ("d", c_double),
95
+ ("f", c_float),
96
+ ("p", c_void_p),
97
+ ]
98
+
99
+ #
100
+ # Thanks to Lenard Lindstrom for this tip:
101
+ # sizeof(PyObject_HEAD) is the same as object.__basicsize__.
102
+ #
103
+ _fields_ = [
104
+ ("PyObject_HEAD", c_byte * object.__basicsize__),
105
+ ("pffi_type", c_void_p),
106
+ ("tag", c_char),
107
+ ("value", value),
108
+ ("obj", c_void_p),
109
+ ("size", c_int),
110
+ ]
111
+
112
+ _anonymous_ = ["value"]
113
+
114
+ # additional checks to make sure that everything works as expected
115
+ expected_size = type(byref(c_int())).__basicsize__
116
+ actual_size = sizeof(PyCArgObject)
117
+ if actual_size != expected_size:
118
+ raise RuntimeError(
119
+ f"sizeof(PyCArgObject) mismatch: expected {expected_size}, "
120
+ f"got {actual_size}."
121
+ )
122
+
123
+ obj = c_int()
124
+ ref = byref(obj)
125
+
126
+ argobj = PyCArgObject.from_address(id(ref))
127
+
128
+ if argobj.obj != id(obj) or argobj.p != addressof(obj) or argobj.tag != b"P":
129
+ raise RuntimeError("PyCArgObject field definitions incorrect")
130
+
131
+ return PyCArgObject.p.offset # offset of the pointer field
132
+
133
+
134
+ ################################################################
135
+ #
136
+ # byref_at
137
+ #
138
+ @overload
139
+ def byref_at(obj: _CArrayType, offset: int) -> "_CArgObject": ...
140
+ @overload
141
+ def byref_at(obj: "_CData", offset: int) -> "_CArgObject": ...
142
+ def byref_at(
143
+ obj,
144
+ offset,
145
+ _byref=byref,
146
+ _c_void_p_from_address=c_void_p.from_address,
147
+ _byref_pointer_offset=_calc_offset(),
148
+ ):
149
+ """byref_at(cobj, offset) behaves similar this C code:
150
+
151
+ (((char *)&obj) + offset)
152
+
153
+ In other words, the returned 'pointer' points to the address of
154
+ 'cobj' + 'offset'. 'offset' is in units of bytes.
155
+ """
156
+ ref = _byref(obj)
157
+ # Change the pointer field in the created byref object by adding
158
+ # 'offset' to it:
159
+ _c_void_p_from_address(id(ref) + _byref_pointer_offset).value += offset
160
+ return ref
161
+
162
+
163
+ ################################################################
164
+ #
165
+ # cast_field
166
+ #
167
+ @overload
168
+ def cast_field(
169
+ struct: Structure, fieldname: str, fieldtype: Type["_SimpleCData[_T]"]
170
+ ) -> _T: ...
171
+ @overload
172
+ def cast_field(struct: Structure, fieldname: str, fieldtype: Type[_CT]) -> _CT: ...
173
+ def cast_field(
174
+ struct,
175
+ fieldname,
176
+ fieldtype,
177
+ _POINTER=POINTER,
178
+ _byref_at=byref_at,
179
+ ):
180
+ """cast_field(struct, fieldname, fieldtype)
181
+
182
+ Return the contents of a struct field as it it were of type
183
+ 'fieldtype'.
184
+ """
185
+ fieldoffset = getattr(type(struct), fieldname).offset
186
+ return cast(_byref_at(struct, fieldoffset), _POINTER(fieldtype))[0]
187
+
188
+
189
+ __all__ = ["byref_at", "cast_field"]
@@ -1,9 +1,22 @@
1
1
  # XXX need to find out what the share from comtypes.dataobject.
2
- from ctypes import *
2
+ from ctypes import (
3
+ HRESULT,
4
+ POINTER,
5
+ Structure,
6
+ alignment,
7
+ c_int,
8
+ c_ubyte,
9
+ c_ulong,
10
+ c_ushort,
11
+ c_void_p,
12
+ sizeof,
13
+ )
3
14
  from ctypes.wintypes import _RECTL, HDC, SIZEL, tagPOINT, tagRECT
4
15
 
5
16
  from comtypes import COMMETHOD, GUID, IUnknown
6
17
 
18
+ X64_PYTHON = sizeof(POINTER(c_int)) * 8 == 64
19
+
7
20
 
8
21
  class tagPALETTEENTRY(Structure):
9
22
  _fields_ = [
@@ -27,7 +40,10 @@ class tagLOGPALETTE(Structure):
27
40
  ]
28
41
 
29
42
 
30
- assert sizeof(tagLOGPALETTE) == 8, sizeof(tagLOGPALETTE)
43
+ if X64_PYTHON:
44
+ assert sizeof(tagLOGPALETTE) == 12, sizeof(tagLOGPALETTE)
45
+ else:
46
+ assert sizeof(tagLOGPALETTE) == 8, sizeof(tagLOGPALETTE)
31
47
  assert alignment(tagLOGPALETTE) == 2, alignment(tagLOGPALETTE)
32
48
 
33
49
 
@@ -42,8 +58,12 @@ class tagDVTARGETDEVICE(Structure):
42
58
  ]
43
59
 
44
60
 
45
- assert sizeof(tagDVTARGETDEVICE) == 16, sizeof(tagDVTARGETDEVICE)
46
- assert alignment(tagDVTARGETDEVICE) == 4, alignment(tagDVTARGETDEVICE)
61
+ if X64_PYTHON:
62
+ assert sizeof(tagDVTARGETDEVICE) == 24, sizeof(tagDVTARGETDEVICE)
63
+ assert alignment(tagDVTARGETDEVICE) == 8, alignment(tagDVTARGETDEVICE)
64
+ else:
65
+ assert sizeof(tagDVTARGETDEVICE) == 16, sizeof(tagDVTARGETDEVICE)
66
+ assert alignment(tagDVTARGETDEVICE) == 4, alignment(tagDVTARGETDEVICE)
47
67
 
48
68
 
49
69
  class tagExtentInfo(Structure):
@@ -55,7 +75,7 @@ class tagExtentInfo(Structure):
55
75
 
56
76
  def __init__(self, *args, **kw):
57
77
  self.cb = sizeof(self)
58
- super(tagExtentInfo, self).__init__(*args, **kw)
78
+ super().__init__(*args, **kw)
59
79
 
60
80
  def __repr__(self):
61
81
  size = (self.sizelProposed.cx, self.sizelProposed.cy)
@@ -64,6 +84,10 @@ class tagExtentInfo(Structure):
64
84
 
65
85
  assert sizeof(tagExtentInfo) == 16, sizeof(tagExtentInfo)
66
86
  assert alignment(tagExtentInfo) == 4, alignment(tagExtentInfo)
87
+
88
+ PALETTEENTRY = tagPALETTEENTRY
89
+ LOGPALETTE = tagLOGPALETTE
90
+ DVTARGETDEVICE = tagDVTARGETDEVICE
67
91
  DVEXTENTINFO = tagExtentInfo
68
92
 
69
93
  IAdviseSink = IUnknown # fake the interface
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comtypes
3
- Version: 1.4.11
3
+ Version: 1.4.13
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.8
16
+ Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE.txt
19
19
  Dynamic: download-url
@@ -25,18 +25,18 @@ Dynamic: license-file
25
25
  [![PyPI version](https://badge.fury.io/py/comtypes.svg)](https://pypi.org/project/comtypes/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/comtypes)](https://pypi.org/project/comtypes/) [![PyPI - Python Requires](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpypi.org%2Fpypi%2Fcomtypes%2Fjson&query=info.requires_python&label=Python Requires)](https://pypi.org/project/comtypes/)
26
26
  [![PyPI - License](https://img.shields.io/pypi/l/comtypes)](https://pypi.org/project/comtypes/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/comtypes)](https://pypi.org/project/comtypes/)
27
27
  [![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) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
28
- [![Tidelift Subscription](https://tidelift.com/badges/package/pypi/comtypes)](https://tidelift.com/subscription/pkg/pypi-comtypes?utm_source=pypi-comtypes&utm_medium=readme)
28
+ [![Tidelift Subscription](https://tidelift.com/badges/package/pypi/comtypes)](https://tidelift.com/subscription/pkg/pypi-comtypes?utm_source=pypi-comtypes&utm_medium=readme) [![Coverage](https://img.shields.io/codecov/c/github/enthought/comtypes)](https://app.codecov.io/github/enthought/comtypes)
29
29
 
30
30
 
31
31
  `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.
32
32
 
33
33
  `comtypes` allows you to define, call, and implement custom and dispatch-based COM interfaces in pure Python.
34
34
 
35
- `comtypes` requires Windows and Python 3.8 or later.
35
+ `comtypes` requires Windows and Python 3.9 or later.
36
+ - Version [1.4.12](https://pypi.org/project/comtypes/1.4.12/) is the last version to support Python 3.8.
36
37
  - Version <= [1.4.7](https://pypi.org/project/comtypes/1.4.7/) does not work with Python 3.13 as reported in [GH-618](https://github.com/enthought/comtypes/issues/618). Version [1.4.8](https://pypi.org/project/comtypes/1.4.8/) can work with Python 3.13.
37
38
  - Version [1.4.6](https://pypi.org/project/comtypes/1.4.6/) is the last version to support Python 3.7.
38
39
  - 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.
39
- - `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.
40
40
  - 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.
41
41
 
42
42
  ## Installation
@@ -38,6 +38,7 @@ comtypes.egg-info/entry_points.txt
38
38
  comtypes.egg-info/top_level.txt
39
39
  comtypes/_post_coinit/__init__.py
40
40
  comtypes/_post_coinit/_cominterface_meta_patcher.py
41
+ comtypes/_post_coinit/activeobj.py
41
42
  comtypes/_post_coinit/bstr.py
42
43
  comtypes/_post_coinit/instancemethod.py
43
44
  comtypes/_post_coinit/misc.py
@@ -103,6 +104,7 @@ comtypes/test/test_ienum.py
103
104
  comtypes/test/test_imfattributes.py
104
105
  comtypes/test/test_inout_args.py
105
106
  comtypes/test/test_jscript.js
107
+ comtypes/test/test_messageloop.py
106
108
  comtypes/test/test_midl_safearray_create.py
107
109
  comtypes/test/test_monikers.py
108
110
  comtypes/test/test_msscript.py
@@ -123,7 +125,9 @@ comtypes/test/test_subinterface.py
123
125
  comtypes/test/test_typeannotator.py
124
126
  comtypes/test/test_typeinfo.py
125
127
  comtypes/test/test_urlhistory.py
128
+ comtypes/test/test_util.py
126
129
  comtypes/test/test_variant.py
130
+ comtypes/test/test_viewobject.py
127
131
  comtypes/test/test_w_getopt.py
128
132
  comtypes/test/test_win32com_interop.py
129
133
  comtypes/test/test_wmi.py
@@ -12,7 +12,6 @@ ignore = ["E402"]
12
12
  "comtypes/_vtbl.py" = ["E722"]
13
13
  "comtypes/automation.py" = ["F401", "F403", "F405"]
14
14
  "comtypes/git.py" = ["F401", "F403", "F405"]
15
- "comtypes/util.py" = ["F403", "F405"]
16
15
  "comtypes/viewobject.py" = ["F403", "F405"]
17
16
  "comtypes/client/_constants.py" = ["F401"]
18
17
  "comtypes/server/automation.py" = ["F403", "F405"]
@@ -40,3 +39,15 @@ ignore = ["E402"]
40
39
  "comtypes/test/test_subinterface.py" = ["E401", "F401", "F403", "F405"]
41
40
  "comtypes/test/test_urlhistory.py" = ["E401", "F401", "F403", "F405", "F841"]
42
41
  "comtypes/test/test_variant.py" = ["F401", "F821", "F841"]
42
+
43
+ [tool.coverage.run]
44
+ # Specify the source directory to avoid tracking temporary files created by "test_client_regenerate_modules.py".
45
+ # Without this, coverage track these temporary files, leading to error when trying to generate a report.
46
+ source = ["comtypes"]
47
+ omit = ["comtypes/gen/*"]
48
+
49
+ [tool.coverage.report]
50
+ exclude_also = [
51
+ "if __name__ == .__main__.:",
52
+ "if TYPE_CHECKING:",
53
+ ]
@@ -18,7 +18,7 @@ classifiers =
18
18
  Topic :: Software Development :: Libraries :: Python Modules
19
19
 
20
20
  [options]
21
- python_requires = >=3.8
21
+ python_requires = >=3.9
22
22
  packages =
23
23
  comtypes
24
24
  comtypes._post_coinit
@@ -1,38 +0,0 @@
1
- import tempfile
2
- import unittest as ut
3
- from pathlib import Path
4
-
5
- from comtypes import GUID, CoCreateInstance, IPersist, persist
6
-
7
- CLSID_ShellLink = GUID("{00021401-0000-0000-C000-000000000046}")
8
-
9
-
10
- class Test_IPersist(ut.TestCase):
11
- def test_GetClassID(self):
12
- p = CoCreateInstance(CLSID_ShellLink).QueryInterface(IPersist)
13
- self.assertEqual(p.GetClassID(), CLSID_ShellLink)
14
-
15
-
16
- class Test_IPersistFile(ut.TestCase):
17
- def setUp(self):
18
- td = tempfile.TemporaryDirectory()
19
- self.addCleanup(td.cleanup)
20
- self.tmp_dir = Path(td.name)
21
-
22
- def _create_pf(self) -> persist.IPersistFile:
23
- return CoCreateInstance(CLSID_ShellLink).QueryInterface(persist.IPersistFile)
24
-
25
- def test_load(self):
26
- pf = self._create_pf()
27
- tgt_file = (self.tmp_dir / "tgt.txt").resolve()
28
- tgt_file.touch()
29
- pf.Load(str(tgt_file), persist.STGM_DIRECT)
30
- self.assertEqual(pf.GetCurFile(), str(tgt_file))
31
-
32
- def test_save(self):
33
- pf = self._create_pf()
34
- tgt_file = self.tmp_dir / "tgt.txt"
35
- self.assertFalse(tgt_file.exists())
36
- pf.Save(str(tgt_file), True)
37
- self.assertEqual(pf.GetCurFile(), str(tgt_file))
38
- self.assertTrue(tgt_file.exists())
@@ -1,107 +0,0 @@
1
- """This module defines the funtions byref_at(cobj, offset)
2
- and cast_field(struct, fieldname, fieldtype).
3
- """
4
-
5
- from ctypes import *
6
-
7
-
8
- def _calc_offset():
9
- # Internal helper function that calculates where the object
10
- # returned by a byref() call stores the pointer.
11
-
12
- # The definition of PyCArgObject in C code (that is the type of
13
- # object that a byref() call returns):
14
- class PyCArgObject(Structure):
15
- class value(Union):
16
- _fields_ = [
17
- ("c", c_char),
18
- ("h", c_short),
19
- ("i", c_int),
20
- ("l", c_long),
21
- ("q", c_longlong),
22
- ("d", c_double),
23
- ("f", c_float),
24
- ("p", c_void_p),
25
- ]
26
-
27
- #
28
- # Thanks to Lenard Lindstrom for this tip:
29
- # sizeof(PyObject_HEAD) is the same as object.__basicsize__.
30
- #
31
- _fields_ = [
32
- ("PyObject_HEAD", c_byte * object.__basicsize__),
33
- ("pffi_type", c_void_p),
34
- ("tag", c_char),
35
- ("value", value),
36
- ("obj", c_void_p),
37
- ("size", c_int),
38
- ]
39
-
40
- _anonymous_ = ["value"]
41
-
42
- # additional checks to make sure that everything works as expected
43
-
44
- if sizeof(PyCArgObject) != type(byref(c_int())).__basicsize__:
45
- raise RuntimeError("sizeof(PyCArgObject) invalid")
46
-
47
- obj = c_int()
48
- ref = byref(obj)
49
-
50
- argobj = PyCArgObject.from_address(id(ref))
51
-
52
- if argobj.obj != id(obj) or argobj.p != addressof(obj) or argobj.tag != "P":
53
- raise RuntimeError("PyCArgObject field definitions incorrect")
54
-
55
- return PyCArgObject.p.offset # offset of the pointer field
56
-
57
-
58
- ################################################################
59
- #
60
- # byref_at
61
- #
62
- def byref_at(
63
- obj,
64
- offset,
65
- _byref=byref,
66
- _c_void_p_from_address=c_void_p.from_address,
67
- _byref_pointer_offset=_calc_offset(),
68
- ):
69
- """byref_at(cobj, offset) behaves similar this C code:
70
-
71
- (((char *)&obj) + offset)
72
-
73
- In other words, the returned 'pointer' points to the address of
74
- 'cobj' + 'offset'. 'offset' is in units of bytes.
75
- """
76
- ref = _byref(obj)
77
- # Change the pointer field in the created byref object by adding
78
- # 'offset' to it:
79
- _c_void_p_from_address(id(ref) + _byref_pointer_offset).value += offset
80
- return ref
81
-
82
-
83
- ################################################################
84
- #
85
- # cast_field
86
- #
87
- def cast_field(
88
- struct,
89
- fieldname,
90
- fieldtype,
91
- offset=0,
92
- _POINTER=POINTER,
93
- _byref_at=byref_at,
94
- _byref=byref,
95
- _divmod=divmod,
96
- _sizeof=sizeof,
97
- ):
98
- """cast_field(struct, fieldname, fieldtype)
99
-
100
- Return the contents of a struct field as it it were of type
101
- 'fieldtype'.
102
- """
103
- fieldoffset = getattr(type(struct), fieldname).offset
104
- return cast(_byref_at(struct, fieldoffset), _POINTER(fieldtype))[0]
105
-
106
-
107
- __all__ = ["byref_at", "cast_field"]
File without changes
File without changes
File without changes