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.
- {comtypes-1.4.8 → comtypes-1.4.9}/CHANGES.txt +21 -0
- {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.9}/PKG-INFO +2 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/README.md +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/GUID.py +6 -5
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/__init__.py +16 -5
- comtypes-1.4.9/comtypes/_comobject.py +507 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_memberspec.py +80 -8
- comtypes-1.4.9/comtypes/_post_coinit/_cominterface_meta_patcher.py +153 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/misc.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/unknwn.py +25 -171
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_safearray.py +1 -2
- comtypes-1.4.9/comtypes/_vtbl.py +448 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/automation.py +36 -45
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_code_cache.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_constants.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_events.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_generate.py +4 -8
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/lazybind.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/errorinfo.py +3 -3
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/git.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hints.pyi +7 -15
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/safearray.py +10 -0
- comtypes-1.4.9/comtypes/server/__init__.py +86 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/inprocserver.py +22 -17
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/localserver.py +28 -16
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/register.py +61 -73
- comtypes-1.4.9/comtypes/server/w_getopt.py +48 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/shelllink.py +3 -26
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/__init__.py +9 -11
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_BSTR.py +4 -7
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_avmc.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_casesensitivity.py +3 -5
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_collections.py +3 -3
- comtypes-1.4.9/comtypes/test/test_comobject.py +146 -0
- comtypes-1.4.9/comtypes/test/test_comserver.py +319 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_createwrappers.py +2 -4
- comtypes-1.4.9/comtypes/test/test_dispinterface.py +153 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_excel.py +22 -12
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ie.py +2 -5
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_inout_args.py +7 -4
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_midl_safearray_create.py +9 -1
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_outparam.py +17 -10
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_safearray.py +1 -90
- comtypes-1.4.9/comtypes/test/test_server.py +350 -0
- comtypes-1.4.9/comtypes/test/test_server_register.py +536 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_showevents.py +7 -17
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_variant.py +0 -17
- comtypes-1.4.9/comtypes/test/test_w_getopt.py +29 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_win32com_interop.py +80 -36
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_wmi.py +0 -3
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/codegenerator.py +62 -68
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/helpers.py +8 -8
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/packing.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/typeannotator.py +7 -7
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc.py +1 -6
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/typeinfo.py +11 -22
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/viewobject.py +1 -5
- {comtypes-1.4.8 → comtypes-1.4.9/comtypes.egg-info}/PKG-INFO +2 -2
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/SOURCES.txt +6 -3
- {comtypes-1.4.8 → comtypes-1.4.9}/pyproject.toml +1 -0
- comtypes-1.4.8/comtypes/_comobject.py +0 -833
- comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
- comtypes-1.4.8/comtypes/server/__init__.py +0 -70
- comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
- comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
- comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
- comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
- comtypes-1.4.8/comtypes/test/test_server.py +0 -354
- {comtypes-1.4.8 → comtypes-1.4.9}/LICENSE.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/MANIFEST.in +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_meta.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_npsupport.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/bstr.py +0 -0
- /comtypes-1.4.8/comtypes/_py_instance_method.py → /comtypes-1.4.9/comtypes/_post_coinit/instancemethod.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_tlib_version_checker.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/clear_cache.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/connectionpoints.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hresult.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/logutil.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/messageloop.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/patcher.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/persist.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/automation.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/connectionpoints.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/stream.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/find_memleak.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/runtests.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/setup.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_GUID.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_agilent.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_basic.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_clear_cache.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_dynamic.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_regenerate_modules.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_records.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_safearrays.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dyndispatch.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_findgendir.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ienum.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_imfattributes.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_monikers.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_npsupport.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_persist.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_recordinfo.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_shelllink.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_storage.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_stream.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeannotator.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeinfo.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_urlhistory.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_word.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/urlhist.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/modulenamer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/namespaces.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/tlbparser.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc_base.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/util.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/setup.cfg +0 -0
- {comtypes-1.4.8 → comtypes-1.4.9}/setup.py +0 -0
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
import unittest
|
|
2
|
-
|
|
3
|
-
from ctypes import PyDLL, py_object, c_void_p, byref, POINTER
|
|
2
|
+
from ctypes import POINTER, PyDLL, byref, c_void_p, py_object
|
|
4
3
|
from ctypes.wintypes import BOOL
|
|
5
4
|
|
|
6
|
-
from comtypes import IUnknown
|
|
5
|
+
from comtypes import COMObject, IUnknown
|
|
6
|
+
from comtypes.automation import VARIANT, IDispatch
|
|
7
7
|
from comtypes.client import CreateObject
|
|
8
|
-
from comtypes.automation import IDispatch
|
|
9
|
-
from comtypes.test import requires
|
|
10
8
|
|
|
11
|
-
requires("pythoncom")
|
|
12
9
|
try:
|
|
13
10
|
import pythoncom
|
|
14
11
|
import win32com.client
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
IMPORT_FAILED = False
|
|
14
|
+
# pywin32 is available. The pythoncom dll contains two handy
|
|
15
|
+
# exported functions that allow to create a VARIANT from a Python
|
|
16
|
+
# object, also a function that unpacks a VARIANT into a Python
|
|
17
|
+
# object.
|
|
18
|
+
#
|
|
19
|
+
# This allows us to create und unpack SAFEARRAY instances
|
|
20
|
+
# contained in VARIANTs, and check for consistency with the
|
|
21
|
+
# comtypes code.
|
|
22
|
+
_dll = PyDLL(pythoncom.__file__)
|
|
23
|
+
|
|
24
|
+
# c:/sf/pywin32/com/win32com/src/oleargs.cpp 213
|
|
25
|
+
# PyObject *PyCom_PyObjectFromVariant(const VARIANT *var)
|
|
26
|
+
unpack = _dll.PyCom_PyObjectFromVariant
|
|
27
|
+
unpack.restype = py_object
|
|
28
|
+
unpack.argtypes = (POINTER(VARIANT),)
|
|
29
|
+
|
|
30
|
+
# c:/sf/pywin32/com/win32com/src/oleargs.cpp 54
|
|
31
|
+
# BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var)
|
|
32
|
+
_pack = _dll.PyCom_VariantFromPyObject
|
|
33
|
+
_pack.argtypes = py_object, POINTER(VARIANT)
|
|
34
|
+
_pack.restype = BOOL
|
|
17
35
|
# We use the PyCom_PyObjectFromIUnknown function in pythoncom25.dll to
|
|
18
36
|
# convert a comtypes COM pointer into a pythoncom COM pointer.
|
|
19
37
|
# Fortunately this function is exported by the dll...
|
|
@@ -30,17 +48,58 @@ except ImportError:
|
|
|
30
48
|
# if it is available since pythoncom is not a project dependency and adding tests depending
|
|
31
49
|
# on the vagaries of various testing environments is not deterministic.
|
|
32
50
|
# TODO: Evaluate if we should just remove this test or what.
|
|
33
|
-
|
|
51
|
+
IMPORT_FAILED = True
|
|
34
52
|
|
|
35
53
|
|
|
36
54
|
def setUpModule():
|
|
37
|
-
if
|
|
55
|
+
if IMPORT_FAILED:
|
|
38
56
|
raise unittest.SkipTest(
|
|
39
57
|
"This test requires the pythoncom library installed. If this is "
|
|
40
58
|
"important tests then we need to add dev dependencies to the project that include pythoncom."
|
|
41
59
|
)
|
|
42
60
|
|
|
43
61
|
|
|
62
|
+
################################################################
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def pack(obj):
|
|
66
|
+
var = VARIANT()
|
|
67
|
+
_pack(obj, byref(var))
|
|
68
|
+
return var
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class PyWinSafeArrayTest(unittest.TestCase):
|
|
72
|
+
def test_1dim(self):
|
|
73
|
+
data = (1, 2, 3)
|
|
74
|
+
variant = pack(data)
|
|
75
|
+
self.assertEqual(variant.value, data)
|
|
76
|
+
self.assertEqual(unpack(variant), data)
|
|
77
|
+
|
|
78
|
+
def test_2dim(self):
|
|
79
|
+
data = ((1, 2, 3), (4, 5, 6), (7, 8, 9))
|
|
80
|
+
variant = pack(data)
|
|
81
|
+
self.assertEqual(variant.value, data)
|
|
82
|
+
self.assertEqual(unpack(variant), data)
|
|
83
|
+
|
|
84
|
+
def test_3dim(self):
|
|
85
|
+
data = (((1, 2), (3, 4), (5, 6)), ((7, 8), (9, 10), (11, 12)))
|
|
86
|
+
variant = pack(data)
|
|
87
|
+
self.assertEqual(variant.value, data)
|
|
88
|
+
self.assertEqual(unpack(variant), data)
|
|
89
|
+
|
|
90
|
+
def test_4dim(self):
|
|
91
|
+
data = (
|
|
92
|
+
(((1, 2), (3, 4)), ((5, 6), (7, 8))),
|
|
93
|
+
(((9, 10), (11, 12)), ((13, 14), (15, 16))),
|
|
94
|
+
)
|
|
95
|
+
variant = pack(data)
|
|
96
|
+
self.assertEqual(variant.value, data)
|
|
97
|
+
self.assertEqual(unpack(variant), data)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
################################################################
|
|
101
|
+
|
|
102
|
+
|
|
44
103
|
def comtypes2pywin(ptr, interface=None):
|
|
45
104
|
"""Convert a comtypes pointer 'ptr' into a pythoncom
|
|
46
105
|
PyI<interface> object.
|
|
@@ -56,9 +115,6 @@ def comtypes2pywin(ptr, interface=None):
|
|
|
56
115
|
return _PyCom_PyObjectFromIUnknown(ptr, byref(interface._iid_), True)
|
|
57
116
|
|
|
58
117
|
|
|
59
|
-
################################################################
|
|
60
|
-
|
|
61
|
-
|
|
62
118
|
def comtypes_get_refcount(ptr):
|
|
63
119
|
"""Helper function for testing: return the COM reference count of
|
|
64
120
|
a comtypes COM object"""
|
|
@@ -66,9 +122,6 @@ def comtypes_get_refcount(ptr):
|
|
|
66
122
|
return ptr.Release()
|
|
67
123
|
|
|
68
124
|
|
|
69
|
-
from comtypes import COMObject
|
|
70
|
-
|
|
71
|
-
|
|
72
125
|
class MyComObject(COMObject):
|
|
73
126
|
"""A completely trivial COM object implementing IDispatch. Calling
|
|
74
127
|
any methods will return the error code E_NOTIMPL (except the
|
|
@@ -77,42 +130,33 @@ class MyComObject(COMObject):
|
|
|
77
130
|
_com_interfaces_ = [IDispatch]
|
|
78
131
|
|
|
79
132
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class Test(unittest.TestCase):
|
|
84
|
-
def tearDown(self):
|
|
85
|
-
if hasattr(self, "ie"):
|
|
86
|
-
self.ie.Quit()
|
|
87
|
-
del self.ie
|
|
88
|
-
|
|
133
|
+
class ConvertComtypesPtrToPythonComObjTest(unittest.TestCase):
|
|
89
134
|
def test_mycomobject(self):
|
|
90
135
|
o = MyComObject()
|
|
91
136
|
p = comtypes2pywin(o, IDispatch)
|
|
92
137
|
disp = win32com.client.Dispatch(p)
|
|
93
138
|
self.assertEqual(repr(disp), "<COMObject <unknown>>")
|
|
94
139
|
|
|
95
|
-
def
|
|
96
|
-
# Convert a comtypes COM interface pointer into a win32com COM
|
|
97
|
-
|
|
98
|
-
ie = self.ie = CreateObject("InternetExplorer.Application")
|
|
140
|
+
def test_refcount(self):
|
|
141
|
+
# Convert a comtypes COM interface pointer into a win32com COM pointer.
|
|
142
|
+
dic = CreateObject("Scripting.Dictionary")
|
|
99
143
|
# The COM refcount of the created object is 1:
|
|
100
|
-
self.assertEqual(comtypes_get_refcount(
|
|
101
|
-
|
|
102
|
-
self.assertEqual(
|
|
144
|
+
self.assertEqual(comtypes_get_refcount(dic), 1)
|
|
145
|
+
dic["foo"] = "bar"
|
|
146
|
+
self.assertEqual(dic.Item("foo"), "bar")
|
|
103
147
|
|
|
104
148
|
# Create a pythoncom PyIDispatch object from it:
|
|
105
|
-
p = comtypes2pywin(
|
|
106
|
-
self.assertEqual(comtypes_get_refcount(
|
|
149
|
+
p = comtypes2pywin(dic, interface=IDispatch)
|
|
150
|
+
self.assertEqual(comtypes_get_refcount(dic), 2)
|
|
107
151
|
|
|
108
152
|
# Make it usable...
|
|
109
153
|
disp = win32com.client.Dispatch(p)
|
|
110
|
-
self.assertEqual(comtypes_get_refcount(
|
|
111
|
-
self.assertEqual(disp.
|
|
154
|
+
self.assertEqual(comtypes_get_refcount(dic), 2)
|
|
155
|
+
self.assertEqual(disp.Item("foo"), "bar")
|
|
112
156
|
|
|
113
157
|
# Cleanup and make sure that the COM refcounts are correct
|
|
114
158
|
del p, disp
|
|
115
|
-
self.assertEqual(comtypes_get_refcount(
|
|
159
|
+
self.assertEqual(comtypes_get_refcount(dic), 1)
|
|
116
160
|
|
|
117
161
|
|
|
118
162
|
if __name__ == "__main__":
|
|
@@ -128,9 +128,9 @@ class CodeGenerator(object):
|
|
|
128
128
|
path = self._make_relative_path(filename, comtypes.gen.__path__[0])
|
|
129
129
|
self.imports.add("os")
|
|
130
130
|
definition = (
|
|
131
|
-
"os.path.normpath(\n"
|
|
132
|
-
" os.path.abspath(os.path.join(os.path.dirname(__file__),\n"
|
|
133
|
-
"
|
|
131
|
+
f"os.path.normpath(\n"
|
|
132
|
+
f" os.path.abspath(os.path.join(os.path.dirname(__file__),\n"
|
|
133
|
+
f" {path!r})))"
|
|
134
134
|
)
|
|
135
135
|
self.declarations.add("typelib_path", definition)
|
|
136
136
|
p = os.path.normpath(
|
|
@@ -293,7 +293,7 @@ class CodeGenerator(object):
|
|
|
293
293
|
indent = " " * depth
|
|
294
294
|
# some chars are replaced to avoid causing a `SyntaxError`
|
|
295
295
|
repled = orig.replace("\\", r"\\").replace('"', r"'")
|
|
296
|
-
return '
|
|
296
|
+
return f'{indent}"""{repled}"""'
|
|
297
297
|
|
|
298
298
|
def ArrayType(self, tp: typedesc.ArrayType) -> None:
|
|
299
299
|
self.generate(get_real_type(tp.typ))
|
|
@@ -347,7 +347,7 @@ class CodeGenerator(object):
|
|
|
347
347
|
self.more.add(struct)
|
|
348
348
|
if head.struct.location:
|
|
349
349
|
self.last_item_class = False
|
|
350
|
-
print("#
|
|
350
|
+
print(f"# {head.struct.location}", file=self.stream)
|
|
351
351
|
basenames = [self._to_type_name(b) for b in head.struct.bases]
|
|
352
352
|
if basenames:
|
|
353
353
|
self.imports.add("comtypes", "GUID")
|
|
@@ -362,7 +362,7 @@ class CodeGenerator(object):
|
|
|
362
362
|
m.name for m in head.struct.members if type(m) is typedesc.Method
|
|
363
363
|
]
|
|
364
364
|
print(
|
|
365
|
-
"class
|
|
365
|
+
f"class {head.struct.name}({', '.join(basenames)}):",
|
|
366
366
|
file=self.stream,
|
|
367
367
|
)
|
|
368
368
|
print(
|
|
@@ -397,7 +397,7 @@ class CodeGenerator(object):
|
|
|
397
397
|
print("assert 0, 'cannot generate code for IUnknown'", file=self.stream)
|
|
398
398
|
print(file=self.stream)
|
|
399
399
|
print(file=self.stream)
|
|
400
|
-
print("class
|
|
400
|
+
print(f"class {head.struct.name}(_com_interface):", file=self.stream)
|
|
401
401
|
print(" pass", file=self.stream)
|
|
402
402
|
print(file=self.stream)
|
|
403
403
|
print(file=self.stream)
|
|
@@ -408,10 +408,10 @@ class CodeGenerator(object):
|
|
|
408
408
|
|
|
409
409
|
self.last_item_class = True
|
|
410
410
|
|
|
411
|
-
print("class
|
|
411
|
+
print(f"class {head.struct.name}(Structure):", file=self.stream)
|
|
412
412
|
if hasattr(head.struct, "_recordinfo_"):
|
|
413
413
|
print(
|
|
414
|
-
" _recordinfo_ =
|
|
414
|
+
f" _recordinfo_ = {head.struct._recordinfo_!r}",
|
|
415
415
|
file=self.stream,
|
|
416
416
|
)
|
|
417
417
|
else:
|
|
@@ -425,7 +425,7 @@ class CodeGenerator(object):
|
|
|
425
425
|
|
|
426
426
|
self.last_item_class = True
|
|
427
427
|
|
|
428
|
-
print("class
|
|
428
|
+
print(f"class {head.struct.name}(Union):", file=self.stream)
|
|
429
429
|
print(" pass", file=self.stream)
|
|
430
430
|
print(file=self.stream)
|
|
431
431
|
print(file=self.stream)
|
|
@@ -462,14 +462,14 @@ class CodeGenerator(object):
|
|
|
462
462
|
pack = packing.calc_packing(body.struct, fields)
|
|
463
463
|
if pack is not None:
|
|
464
464
|
self.last_item_class = False
|
|
465
|
-
print("
|
|
465
|
+
print(f"{body.struct.name}._pack_ = {pack}", file=self.stream)
|
|
466
466
|
except packing.PackingError as details:
|
|
467
467
|
# if packing fails, write a warning comment to the output.
|
|
468
468
|
import warnings
|
|
469
469
|
|
|
470
470
|
message = "Structure %s: %s" % (body.struct.name, details)
|
|
471
471
|
warnings.warn(message, UserWarning)
|
|
472
|
-
print("# WARNING:
|
|
472
|
+
print(f"# WARNING: {details}", file=self.stream)
|
|
473
473
|
self.last_item_class = False
|
|
474
474
|
|
|
475
475
|
if fields:
|
|
@@ -482,9 +482,9 @@ class CodeGenerator(object):
|
|
|
482
482
|
|
|
483
483
|
self.last_item_class = False
|
|
484
484
|
|
|
485
|
-
print("
|
|
485
|
+
print(f"{body.struct.name}._fields_ = [", file=self.stream)
|
|
486
486
|
if body.struct.location:
|
|
487
|
-
print(" #
|
|
487
|
+
print(f" # {body.struct.location}", file=self.stream)
|
|
488
488
|
# unnamed fields will get autogenerated names "_", "_1". "_2", "_3", ...
|
|
489
489
|
unnamed_index = 0
|
|
490
490
|
for f in fields:
|
|
@@ -495,20 +495,19 @@ class CodeGenerator(object):
|
|
|
495
495
|
fieldname = "_"
|
|
496
496
|
unnamed_index += 1
|
|
497
497
|
print(
|
|
498
|
-
" # Unnamed field renamed to '
|
|
498
|
+
f" # Unnamed field renamed to '{fieldname}'",
|
|
499
499
|
file=self.stream,
|
|
500
500
|
)
|
|
501
501
|
else:
|
|
502
502
|
fieldname = f.name
|
|
503
503
|
if f.bits is None:
|
|
504
504
|
print(
|
|
505
|
-
" ('
|
|
505
|
+
f" ('{fieldname}', {self._to_type_name(f.typ)}),",
|
|
506
506
|
file=self.stream,
|
|
507
507
|
)
|
|
508
508
|
else:
|
|
509
509
|
print(
|
|
510
|
-
" ('
|
|
511
|
-
% (fieldname, self._to_type_name(f.typ), f.bits),
|
|
510
|
+
f" ('{fieldname}', {self._to_type_name(f.typ)}, {f.bits}),",
|
|
512
511
|
file=self.stream,
|
|
513
512
|
)
|
|
514
513
|
print("]", file=self.stream)
|
|
@@ -524,14 +523,12 @@ class CodeGenerator(object):
|
|
|
524
523
|
print(file=self.stream)
|
|
525
524
|
size = body.struct.size // 8
|
|
526
525
|
print(
|
|
527
|
-
"assert sizeof(
|
|
528
|
-
% (body.struct.name, size, body.struct.name),
|
|
526
|
+
f"assert sizeof({body.struct.name}) == {size}, sizeof({body.struct.name})",
|
|
529
527
|
file=self.stream,
|
|
530
528
|
)
|
|
531
529
|
align = body.struct.align // 8
|
|
532
530
|
print(
|
|
533
|
-
"assert alignment(
|
|
534
|
-
% (body.struct.name, align, body.struct.name),
|
|
531
|
+
f"assert alignment({body.struct.name}) == {align}, alignment({body.struct.name})",
|
|
535
532
|
file=self.stream,
|
|
536
533
|
)
|
|
537
534
|
|
|
@@ -542,27 +539,24 @@ class CodeGenerator(object):
|
|
|
542
539
|
print(file=self.stream)
|
|
543
540
|
|
|
544
541
|
self.last_item_class = False
|
|
545
|
-
print("
|
|
542
|
+
print(f"{body.struct.name}._methods_ = [", file=self.stream)
|
|
546
543
|
if body.struct.location:
|
|
547
|
-
print("#
|
|
544
|
+
print(f"# {body.struct.location}", file=self.stream)
|
|
548
545
|
|
|
549
546
|
for m in methods:
|
|
550
547
|
if m.location:
|
|
551
|
-
print(" #
|
|
548
|
+
print(f" # {m.location}", file=self.stream)
|
|
552
549
|
print(
|
|
553
550
|
(
|
|
554
|
-
" COMMETHOD(\n"
|
|
555
|
-
" [], \n"
|
|
556
|
-
"
|
|
557
|
-
" '
|
|
558
|
-
)
|
|
559
|
-
% (self._to_type_name(m.returns), m.name),
|
|
551
|
+
f" COMMETHOD(\n"
|
|
552
|
+
f" [], \n"
|
|
553
|
+
f" {self._to_type_name(m.returns)},\n"
|
|
554
|
+
f" '{m.name}',\n"
|
|
555
|
+
),
|
|
560
556
|
file=self.stream,
|
|
561
557
|
)
|
|
562
558
|
for a in m.iterArgTypes():
|
|
563
|
-
print(
|
|
564
|
-
" ([], %s),\n" % self._to_type_name(a), file=self.stream
|
|
565
|
-
)
|
|
559
|
+
print(f" ([], {self._to_type_name(a)}),\n", file=self.stream)
|
|
566
560
|
print(" ),", file=self.stream)
|
|
567
561
|
print("]", file=self.stream)
|
|
568
562
|
|
|
@@ -589,10 +583,10 @@ class CodeGenerator(object):
|
|
|
589
583
|
print(self._to_docstring(lib.doc), file=self.stream)
|
|
590
584
|
|
|
591
585
|
if lib.name:
|
|
592
|
-
print(" name =
|
|
586
|
+
print(f" name = {lib.name!r}", file=self.stream)
|
|
593
587
|
|
|
594
588
|
print(
|
|
595
|
-
" _reg_typelib_ = (
|
|
589
|
+
f" _reg_typelib_ = ({lib.guid!r}, {lib.major!r}, {lib.minor!r})",
|
|
596
590
|
file=self.stream,
|
|
597
591
|
)
|
|
598
592
|
print(file=self.stream)
|
|
@@ -608,7 +602,7 @@ class CodeGenerator(object):
|
|
|
608
602
|
def Constant(self, tp: typedesc.Constant) -> None:
|
|
609
603
|
self.last_item_class = False
|
|
610
604
|
print(
|
|
611
|
-
"
|
|
605
|
+
f"{tp.name} = {tp.value!r} # Constant {self._to_type_name(tp.typ)}",
|
|
612
606
|
file=self.stream,
|
|
613
607
|
)
|
|
614
608
|
self.names.add(tp.name)
|
|
@@ -650,11 +644,11 @@ class CodeGenerator(object):
|
|
|
650
644
|
|
|
651
645
|
self.last_item_class = True
|
|
652
646
|
|
|
653
|
-
print("class
|
|
647
|
+
print(f"class {coclass.name}(CoClass):", file=self.stream)
|
|
654
648
|
if coclass.doc:
|
|
655
649
|
print(self._to_docstring(coclass.doc), file=self.stream)
|
|
656
|
-
print(" _reg_clsid_ = GUID(
|
|
657
|
-
print(" _idlflags_ =
|
|
650
|
+
print(f" _reg_clsid_ = GUID({coclass.clsid!r})", file=self.stream)
|
|
651
|
+
print(f" _idlflags_ = {coclass.idlflags}", file=self.stream)
|
|
658
652
|
if self.filename is not None:
|
|
659
653
|
print(" _typelib_path_ = typelib_path", file=self.stream)
|
|
660
654
|
# X print
|
|
@@ -663,7 +657,7 @@ class CodeGenerator(object):
|
|
|
663
657
|
libid = coclass.tlibattr.guid
|
|
664
658
|
wMajor, wMinor = coclass.tlibattr.wMajorVerNum, coclass.tlibattr.wMinorVerNum
|
|
665
659
|
print(
|
|
666
|
-
" _reg_typelib_ = (
|
|
660
|
+
f" _reg_typelib_ = ({str(libid)!r}, {wMajor}, {wMinor})",
|
|
667
661
|
file=self.stream,
|
|
668
662
|
)
|
|
669
663
|
print(file=self.stream)
|
|
@@ -678,13 +672,13 @@ class CodeGenerator(object):
|
|
|
678
672
|
if implemented:
|
|
679
673
|
self.last_item_class = False
|
|
680
674
|
print(
|
|
681
|
-
"
|
|
675
|
+
f"{coclass.name}._com_interfaces_ = [{', '.join(implemented)}]",
|
|
682
676
|
file=self.stream,
|
|
683
677
|
)
|
|
684
678
|
if sources:
|
|
685
679
|
self.last_item_class = False
|
|
686
680
|
print(
|
|
687
|
-
"
|
|
681
|
+
f"{coclass.name}._outgoing_interfaces_ = [{', '.join(sources)}]",
|
|
688
682
|
file=self.stream,
|
|
689
683
|
)
|
|
690
684
|
|
|
@@ -773,13 +767,13 @@ class CodeGenerator(object):
|
|
|
773
767
|
|
|
774
768
|
self.last_item_class = True
|
|
775
769
|
|
|
776
|
-
print("class
|
|
770
|
+
print(f"class {head.itf.name}({basename}):", file=self.stream)
|
|
777
771
|
if head.itf.doc:
|
|
778
772
|
print(self._to_docstring(head.itf.doc), file=self.stream)
|
|
779
773
|
|
|
780
774
|
print(" _case_insensitive_ = True", file=self.stream)
|
|
781
|
-
print(" _iid_ = GUID(
|
|
782
|
-
print(" _idlflags_ =
|
|
775
|
+
print(f" _iid_ = GUID({head.itf.iid!r})", file=self.stream)
|
|
776
|
+
print(f" _idlflags_ = {head.itf.idlflags}", file=self.stream)
|
|
783
777
|
|
|
784
778
|
if self._is_enuminterface(head.itf):
|
|
785
779
|
print(file=self.stream)
|
|
@@ -826,7 +820,7 @@ class CodeGenerator(object):
|
|
|
826
820
|
print(file=self.stream)
|
|
827
821
|
|
|
828
822
|
self.last_item_class = False
|
|
829
|
-
print("
|
|
823
|
+
print(f"{body.itf.name}._methods_ = [", file=self.stream)
|
|
830
824
|
for m in body.itf.members:
|
|
831
825
|
if isinstance(m, typedesc.ComMethod):
|
|
832
826
|
self.make_ComMethod(m, "dual" in body.itf.idlflags)
|
|
@@ -839,8 +833,8 @@ class CodeGenerator(object):
|
|
|
839
833
|
"################################################################",
|
|
840
834
|
file=self.stream,
|
|
841
835
|
)
|
|
842
|
-
print("# code template for
|
|
843
|
-
print("# class
|
|
836
|
+
print(f"# code template for {body.itf.name} implementation", file=self.stream)
|
|
837
|
+
print(f"# class {body.itf.name}_Impl(object):", file=self.stream)
|
|
844
838
|
|
|
845
839
|
methods = {}
|
|
846
840
|
for m in body.itf.members:
|
|
@@ -862,43 +856,43 @@ class CodeGenerator(object):
|
|
|
862
856
|
for name, (typ, inargs, outargs, doc) in methods.items():
|
|
863
857
|
if typ == 0: # method
|
|
864
858
|
print(
|
|
865
|
-
"# def
|
|
859
|
+
f"# def {name}({', '.join(['self'] + inargs)}):",
|
|
866
860
|
file=self.stream,
|
|
867
861
|
)
|
|
868
|
-
print("#
|
|
869
|
-
print("# #return
|
|
862
|
+
print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
|
|
863
|
+
print(f"# #return {', '.join(outargs)}", file=self.stream)
|
|
870
864
|
elif typ == 1: # propget
|
|
871
865
|
print("# @property", file=self.stream)
|
|
872
866
|
print(
|
|
873
|
-
"# def
|
|
867
|
+
f"# def {name}({', '.join(['self'] + inargs)}):",
|
|
874
868
|
file=self.stream,
|
|
875
869
|
)
|
|
876
|
-
print("#
|
|
877
|
-
print("# #return
|
|
870
|
+
print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
|
|
871
|
+
print(f"# #return {', '.join(outargs)}", file=self.stream)
|
|
878
872
|
elif typ == 2: # propput
|
|
879
873
|
print(
|
|
880
|
-
"# def _set(
|
|
874
|
+
f"# def _set({', '.join(['self'] + inargs + outargs)}):",
|
|
881
875
|
file=self.stream,
|
|
882
876
|
)
|
|
883
|
-
print("#
|
|
877
|
+
print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
|
|
884
878
|
print(
|
|
885
|
-
"#
|
|
879
|
+
f"# {name} = property(fset = _set, doc = _set.__doc__)",
|
|
886
880
|
file=self.stream,
|
|
887
881
|
)
|
|
888
882
|
elif typ == 3: # propget + propput
|
|
889
883
|
print(
|
|
890
|
-
"# def _get(
|
|
884
|
+
f"# def _get({', '.join(['self'] + inargs)}):",
|
|
891
885
|
file=self.stream,
|
|
892
886
|
)
|
|
893
|
-
print("#
|
|
894
|
-
print("# #return
|
|
887
|
+
print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
|
|
888
|
+
print(f"# #return {', '.join(outargs)}", file=self.stream)
|
|
895
889
|
print(
|
|
896
|
-
"# def _set(
|
|
890
|
+
f"# def _set({', '.join(['self'] + inargs + outargs)}):",
|
|
897
891
|
file=self.stream,
|
|
898
892
|
)
|
|
899
|
-
print("#
|
|
893
|
+
print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
|
|
900
894
|
print(
|
|
901
|
-
"#
|
|
895
|
+
f"# {name} = property(_get, _set, doc = _set.__doc__)",
|
|
902
896
|
file=self.stream,
|
|
903
897
|
)
|
|
904
898
|
else:
|
|
@@ -921,12 +915,12 @@ class CodeGenerator(object):
|
|
|
921
915
|
|
|
922
916
|
self.last_item_class = True
|
|
923
917
|
|
|
924
|
-
print("class
|
|
918
|
+
print(f"class {head.itf.name}({basename}):", file=self.stream)
|
|
925
919
|
if head.itf.doc:
|
|
926
920
|
print(self._to_docstring(head.itf.doc), file=self.stream)
|
|
927
921
|
print(" _case_insensitive_ = True", file=self.stream)
|
|
928
|
-
print(" _iid_ = GUID(
|
|
929
|
-
print(" _idlflags_ =
|
|
922
|
+
print(f" _iid_ = GUID({head.itf.iid!r})", file=self.stream)
|
|
923
|
+
print(f" _idlflags_ = {head.itf.idlflags}", file=self.stream)
|
|
930
924
|
print(" _methods_ = []", file=self.stream)
|
|
931
925
|
|
|
932
926
|
annotations = typeannotator.DispInterfaceMembersAnnotator(head.itf).generate()
|
|
@@ -955,7 +949,7 @@ class CodeGenerator(object):
|
|
|
955
949
|
|
|
956
950
|
self.last_item_class = False
|
|
957
951
|
|
|
958
|
-
print("
|
|
952
|
+
print(f"{body.itf.name}._disp_methods_ = [", file=self.stream)
|
|
959
953
|
for m in body.itf.members:
|
|
960
954
|
if isinstance(m, typedesc.DispMethod):
|
|
961
955
|
self.make_DispMethod(m)
|
|
@@ -22,7 +22,7 @@ class dispid(object):
|
|
|
22
22
|
self.memid = memid
|
|
23
23
|
|
|
24
24
|
def __repr__(self):
|
|
25
|
-
return "dispid(
|
|
25
|
+
return f"dispid({self.memid})"
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class helpstring(object):
|
|
@@ -30,7 +30,7 @@ class helpstring(object):
|
|
|
30
30
|
self.text = text
|
|
31
31
|
|
|
32
32
|
def __repr__(self):
|
|
33
|
-
return "helpstring(
|
|
33
|
+
return f"helpstring({self.text!r})"
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
# XXX Should this be in ctypes itself?
|
|
@@ -299,22 +299,22 @@ class TypeNamer(object):
|
|
|
299
299
|
# to refer to the type. Assumes the 'from ctypes import *'
|
|
300
300
|
# namespace is available.
|
|
301
301
|
if isinstance(t, typedesc.SAFEARRAYType):
|
|
302
|
-
return "_midlSAFEARRAY(
|
|
302
|
+
return f"_midlSAFEARRAY({self(t.typ)})"
|
|
303
303
|
# if isinstance(t, typedesc.CoClass):
|
|
304
304
|
# return "%s._com_interfaces_[0]" % t.name
|
|
305
305
|
if isinstance(t, typedesc.Typedef):
|
|
306
306
|
return t.name
|
|
307
307
|
if isinstance(t, typedesc.PointerType):
|
|
308
308
|
_t, pcnt = self._inspect_PointerType(t)
|
|
309
|
-
return "
|
|
309
|
+
return f"{'POINTER(' * pcnt}{self(_t)}{')' * pcnt}"
|
|
310
310
|
elif isinstance(t, typedesc.ArrayType):
|
|
311
|
-
return "
|
|
311
|
+
return f"{self(t.typ)} * {int(t.max) + 1}"
|
|
312
312
|
elif isinstance(t, typedesc.FunctionType):
|
|
313
313
|
args = [self(x) for x in [t.returns] + list(t.iterArgTypes())]
|
|
314
314
|
if "__stdcall__" in t.attributes:
|
|
315
|
-
return "WINFUNCTYPE(
|
|
315
|
+
return f"WINFUNCTYPE({', '.join(args)})"
|
|
316
316
|
else:
|
|
317
|
-
return "CFUNCTYPE(
|
|
317
|
+
return f"CFUNCTYPE({', '.join(args)})"
|
|
318
318
|
elif isinstance(t, typedesc.CvQualifiedType):
|
|
319
319
|
# const and volatile are ignored
|
|
320
320
|
return "%s" % self(t.typ)
|
|
@@ -334,7 +334,7 @@ class TypeNamer(object):
|
|
|
334
334
|
# t.symbol_name - symbol to generate
|
|
335
335
|
# t.tlib - the ITypeLib pointer to the typelibrary containing the symbols definition
|
|
336
336
|
modname = name_wrapper_module(t.tlib)
|
|
337
|
-
return "
|
|
337
|
+
return f"{modname}.{t.symbol_name}"
|
|
338
338
|
return t.name
|
|
339
339
|
|
|
340
340
|
def _inspect_PointerType(
|
|
@@ -25,20 +25,20 @@ def _calc_packing(struct, fields, pack, isStruct):
|
|
|
25
25
|
size += a - size % a
|
|
26
26
|
if isStruct:
|
|
27
27
|
if size != f.offset:
|
|
28
|
-
raise PackingError("field
|
|
28
|
+
raise PackingError(f"field {f.name} offset ({size}/{f.offset})")
|
|
29
29
|
size += s
|
|
30
30
|
else:
|
|
31
31
|
size = max(size, s)
|
|
32
32
|
total_align = max(total_align, a)
|
|
33
33
|
if total_align != struct.align:
|
|
34
|
-
raise PackingError("total alignment (
|
|
34
|
+
raise PackingError(f"total alignment ({total_align}/{struct.align})")
|
|
35
35
|
a = total_align
|
|
36
36
|
if pack is not None:
|
|
37
37
|
a = min(pack, a)
|
|
38
38
|
if size % a:
|
|
39
39
|
size += a - size % a
|
|
40
40
|
if size != struct.size:
|
|
41
|
-
raise PackingError("total size (
|
|
41
|
+
raise PackingError(f"total size ({size}/{struct.size})")
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
def calc_packing(struct, fields):
|
|
@@ -55,7 +55,7 @@ def calc_packing(struct, fields):
|
|
|
55
55
|
|
|
56
56
|
return int(pack / 8)
|
|
57
57
|
|
|
58
|
-
raise PackingError("PACKING FAILED:
|
|
58
|
+
raise PackingError(f"PACKING FAILED: {details}")
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
class PackingError(Exception):
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import abc
|
|
2
2
|
import keyword
|
|
3
|
-
from typing import Any, Generic,
|
|
3
|
+
from typing import Any, Generic, Protocol, TypeVar
|
|
4
4
|
from typing import Dict, List, Optional, Sequence, Tuple
|
|
5
5
|
from typing import Iterable, Iterator
|
|
6
6
|
|
|
7
7
|
from comtypes.tools import typedesc
|
|
8
8
|
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from comtypes import hints
|
|
11
9
|
|
|
10
|
+
class _MethodTypeDesc(Protocol):
|
|
11
|
+
arguments: List[Tuple[Any, str, List[str], Optional[Any]]]
|
|
12
|
+
idlflags: List[str]
|
|
13
|
+
name: str
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
else:
|
|
16
|
-
_T_MTD = TypeVar("_T_MTD")
|
|
15
|
+
|
|
16
|
+
_T_MTD = TypeVar("_T_MTD", bound=_MethodTypeDesc)
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class _MethodAnnotator(abc.ABC, Generic[_T_MTD]):
|