comtypes 1.4.6__zip → 1.4.8__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.
- {comtypes-1.4.6 → comtypes-1.4.8}/CHANGES.txt +36 -0
- {comtypes-1.4.6/comtypes.egg-info → comtypes-1.4.8}/PKG-INFO +32 -38
- {comtypes-1.4.6 → comtypes-1.4.8}/README.md +30 -36
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/__init__.py +1 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_comobject.py +0 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_memberspec.py +1 -1
- comtypes-1.4.8/comtypes/_meta.py +95 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_npsupport.py +2 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_post_coinit/__init__.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_post_coinit/bstr.py +13 -6
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_post_coinit/misc.py +20 -39
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_post_coinit/unknwn.py +94 -69
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/automation.py +9 -15
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/client/__init__.py +21 -31
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/client/_code_cache.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/client/_events.py +0 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/client/_generate.py +5 -5
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/client/lazybind.py +0 -5
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/git.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/hints.pyi +6 -4
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/persist.py +19 -3
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/safearray.py +2 -6
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/server/__init__.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/server/register.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/shelllink.py +90 -34
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/TestComServer.py +1 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/TestDispServer.py +1 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/__init__.py +0 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/find_memleak.py +0 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_agilent.py +0 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_clear_cache.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_client.py +9 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_createwrappers.py +0 -2
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_dispinterface.py +0 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_excel.py +0 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_inout_args.py +1 -1
- comtypes-1.4.8/comtypes/test/test_monikers.py +70 -0
- comtypes-1.4.8/comtypes/test/test_persist.py +40 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_server.py +6 -0
- comtypes-1.4.8/comtypes/test/test_shelllink.py +129 -0
- comtypes-1.4.8/comtypes/test/test_storage.py +127 -0
- comtypes-1.4.8/comtypes/test/test_stream.py +131 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_typeannotator.py +1 -1
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_urlhistory.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_variant.py +0 -2
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/codegenerator/namespaces.py +97 -27
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/codegenerator/typeannotator.py +2 -4
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/tlbparser.py +33 -32
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/typedesc.py +2 -2
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/typeinfo.py +42 -43
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/util.py +1 -0
- {comtypes-1.4.6 → comtypes-1.4.8/comtypes.egg-info}/PKG-INFO +32 -38
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes.egg-info/SOURCES.txt +5 -1
- comtypes-1.4.8/pyproject.toml +54 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/setup.cfg +1 -1
- comtypes-1.4.6/comtypes/_meta.py +0 -70
- comtypes-1.4.6/comtypes/test/test_istream.py +0 -53
- comtypes-1.4.6/pyproject.toml +0 -3
- {comtypes-1.4.6 → comtypes-1.4.8}/LICENSE.txt +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/MANIFEST.in +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/GUID.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_idl_stuff.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_py_instance_method.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_safearray.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/_tlib_version_checker.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/clear_cache.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/client/_constants.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/connectionpoints.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/errorinfo.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/hresult.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/logutil.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/messageloop.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/patcher.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/server/automation.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/server/connectionpoints.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/server/inprocserver.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/server/localserver.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/server/w_getopt.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/stream.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/mylib.tlb +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/runtests.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/setup.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_BSTR.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_GUID.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_avmc.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_basic.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_casesensitivity.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_client_dynamic.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_client_regenerate_modules.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_collections.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_comserver.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_dispifc_records.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_dispifc_safearrays.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_dyndispatch.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_findgendir.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_ie.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_ienum.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_imfattributes.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_midl_safearray_create.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_npsupport.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_outparam.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_propputref.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_recordinfo.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_safearray.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_showevents.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_typeinfo.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_win32com_interop.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_wmi.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/test_word.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/test/urlhist.tlb +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/codegenerator/__init__.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/codegenerator/codegenerator.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/codegenerator/helpers.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/codegenerator/modulenamer.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/codegenerator/packing.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/tools/typedesc_base.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes/viewobject.py +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.4.6 → comtypes-1.4.8}/setup.py +0 -0
|
@@ -69,12 +69,37 @@ class _cominterface_meta(type):
|
|
|
69
69
|
def __new__(cls, name, bases, namespace):
|
|
70
70
|
methods = namespace.pop("_methods_", None)
|
|
71
71
|
dispmethods = namespace.pop("_disp_methods_", None)
|
|
72
|
-
|
|
72
|
+
self = type.__new__(cls, name, bases, namespace)
|
|
73
73
|
|
|
74
74
|
if methods is not None:
|
|
75
|
-
|
|
75
|
+
self._methods_ = methods
|
|
76
76
|
if dispmethods is not None:
|
|
77
|
-
|
|
77
|
+
self._disp_methods_ = dispmethods
|
|
78
|
+
|
|
79
|
+
# ` _compointer_meta` is a subclass inherited from `_cominterface_meta`.
|
|
80
|
+
# `_compointer_base` uses `_compointer_meta` as its metaclass.
|
|
81
|
+
# In other words, when the `__new__` method of this metaclass is called,
|
|
82
|
+
# `_compointer_base` type or an subclass of it might be created and assigned
|
|
83
|
+
# to `self`.
|
|
84
|
+
if bases == (c_void_p,):
|
|
85
|
+
# `self` is the `_compointer_base` type.
|
|
86
|
+
# On some versions of Python, `_compointer_base` is not yet available in
|
|
87
|
+
# the accessible namespace at this point in its initialization, and
|
|
88
|
+
# referencing it could raise a `NameError`.
|
|
89
|
+
# This metaclass is intended to be used only as a base class for defining
|
|
90
|
+
# the `_compointer_meta` or as the metaclass for the `IUnknown`, so the
|
|
91
|
+
# situation where the `bases` parameter is `(c_void_p,)` is limited to when
|
|
92
|
+
# the `_compointer_meta` is specified as the metaclass of the
|
|
93
|
+
# `_compointer_base`.
|
|
94
|
+
# Prevent specifying the metaclass type instance in the `bases` parameter
|
|
95
|
+
# when instantiating it, as this would lead to infinite recursion.
|
|
96
|
+
return self
|
|
97
|
+
if issubclass(self, _compointer_base):
|
|
98
|
+
# `self` is a `POINTER(interface)` type.
|
|
99
|
+
# Prevent creating/registering a pointer to a pointer (to a pointer...),
|
|
100
|
+
# which would lead to infinite recursion.
|
|
101
|
+
# Depending on a version or revision of Python, this may be essential.
|
|
102
|
+
return self
|
|
78
103
|
|
|
79
104
|
# If we sublass a COM interface, for example:
|
|
80
105
|
#
|
|
@@ -85,49 +110,67 @@ class _cominterface_meta(type):
|
|
|
85
110
|
# subclass of POINTER(IUnknown) because of the way ctypes
|
|
86
111
|
# typechecks work.
|
|
87
112
|
if bases == (object,):
|
|
88
|
-
|
|
113
|
+
# `self` is the `IUnknown` type.
|
|
114
|
+
_ptr_bases = (self, _compointer_base)
|
|
89
115
|
else:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
# `self` is an interface type derived from `IUnknown`.
|
|
117
|
+
_ptr_bases = (self, POINTER(bases[0]))
|
|
118
|
+
|
|
119
|
+
# The interface 'self' is used as a mixin.
|
|
120
|
+
# HACK: Could `type(_compointer_base)` be replaced with `_compointer_meta`?
|
|
121
|
+
# `type(klass)` returns its metaclass.
|
|
122
|
+
# Since this specification, `type(_compointer_base)` will return the
|
|
123
|
+
# `_compointer_meta` type as per the class definition.
|
|
124
|
+
# The reason for this implementation might be a remnant of the differences in
|
|
125
|
+
# how metaclasses work between Python 3.x and Python 2.x.
|
|
126
|
+
# If there are no problems with the versions of Python that `comtypes`
|
|
127
|
+
# supports, this replacement could make the process flow easier to understand.
|
|
93
128
|
p = type(_compointer_base)(
|
|
94
|
-
"POINTER(
|
|
129
|
+
f"POINTER({self.__name__})",
|
|
95
130
|
_ptr_bases,
|
|
96
|
-
{"__com_interface__":
|
|
131
|
+
{"__com_interface__": self, "_needs_com_addref_": None},
|
|
97
132
|
)
|
|
98
133
|
|
|
99
|
-
from ctypes import _pointer_type_cache
|
|
134
|
+
from ctypes import _pointer_type_cache # type: ignore
|
|
100
135
|
|
|
101
|
-
_pointer_type_cache[
|
|
136
|
+
_pointer_type_cache[self] = p
|
|
102
137
|
|
|
103
|
-
if
|
|
138
|
+
if self._case_insensitive_:
|
|
139
|
+
self._patch_case_insensitive_to_ptr_type(p)
|
|
140
|
+
self._patch_reference_fix_to_ptrptr_type(POINTER(p)) # type: ignore
|
|
104
141
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
return self
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def _patch_case_insensitive_to_ptr_type(p: Type) -> None:
|
|
146
|
+
@patcher.Patch(p)
|
|
147
|
+
class CaseInsensitive(object):
|
|
148
|
+
# case insensitive attributes for COM methods and properties
|
|
149
|
+
def __getattr__(self, name):
|
|
150
|
+
"""Implement case insensitive access to methods and properties"""
|
|
151
|
+
try:
|
|
152
|
+
fixed_name = self.__map_case__[name.lower()]
|
|
153
|
+
except KeyError:
|
|
154
|
+
raise AttributeError(name) # Should we use exception-chaining?
|
|
155
|
+
if fixed_name != name: # prevent unbounded recursion
|
|
156
|
+
return getattr(self, fixed_name)
|
|
157
|
+
raise AttributeError(name)
|
|
158
|
+
|
|
159
|
+
# __setattr__ is pretty heavy-weight, because it is called for
|
|
160
|
+
# EVERY attribute assignment. Settings a non-com attribute
|
|
161
|
+
# through this function takes 8.6 usec, while without this
|
|
162
|
+
# function it takes 0.7 sec - 12 times slower.
|
|
163
|
+
#
|
|
164
|
+
# How much faster would this be if implemented in C?
|
|
165
|
+
def __setattr__(self, name, value):
|
|
166
|
+
"""Implement case insensitive access to methods and properties"""
|
|
167
|
+
object.__setattr__(
|
|
168
|
+
self, self.__map_case__.get(name.lower(), name), value
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
@staticmethod
|
|
172
|
+
def _patch_reference_fix_to_ptrptr_type(pp: Type) -> None:
|
|
173
|
+
@patcher.Patch(pp)
|
|
131
174
|
class ReferenceFix(object):
|
|
132
175
|
def __setitem__(self, index, value):
|
|
133
176
|
# We override the __setitem__ method of the
|
|
@@ -149,13 +192,11 @@ class _cominterface_meta(type):
|
|
|
149
192
|
# CopyComPointer should do if index != 0.
|
|
150
193
|
if bool(value):
|
|
151
194
|
value.AddRef()
|
|
152
|
-
super(
|
|
195
|
+
super(pp, self).__setitem__(index, value) # type: ignore
|
|
153
196
|
return
|
|
154
197
|
from _ctypes import CopyComPointer
|
|
155
198
|
|
|
156
|
-
CopyComPointer(value, self)
|
|
157
|
-
|
|
158
|
-
return new_cls
|
|
199
|
+
CopyComPointer(value, self) # type: ignore
|
|
159
200
|
|
|
160
201
|
def __setattr__(self, name, value):
|
|
161
202
|
if name == "_methods_":
|
|
@@ -308,16 +349,13 @@ class _cominterface_meta(type):
|
|
|
308
349
|
|
|
309
350
|
def __get_baseinterface_methodcount(self):
|
|
310
351
|
"Return the number of com methods in the base interfaces"
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
result += len(itf
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if name == "_methods_":
|
|
319
|
-
raise TypeError("baseinterface '%s' has no _methods_" % itf.__name__)
|
|
320
|
-
raise
|
|
352
|
+
result = 0
|
|
353
|
+
for itf in self.mro()[1:-1]:
|
|
354
|
+
if "_methods_" in vars(itf):
|
|
355
|
+
result += len(vars(itf)["_methods_"])
|
|
356
|
+
else:
|
|
357
|
+
raise TypeError(f"baseinterface '{itf.__name__}' has no _methods_")
|
|
358
|
+
return result
|
|
321
359
|
|
|
322
360
|
def _make_methods(self, methods: List[_ComMemberSpec]) -> None:
|
|
323
361
|
if self._case_insensitive_:
|
|
@@ -363,9 +401,11 @@ class _cominterface_meta(type):
|
|
|
363
401
|
################################################################
|
|
364
402
|
|
|
365
403
|
|
|
404
|
+
# will not work if we change the order of the two base classes!
|
|
366
405
|
class _compointer_meta(type(c_void_p), _cominterface_meta):
|
|
367
|
-
"metaclass for COM interface pointer classes"
|
|
368
|
-
|
|
406
|
+
"""metaclass for COM interface pointer classes"""
|
|
407
|
+
|
|
408
|
+
pass # no functionality, but needed to avoid a metaclass conflict
|
|
369
409
|
|
|
370
410
|
|
|
371
411
|
class _compointer_base(c_void_p, metaclass=_compointer_meta):
|
|
@@ -385,21 +425,6 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
|
|
|
385
425
|
_debug("Release %s", self)
|
|
386
426
|
self.Release()
|
|
387
427
|
|
|
388
|
-
def __cmp__(self, other):
|
|
389
|
-
"""Compare pointers to COM interfaces."""
|
|
390
|
-
# COM identity rule
|
|
391
|
-
#
|
|
392
|
-
# XXX To compare COM interface pointers, should we
|
|
393
|
-
# automatically QueryInterface for IUnknown on both items, and
|
|
394
|
-
# compare the pointer values?
|
|
395
|
-
if not isinstance(other, _compointer_base):
|
|
396
|
-
return 1
|
|
397
|
-
|
|
398
|
-
# get the value property of the c_void_p baseclass, this is the pointer value
|
|
399
|
-
return cmp(
|
|
400
|
-
super(_compointer_base, self).value, super(_compointer_base, other).value
|
|
401
|
-
)
|
|
402
|
-
|
|
403
428
|
def __eq__(self, other):
|
|
404
429
|
if not isinstance(other, _compointer_base):
|
|
405
430
|
return False
|
|
@@ -4,7 +4,7 @@ import datetime
|
|
|
4
4
|
import decimal
|
|
5
5
|
import sys
|
|
6
6
|
from ctypes import *
|
|
7
|
-
from ctypes import _Pointer
|
|
7
|
+
from ctypes import _Pointer, Array as _CArrayType
|
|
8
8
|
from _ctypes import CopyComPointer
|
|
9
9
|
from ctypes.wintypes import DWORD, LONG, UINT, VARIANT_BOOL, WCHAR, WORD
|
|
10
10
|
from typing import Any, ClassVar, Dict, List, Optional, TYPE_CHECKING, Type
|
|
@@ -16,9 +16,11 @@ import comtypes.patcher
|
|
|
16
16
|
import comtypes
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
19
|
+
from ctypes import _CArgObject
|
|
19
20
|
from comtypes import hints # type: ignore
|
|
20
21
|
from comtypes import _safearray
|
|
21
22
|
else:
|
|
23
|
+
_CArgObject = type(byref(c_int()))
|
|
22
24
|
try:
|
|
23
25
|
from comtypes import _safearray
|
|
24
26
|
except (ImportError, AttributeError):
|
|
@@ -50,7 +52,6 @@ INVOKEKIND = tagINVOKEKIND
|
|
|
50
52
|
# helpers
|
|
51
53
|
IID_NULL = GUID()
|
|
52
54
|
riid_null = byref(IID_NULL)
|
|
53
|
-
_byref_type = type(byref(c_int()))
|
|
54
55
|
|
|
55
56
|
# 30. December 1899, midnight. For VT_DATE.
|
|
56
57
|
_com_null_date = datetime.datetime(1899, 12, 30, 0, 0, 0)
|
|
@@ -129,7 +130,7 @@ class tagDEC(Structure):
|
|
|
129
130
|
("Lo64", c_ulonglong),
|
|
130
131
|
]
|
|
131
132
|
|
|
132
|
-
def as_decimal(self):
|
|
133
|
+
def as_decimal(self) -> decimal.Decimal:
|
|
133
134
|
"""Convert a tagDEC struct to Decimal.
|
|
134
135
|
|
|
135
136
|
See http://msdn.microsoft.com/en-us/library/cc234586.aspx for the tagDEC
|
|
@@ -137,12 +138,8 @@ class tagDEC(Structure):
|
|
|
137
138
|
|
|
138
139
|
"""
|
|
139
140
|
digits = (self.Hi32 << 64) + self.Lo64
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
digits,
|
|
143
|
-
self.scale,
|
|
144
|
-
)
|
|
145
|
-
return decimal.Decimal(decimal_str)
|
|
141
|
+
sign = "-" if self.sign else ""
|
|
142
|
+
return decimal.Decimal(f"{sign}{digits}e-{self.scale}")
|
|
146
143
|
|
|
147
144
|
|
|
148
145
|
DECIMAL = tagDEC
|
|
@@ -382,7 +379,7 @@ class tagVARIANT(Structure):
|
|
|
382
379
|
elif isinstance(value, c_uint64):
|
|
383
380
|
self.vt = VT_UI8
|
|
384
381
|
self._.VT_UI8 = value
|
|
385
|
-
elif isinstance(value,
|
|
382
|
+
elif isinstance(value, _CArgObject):
|
|
386
383
|
ref = value._obj
|
|
387
384
|
self._.c_void_p = addressof(ref)
|
|
388
385
|
self.__keepref = value
|
|
@@ -609,9 +606,6 @@ v.vt = VT_ERROR
|
|
|
609
606
|
v._.VT_I4 = 0x80020004
|
|
610
607
|
del v
|
|
611
608
|
|
|
612
|
-
_carg_obj = type(byref(c_int()))
|
|
613
|
-
from ctypes import Array as _CArrayType
|
|
614
|
-
|
|
615
609
|
|
|
616
610
|
@comtypes.patcher.Patch(POINTER(VARIANT))
|
|
617
611
|
class _(object):
|
|
@@ -626,7 +620,7 @@ class _(object):
|
|
|
626
620
|
if isinstance(arg, POINTER(VARIANT)):
|
|
627
621
|
return arg
|
|
628
622
|
# accept byref(VARIANT) instance
|
|
629
|
-
if isinstance(arg,
|
|
623
|
+
if isinstance(arg, _CArgObject) and isinstance(arg._obj, VARIANT):
|
|
630
624
|
return arg
|
|
631
625
|
# accept VARIANT instance
|
|
632
626
|
if isinstance(arg, VARIANT):
|
|
@@ -750,7 +744,7 @@ EXCEPINFO = tagEXCEPINFO
|
|
|
750
744
|
|
|
751
745
|
class tagDISPPARAMS(Structure):
|
|
752
746
|
if TYPE_CHECKING:
|
|
753
|
-
rgvarg:
|
|
747
|
+
rgvarg: _CArrayType[VARIANT]
|
|
754
748
|
rgdispidNamedArgs: _Pointer[DISPID]
|
|
755
749
|
cArgs: int
|
|
756
750
|
cNamedArgs: int
|
|
@@ -138,22 +138,17 @@ wrap = GetBestInterface
|
|
|
138
138
|
# Should we do this for POINTER(IUnknown) also?
|
|
139
139
|
ctypes.POINTER(automation.IDispatch).__ctypes_from_outparam__ = wrap_outparam # type: ignore
|
|
140
140
|
|
|
141
|
+
|
|
141
142
|
################################################################
|
|
142
143
|
#
|
|
143
144
|
# Object creation
|
|
144
145
|
#
|
|
145
146
|
@overload
|
|
146
|
-
def GetActiveObject(progid: _UnionT[str, CoClass, GUID]) -> Any:
|
|
147
|
-
...
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
def GetActiveObject(progid: _UnionT[str, CoClass, GUID]) -> Any: ...
|
|
150
148
|
@overload
|
|
151
149
|
def GetActiveObject(
|
|
152
150
|
progid: _UnionT[str, CoClass, GUID], interface: Type[_T_IUnknown]
|
|
153
|
-
) -> _T_IUnknown:
|
|
154
|
-
...
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
) -> _T_IUnknown: ...
|
|
157
152
|
def GetActiveObject(
|
|
158
153
|
progid: _UnionT[str, CoClass, GUID],
|
|
159
154
|
interface: Optional[Type[IUnknown]] = None,
|
|
@@ -193,14 +188,19 @@ def _manage(
|
|
|
193
188
|
if TYPE_CHECKING:
|
|
194
189
|
|
|
195
190
|
@overload
|
|
196
|
-
def GetClassObject(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
191
|
+
def GetClassObject(
|
|
192
|
+
progid: _UnionT[str, CoClass, GUID],
|
|
193
|
+
clsctx: Optional[int] = None,
|
|
194
|
+
pServerInfo: Optional[comtypes.COSERVERINFO] = None,
|
|
195
|
+
interface: None = None,
|
|
196
|
+
) -> hints.IClassFactory: ...
|
|
200
197
|
@overload
|
|
201
|
-
def GetClassObject(
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
def GetClassObject(
|
|
199
|
+
progid: _UnionT[str, CoClass, GUID],
|
|
200
|
+
clsctx: Optional[int] = None,
|
|
201
|
+
pServerInfo: Optional[comtypes.COSERVERINFO] = None,
|
|
202
|
+
interface: Type[_T_IUnknown] = hints.IClassFactory,
|
|
203
|
+
) -> _T_IUnknown: ...
|
|
204
204
|
|
|
205
205
|
|
|
206
206
|
def GetClassObject(progid, clsctx=None, pServerInfo=None, interface=None):
|
|
@@ -216,10 +216,7 @@ def GetClassObject(progid, clsctx=None, pServerInfo=None, interface=None):
|
|
|
216
216
|
|
|
217
217
|
|
|
218
218
|
@overload
|
|
219
|
-
def CreateObject(progid: _UnionT[str, Type[CoClass], GUID]) -> Any:
|
|
220
|
-
...
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
def CreateObject(progid: _UnionT[str, Type[CoClass], GUID]) -> Any: ...
|
|
223
220
|
@overload
|
|
224
221
|
def CreateObject(
|
|
225
222
|
progid: _UnionT[str, Type[CoClass], GUID],
|
|
@@ -228,10 +225,7 @@ def CreateObject(
|
|
|
228
225
|
interface: Optional[Type[_T_IUnknown]] = None,
|
|
229
226
|
dynamic: bool = ...,
|
|
230
227
|
pServerInfo: Optional[comtypes.COSERVERINFO] = None,
|
|
231
|
-
) -> _T_IUnknown:
|
|
232
|
-
...
|
|
233
|
-
|
|
234
|
-
|
|
228
|
+
) -> _T_IUnknown: ...
|
|
235
229
|
def CreateObject(
|
|
236
230
|
progid: _UnionT[str, Type[CoClass], GUID], # which object to create
|
|
237
231
|
clsctx: Optional[int] = None, # how to create the object
|
|
@@ -297,15 +291,11 @@ def CreateObject(
|
|
|
297
291
|
|
|
298
292
|
|
|
299
293
|
@overload
|
|
300
|
-
def CoGetObject(displayname: str, interface: Type[_T_IUnknown]) -> _T_IUnknown:
|
|
301
|
-
...
|
|
302
|
-
|
|
303
|
-
|
|
294
|
+
def CoGetObject(displayname: str, interface: Type[_T_IUnknown]) -> _T_IUnknown: ...
|
|
304
295
|
@overload
|
|
305
|
-
def CoGetObject(
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
296
|
+
def CoGetObject(
|
|
297
|
+
displayname: str, interface: None = None, dynamic: bool = False
|
|
298
|
+
) -> Any: ...
|
|
309
299
|
def CoGetObject(
|
|
310
300
|
displayname: str,
|
|
311
301
|
interface: Optional[Type[comtypes.IUnknown]] = None,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from __future__ import print_function
|
|
2
1
|
import ctypes
|
|
3
2
|
import importlib
|
|
4
3
|
import inspect
|
|
@@ -106,7 +105,8 @@ def GetModule(tlib: _UnionT[Any, typeinfo.ITypeLib]) -> types.ModuleType:
|
|
|
106
105
|
frame = sys._getframe(1)
|
|
107
106
|
_file_: Optional[str] = frame.f_globals.get("__file__", None)
|
|
108
107
|
pathname, is_abs = _resolve_filename(
|
|
109
|
-
tlib_string,
|
|
108
|
+
tlib_string,
|
|
109
|
+
_file_ and os.path.dirname(_file_), # type: ignore
|
|
110
110
|
)
|
|
111
111
|
logger.debug("GetModule(%s), resolved: %s", pathname, is_abs)
|
|
112
112
|
tlib = _load_tlib(pathname) # don't register
|
|
@@ -251,9 +251,9 @@ _ItfName = str
|
|
|
251
251
|
_ItfIid = str
|
|
252
252
|
|
|
253
253
|
|
|
254
|
-
def _get_known_namespaces() ->
|
|
255
|
-
Mapping[_SymbolName, _ModuleName], Mapping[_ItfName, _ItfIid]
|
|
256
|
-
|
|
254
|
+
def _get_known_namespaces() -> (
|
|
255
|
+
Tuple[Mapping[_SymbolName, _ModuleName], Mapping[_ItfName, _ItfIid]]
|
|
256
|
+
):
|
|
257
257
|
"""Returns symbols and interfaces that are already statically defined in `ctypes`
|
|
258
258
|
and `comtypes`.
|
|
259
259
|
From `ctypes`, all the names are obtained.
|
|
@@ -126,11 +126,6 @@ class Dispatch(object):
|
|
|
126
126
|
"QueryInterface is forwarded to the real com object."
|
|
127
127
|
return self._comobj.QueryInterface(*args)
|
|
128
128
|
|
|
129
|
-
def __cmp__(self, other):
|
|
130
|
-
if not isinstance(other, Dispatch):
|
|
131
|
-
return 1
|
|
132
|
-
return cmp(self._comobj, other._comobj)
|
|
133
|
-
|
|
134
129
|
def __eq__(self, other):
|
|
135
130
|
return isinstance(other, Dispatch) and self._comobj == other._comobj
|
|
136
131
|
|
|
@@ -10,8 +10,10 @@ from typing import Callable, Iterator, Sequence
|
|
|
10
10
|
|
|
11
11
|
if sys.version_info >= (3, 8):
|
|
12
12
|
from typing import Protocol
|
|
13
|
+
from typing import Literal as Literal
|
|
13
14
|
else:
|
|
14
15
|
from typing_extensions import Protocol
|
|
16
|
+
from typing_extensions import Literal as Literal
|
|
15
17
|
if sys.version_info >= (3, 9):
|
|
16
18
|
from typing import Annotated as Annotated
|
|
17
19
|
else:
|
|
@@ -251,7 +253,7 @@ _T_E = TypeVar("_T_E")
|
|
|
251
253
|
def to_dunder_iter(
|
|
252
254
|
newenum: _UnionT[
|
|
253
255
|
_Descriptor[_T_Inst, Iterator[_T_E]], Callable[[_T_Inst], Iterator[_T_E]]
|
|
254
|
-
]
|
|
256
|
+
],
|
|
255
257
|
) -> Callable[[_T_Inst], Iterator[_T_E]]: ...
|
|
256
258
|
@overload
|
|
257
259
|
def to_dunder_iter(newenum: Any) -> Callable[..., NoReturn]: ...
|
|
@@ -264,7 +266,7 @@ def to_dunder_call(
|
|
|
264
266
|
_GetSetNamedProperty[_T_Inst, _P_Get, _R_Get, ...],
|
|
265
267
|
_GetOnlyNamedProperty[_T_Inst, _P_Get, _R_Get],
|
|
266
268
|
Callable[Concatenate[_T_Inst, _P_Get], _R_Get],
|
|
267
|
-
]
|
|
269
|
+
],
|
|
268
270
|
) -> Callable[Concatenate[_T_Inst, _P_Get], _R_Get]: ...
|
|
269
271
|
@overload
|
|
270
272
|
def to_dunder_call(item: Any) -> Callable[..., NoReturn]: ...
|
|
@@ -276,7 +278,7 @@ def to_dunder_getitem(
|
|
|
276
278
|
_GetSetNamedProperty[_T_Inst, _P_Get, _R_Get, ...],
|
|
277
279
|
_GetOnlyNamedProperty[_T_Inst, _P_Get, _R_Get],
|
|
278
280
|
Callable[Concatenate[_T_Inst, _P_Get], _R_Get],
|
|
279
|
-
]
|
|
281
|
+
],
|
|
280
282
|
) -> Callable[Concatenate[_T_Inst, _P_Get], _R_Get]: ...
|
|
281
283
|
@overload
|
|
282
284
|
def to_dunder_getitem(item: Any) -> Callable[..., NoReturn]: ...
|
|
@@ -287,7 +289,7 @@ def to_dunder_setitem(
|
|
|
287
289
|
item: _UnionT[
|
|
288
290
|
_GetSetNamedProperty[_T_Inst, ..., Any, _P_Set],
|
|
289
291
|
_SetOnlyNamedProperty[_T_Inst, _P_Set],
|
|
290
|
-
]
|
|
292
|
+
],
|
|
291
293
|
) -> Callable[Concatenate[_T_Inst, _P_Set], Any]: ...
|
|
292
294
|
@overload
|
|
293
295
|
def to_dunder_setitem(item: Any) -> Callable[..., NoReturn]: ...
|
|
@@ -9,12 +9,20 @@
|
|
|
9
9
|
The 'DictPropertyBag' class is a class implementing the IPropertyBag
|
|
10
10
|
interface, useful in client code.
|
|
11
11
|
"""
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
from ctypes import c_int, c_ulong, c_ushort, c_wchar_p
|
|
14
|
+
from ctypes import POINTER, Structure
|
|
13
15
|
from ctypes.wintypes import WORD, DWORD, BOOL
|
|
14
|
-
from
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
17
|
+
|
|
18
|
+
from comtypes import GUID, IUnknown, COMMETHOD, HRESULT
|
|
15
19
|
from comtypes import IPersist
|
|
16
20
|
from comtypes.automation import VARIANT, tagEXCEPINFO
|
|
17
21
|
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from comtypes import hints # type: ignore
|
|
24
|
+
|
|
25
|
+
|
|
18
26
|
# XXX Replace by canonical solution!!!
|
|
19
27
|
WSTRING = c_wchar_p
|
|
20
28
|
|
|
@@ -236,9 +244,17 @@ class IPersistFile(IPersist):
|
|
|
236
244
|
),
|
|
237
245
|
]
|
|
238
246
|
|
|
247
|
+
if TYPE_CHECKING:
|
|
248
|
+
|
|
249
|
+
def IsDirty(self) -> hints.Hresult: ...
|
|
250
|
+
def Load(self, pszFileName: str, dwMode: int) -> hints.Hresult: ...
|
|
251
|
+
def Save(self, pszFileName: str, fRemember: bool) -> hints.Hresult: ...
|
|
252
|
+
def SaveCompleted(self, pszFileName: str) -> hints.Hresult: ...
|
|
253
|
+
def GetCurFile(self) -> str: ...
|
|
254
|
+
|
|
239
255
|
|
|
240
256
|
from comtypes import COMObject
|
|
241
|
-
from comtypes.hresult import
|
|
257
|
+
from comtypes.hresult import E_INVALIDARG, S_OK
|
|
242
258
|
|
|
243
259
|
|
|
244
260
|
class DictPropertyBag(COMObject):
|
|
@@ -81,9 +81,7 @@ def _make_safearray_type(itemtype):
|
|
|
81
81
|
)
|
|
82
82
|
|
|
83
83
|
meta = type(_safearray.tagSAFEARRAY)
|
|
84
|
-
sa_type = meta.
|
|
85
|
-
meta, "SAFEARRAY_%s" % itemtype.__name__, (_safearray.tagSAFEARRAY,), {}
|
|
86
|
-
)
|
|
84
|
+
sa_type = meta(f"SAFEARRAY_{itemtype.__name__}", (_safearray.tagSAFEARRAY,), {})
|
|
87
85
|
|
|
88
86
|
try:
|
|
89
87
|
vartype = _ctype_to_vartype[itemtype]
|
|
@@ -192,9 +190,7 @@ def _make_safearray_type(itemtype):
|
|
|
192
190
|
nitems *= d
|
|
193
191
|
rgsa[i].cElements = d
|
|
194
192
|
rgsa[i].lBound = lBound
|
|
195
|
-
pa = _safearray.SafeArrayCreateEx(
|
|
196
|
-
cls._vartype_, value.ndim, rgsa, extra # cDims # rgsaBound
|
|
197
|
-
) # pvExtra
|
|
193
|
+
pa = _safearray.SafeArrayCreateEx(cls._vartype_, value.ndim, rgsa, extra)
|
|
198
194
|
if not pa:
|
|
199
195
|
if cls._vartype_ == VT_RECORD and extra is None:
|
|
200
196
|
raise TypeError(
|