comtypes 1.4.2__zip → 1.4.3__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.2 → comtypes-1.4.3}/CHANGES.txt +16 -2
- {comtypes-1.4.2/comtypes.egg-info → comtypes-1.4.3}/PKG-INFO +29 -1
- {comtypes-1.4.2 → comtypes-1.4.3}/README.md +28 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/__init__.py +6 -8
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/automation.py +26 -2
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/hints.pyi +15 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_GUID.py +23 -2
- comtypes-1.4.3/comtypes/test/test_dispifc_records.py +90 -0
- comtypes-1.4.3/comtypes/test/test_findgendir.py +87 -0
- comtypes-1.4.3/comtypes/tools/codegenerator/__init__.py +5 -0
- {comtypes-1.4.2/comtypes/tools → comtypes-1.4.3/comtypes/tools/codegenerator}/codegenerator.py +56 -721
- comtypes-1.4.3/comtypes/tools/codegenerator/helpers.py +357 -0
- comtypes-1.4.3/comtypes/tools/codegenerator/modulenamer.py +24 -0
- comtypes-1.4.3/comtypes/tools/codegenerator/namespaces.py +212 -0
- comtypes-1.4.3/comtypes/tools/codegenerator/packing.py +81 -0
- {comtypes-1.4.2/comtypes/tools → comtypes-1.4.3/comtypes/tools/codegenerator}/typeannotator.py +18 -3
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/tlbparser.py +19 -49
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/typedesc.py +57 -9
- {comtypes-1.4.2 → comtypes-1.4.3/comtypes.egg-info}/PKG-INFO +29 -1
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/SOURCES.txt +9 -3
- {comtypes-1.4.2 → comtypes-1.4.3}/setup.py +1 -0
- comtypes-1.4.2/comtypes/test/test_findgendir.py +0 -94
- {comtypes-1.4.2 → comtypes-1.4.3}/LICENSE.txt +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/MANIFEST.in +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/GUID.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_comobject.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_memberspec.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_meta.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_npsupport.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_safearray.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/clear_cache.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/__init__.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_code_cache.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_constants.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_events.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_generate.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/lazybind.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/connectionpoints.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/errorinfo.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/git.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/hresult.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/logutil.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/messageloop.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/patcher.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/persist.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/safearray.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/__init__.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/automation.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/connectionpoints.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/inprocserver.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/localserver.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/register.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/w_getopt.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/shelllink.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestComServer.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestDispServer.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/__init__.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/find_memleak.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/runtests.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/setup.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_BSTR.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_agilent.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_avmc.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_basic.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_casesensitivity.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_clear_cache.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_client.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_client_dynamic.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_client_regenerate_modules.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_collections.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_comserver.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_createwrappers.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_dispinterface.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_dyndispatch.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_excel.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_ie.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_ienum.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_imfattributes.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_inout_args.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_npsupport.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_outparam.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_propputref.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_safearray.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_server.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_showevents.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_typeinfo.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_urlhistory.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_variant.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_win32com_interop.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_wmi.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_word.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/typedesc_base.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/typeinfo.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/util.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/viewobject.py +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.4.2 → comtypes-1.4.3}/setup.cfg +0 -0
{comtypes-1.4.2/comtypes/tools → comtypes-1.4.3/comtypes/tools/codegenerator}/codegenerator.py
RENAMED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
# Code generator to generate code for everything contained in COM type
|
|
2
2
|
# libraries.
|
|
3
|
-
from __future__ import print_function
|
|
4
|
-
import ctypes
|
|
5
3
|
import keyword
|
|
6
4
|
import logging
|
|
7
5
|
import os
|
|
8
|
-
import sys
|
|
9
6
|
import textwrap
|
|
10
|
-
from typing import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
List,
|
|
15
|
-
Optional,
|
|
16
|
-
Sequence,
|
|
17
|
-
Set,
|
|
18
|
-
Tuple,
|
|
19
|
-
Union as _UnionT,
|
|
20
|
-
)
|
|
7
|
+
from typing import Any
|
|
8
|
+
from typing import Dict, List, Tuple
|
|
9
|
+
from typing import Sequence
|
|
10
|
+
from typing import Optional, Union as _UnionT
|
|
21
11
|
import io
|
|
22
12
|
|
|
23
13
|
import comtypes
|
|
24
14
|
from comtypes import typeinfo
|
|
25
|
-
from comtypes.tools import tlbparser, typedesc
|
|
15
|
+
from comtypes.tools import tlbparser, typedesc
|
|
16
|
+
from comtypes.tools.codegenerator import namespaces
|
|
17
|
+
from comtypes.tools.codegenerator import packing
|
|
18
|
+
from comtypes.tools.codegenerator.modulenamer import name_wrapper_module
|
|
19
|
+
from comtypes.tools.codegenerator.helpers import (
|
|
20
|
+
get_real_type,
|
|
21
|
+
ASSUME_STRINGS,
|
|
22
|
+
ComMethodGenerator,
|
|
23
|
+
DispMethodGenerator,
|
|
24
|
+
DispPropertyGenerator,
|
|
25
|
+
TypeNamer,
|
|
26
|
+
)
|
|
27
|
+
from comtypes.tools.codegenerator import typeannotator
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
version = comtypes.__version__
|
|
@@ -32,395 +34,6 @@ logger = logging.getLogger(__name__)
|
|
|
32
34
|
__warn_on_munge__ = __debug__
|
|
33
35
|
|
|
34
36
|
|
|
35
|
-
class lcid(object):
|
|
36
|
-
def __repr__(self):
|
|
37
|
-
return "_lcid"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
lcid = lcid()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class dispid(object):
|
|
44
|
-
def __init__(self, memid):
|
|
45
|
-
self.memid = memid
|
|
46
|
-
|
|
47
|
-
def __repr__(self):
|
|
48
|
-
return "dispid(%s)" % self.memid
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class helpstring(object):
|
|
52
|
-
def __init__(self, text):
|
|
53
|
-
self.text = text
|
|
54
|
-
|
|
55
|
-
def __repr__(self):
|
|
56
|
-
return "helpstring(%r)" % self.text
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# XXX Should this be in ctypes itself?
|
|
60
|
-
ctypes_names = {
|
|
61
|
-
"unsigned char": "c_ubyte",
|
|
62
|
-
"signed char": "c_byte",
|
|
63
|
-
"char": "c_char",
|
|
64
|
-
"wchar_t": "c_wchar",
|
|
65
|
-
"short unsigned int": "c_ushort",
|
|
66
|
-
"short int": "c_short",
|
|
67
|
-
"long unsigned int": "c_ulong",
|
|
68
|
-
"long int": "c_long",
|
|
69
|
-
"long signed int": "c_long",
|
|
70
|
-
"unsigned int": "c_uint",
|
|
71
|
-
"int": "c_int",
|
|
72
|
-
"long long unsigned int": "c_ulonglong",
|
|
73
|
-
"long long int": "c_longlong",
|
|
74
|
-
"double": "c_double",
|
|
75
|
-
"float": "c_float",
|
|
76
|
-
# Hm...
|
|
77
|
-
"void": "None",
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def get_real_type(tp):
|
|
82
|
-
if type(tp) is typedesc.Typedef:
|
|
83
|
-
return get_real_type(tp.typ)
|
|
84
|
-
elif isinstance(tp, typedesc.CvQualifiedType):
|
|
85
|
-
return get_real_type(tp.typ)
|
|
86
|
-
return tp
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
ASSUME_STRINGS = True
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
def _calc_packing(struct, fields, pack, isStruct):
|
|
93
|
-
# Try a certain packing, raise PackingError if field offsets,
|
|
94
|
-
# total size ot total alignment is wrong.
|
|
95
|
-
if struct.size is None: # incomplete struct
|
|
96
|
-
return -1
|
|
97
|
-
if struct.name in dont_assert_size:
|
|
98
|
-
return None
|
|
99
|
-
if struct.bases:
|
|
100
|
-
size = struct.bases[0].size
|
|
101
|
-
total_align = struct.bases[0].align
|
|
102
|
-
else:
|
|
103
|
-
size = 0
|
|
104
|
-
total_align = 8 # in bits
|
|
105
|
-
for i, f in enumerate(fields):
|
|
106
|
-
if f.bits: # this code cannot handle bit field sizes.
|
|
107
|
-
# print "##XXX FIXME"
|
|
108
|
-
return -2 # XXX FIXME
|
|
109
|
-
s, a = storage(f.typ)
|
|
110
|
-
if pack is not None:
|
|
111
|
-
a = min(pack, a)
|
|
112
|
-
if size % a:
|
|
113
|
-
size += a - size % a
|
|
114
|
-
if isStruct:
|
|
115
|
-
if size != f.offset:
|
|
116
|
-
raise PackingError("field %s offset (%s/%s)" % (f.name, size, f.offset))
|
|
117
|
-
size += s
|
|
118
|
-
else:
|
|
119
|
-
size = max(size, s)
|
|
120
|
-
total_align = max(total_align, a)
|
|
121
|
-
if total_align != struct.align:
|
|
122
|
-
raise PackingError("total alignment (%s/%s)" % (total_align, struct.align))
|
|
123
|
-
a = total_align
|
|
124
|
-
if pack is not None:
|
|
125
|
-
a = min(pack, a)
|
|
126
|
-
if size % a:
|
|
127
|
-
size += a - size % a
|
|
128
|
-
if size != struct.size:
|
|
129
|
-
raise PackingError("total size (%s/%s)" % (size, struct.size))
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def calc_packing(struct, fields):
|
|
133
|
-
# try several packings, starting with unspecified packing
|
|
134
|
-
isStruct = isinstance(struct, typedesc.Structure)
|
|
135
|
-
for pack in [None, 16 * 8, 8 * 8, 4 * 8, 2 * 8, 1 * 8]:
|
|
136
|
-
try:
|
|
137
|
-
_calc_packing(struct, fields, pack, isStruct)
|
|
138
|
-
except PackingError as details:
|
|
139
|
-
continue
|
|
140
|
-
else:
|
|
141
|
-
if pack is None:
|
|
142
|
-
return None
|
|
143
|
-
|
|
144
|
-
return int(pack / 8)
|
|
145
|
-
|
|
146
|
-
raise PackingError("PACKING FAILED: %s" % details)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
class PackingError(Exception):
|
|
150
|
-
pass
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
# XXX These should be filtered out in gccxmlparser.
|
|
154
|
-
dont_assert_size = set(
|
|
155
|
-
[
|
|
156
|
-
"__si_class_type_info_pseudo",
|
|
157
|
-
"__class_type_info_pseudo",
|
|
158
|
-
]
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def storage(t):
|
|
163
|
-
# return the size and alignment of a type
|
|
164
|
-
if isinstance(t, typedesc.Typedef):
|
|
165
|
-
return storage(t.typ)
|
|
166
|
-
elif isinstance(t, typedesc.ArrayType):
|
|
167
|
-
s, a = storage(t.typ)
|
|
168
|
-
return s * (int(t.max) - int(t.min) + 1), a
|
|
169
|
-
return int(t.size), int(t.align)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
################################################################
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def name_wrapper_module(tlib):
|
|
176
|
-
"""Determine the name of a typelib wrapper module"""
|
|
177
|
-
libattr = tlib.GetLibAttr()
|
|
178
|
-
modname = "_%s_%s_%s_%s" % (
|
|
179
|
-
str(libattr.guid)[1:-1].replace("-", "_"),
|
|
180
|
-
libattr.lcid,
|
|
181
|
-
libattr.wMajorVerNum,
|
|
182
|
-
libattr.wMinorVerNum,
|
|
183
|
-
)
|
|
184
|
-
return "comtypes.gen.%s" % modname
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def name_friendly_module(tlib):
|
|
188
|
-
"""Determine the friendly-name of a typelib module.
|
|
189
|
-
If cannot get friendly-name from typelib, returns `None`.
|
|
190
|
-
"""
|
|
191
|
-
try:
|
|
192
|
-
modulename = tlib.GetDocumentation(-1)[0]
|
|
193
|
-
except comtypes.COMError:
|
|
194
|
-
return
|
|
195
|
-
return "comtypes.gen.%s" % modulename
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
################################################################
|
|
199
|
-
|
|
200
|
-
_DefValType = _UnionT["lcid", Any, None]
|
|
201
|
-
_IdlFlagType = _UnionT[str, dispid, helpstring]
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def _to_arg_definition(
|
|
205
|
-
type_name: str,
|
|
206
|
-
arg_name: str,
|
|
207
|
-
idlflags: List[str],
|
|
208
|
-
default: _DefValType,
|
|
209
|
-
) -> str:
|
|
210
|
-
if default is not None:
|
|
211
|
-
code = f" ({idlflags!r}, {type_name}, '{arg_name}', {default!r})"
|
|
212
|
-
if len(code) > 80:
|
|
213
|
-
code = (
|
|
214
|
-
" (\n"
|
|
215
|
-
f" {idlflags!r},\n"
|
|
216
|
-
f" {type_name},\n"
|
|
217
|
-
f" '{arg_name}',\n"
|
|
218
|
-
f" {default!r}\n"
|
|
219
|
-
" )"
|
|
220
|
-
)
|
|
221
|
-
else:
|
|
222
|
-
code = f" ({idlflags!r}, {type_name}, '{arg_name}')"
|
|
223
|
-
if len(code) > 80:
|
|
224
|
-
code = (
|
|
225
|
-
" (\n"
|
|
226
|
-
f" {idlflags!r},\n"
|
|
227
|
-
f" {type_name},\n"
|
|
228
|
-
f" '{arg_name}',\n"
|
|
229
|
-
" )"
|
|
230
|
-
)
|
|
231
|
-
return code
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
class ComMethodGenerator(object):
|
|
235
|
-
def __init__(self, m: typedesc.ComMethod, isdual: bool) -> None:
|
|
236
|
-
self._m = m
|
|
237
|
-
self._isdual = isdual
|
|
238
|
-
self.data: List[str] = []
|
|
239
|
-
self._to_type_name = TypeNamer()
|
|
240
|
-
|
|
241
|
-
def generate(self) -> str:
|
|
242
|
-
if not self._m.arguments:
|
|
243
|
-
self._make_noargs()
|
|
244
|
-
else:
|
|
245
|
-
self._make_withargs()
|
|
246
|
-
return "\n".join(self.data)
|
|
247
|
-
|
|
248
|
-
def _get_common_elms(self) -> Tuple[List[_IdlFlagType], str, str]:
|
|
249
|
-
idlflags: List[_IdlFlagType] = []
|
|
250
|
-
if self._isdual:
|
|
251
|
-
idlflags.append(dispid(self._m.memid))
|
|
252
|
-
idlflags.extend(self._m.idlflags)
|
|
253
|
-
else: # We don't include the dispid for non-dispatch COM interfaces
|
|
254
|
-
idlflags.extend(self._m.idlflags)
|
|
255
|
-
if __debug__ and self._m.doc:
|
|
256
|
-
idlflags.insert(1, helpstring(self._m.doc))
|
|
257
|
-
type_name = self._to_type_name(self._m.returns)
|
|
258
|
-
return (idlflags, type_name, self._m.name)
|
|
259
|
-
|
|
260
|
-
def _make_noargs(self) -> None:
|
|
261
|
-
flags, type_name, member_name = self._get_common_elms()
|
|
262
|
-
code = f" COMMETHOD({flags!r}, {type_name}, '{member_name}'),"
|
|
263
|
-
if len(code) > 80:
|
|
264
|
-
code = (
|
|
265
|
-
" COMMETHOD(\n"
|
|
266
|
-
f" {flags!r},\n"
|
|
267
|
-
f" {type_name},\n"
|
|
268
|
-
f" '{member_name}',\n"
|
|
269
|
-
" ),"
|
|
270
|
-
)
|
|
271
|
-
self.data.append(code)
|
|
272
|
-
|
|
273
|
-
def _make_withargs(self) -> None:
|
|
274
|
-
flags, type_name, member_name = self._get_common_elms()
|
|
275
|
-
code = (
|
|
276
|
-
" COMMETHOD(\n"
|
|
277
|
-
f" {flags!r},\n"
|
|
278
|
-
f" {type_name},\n"
|
|
279
|
-
f" '{member_name}',"
|
|
280
|
-
)
|
|
281
|
-
self.data.append(code)
|
|
282
|
-
arglist = [_to_arg_definition(*i) for i in self._iter_args()]
|
|
283
|
-
self.data.append(",\n".join(arglist))
|
|
284
|
-
self.data.append(" ),")
|
|
285
|
-
|
|
286
|
-
def _iter_args(self) -> Iterator[Tuple[str, str, List[str], _DefValType]]:
|
|
287
|
-
for typ, arg_name, _f, _defval in self._m.arguments:
|
|
288
|
-
###########################################################
|
|
289
|
-
# IDL files that contain 'open arrays' or 'conformant
|
|
290
|
-
# varying arrays' method parameters are strange.
|
|
291
|
-
# These arrays have both a 'size_is()' and
|
|
292
|
-
# 'length_is()' attribute, like this example from
|
|
293
|
-
# dia2.idl (in the DIA SDK):
|
|
294
|
-
#
|
|
295
|
-
# interface IDiaSymbol: IUnknown {
|
|
296
|
-
# ...
|
|
297
|
-
# HRESULT get_dataBytes(
|
|
298
|
-
# [in] DWORD cbData,
|
|
299
|
-
# [out] DWORD *pcbData,
|
|
300
|
-
# [out, size_is(cbData),
|
|
301
|
-
# length_is(*pcbData)] BYTE data[]
|
|
302
|
-
# );
|
|
303
|
-
#
|
|
304
|
-
# The really strange thing is that the decompiled type
|
|
305
|
-
# library then contains this declaration, which declares
|
|
306
|
-
# the interface itself as [out] method parameter:
|
|
307
|
-
#
|
|
308
|
-
# interface IDiaSymbol: IUnknown {
|
|
309
|
-
# ...
|
|
310
|
-
# HRESULT _stdcall get_dataBytes(
|
|
311
|
-
# [in] unsigned long cbData,
|
|
312
|
-
# [out] unsigned long* pcbData,
|
|
313
|
-
# [out] IDiaSymbol data);
|
|
314
|
-
#
|
|
315
|
-
# Of course, comtypes does not accept a COM interface
|
|
316
|
-
# as method parameter; so replace the parameter type
|
|
317
|
-
# with the comtypes spelling of 'unsigned char *', and
|
|
318
|
-
# mark the parameter as [in, out], so the IDL
|
|
319
|
-
# equivalent would be like this:
|
|
320
|
-
#
|
|
321
|
-
# interface IDiaSymbol: IUnknown {
|
|
322
|
-
# ...
|
|
323
|
-
# HRESULT _stdcall get_dataBytes(
|
|
324
|
-
# [in] unsigned long cbData,
|
|
325
|
-
# [out] unsigned long* pcbData,
|
|
326
|
-
# [in, out] BYTE data[]);
|
|
327
|
-
###########################################################
|
|
328
|
-
idlflags = list(_f) # shallow copy to avoid side effects
|
|
329
|
-
if isinstance(typ, typedesc.ComInterface):
|
|
330
|
-
type_name = "OPENARRAY"
|
|
331
|
-
if "in" not in idlflags:
|
|
332
|
-
idlflags.append("in")
|
|
333
|
-
else:
|
|
334
|
-
type_name = self._to_type_name(typ)
|
|
335
|
-
if "lcid" in idlflags: # and 'in' in idlflags:
|
|
336
|
-
default = lcid
|
|
337
|
-
else:
|
|
338
|
-
default = _defval
|
|
339
|
-
yield (type_name, arg_name, idlflags, default)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
class DispMethodGenerator(object):
|
|
343
|
-
def __init__(self, m: typedesc.DispMethod) -> None:
|
|
344
|
-
self._m = m
|
|
345
|
-
self.data: List[str] = []
|
|
346
|
-
self._to_type_name = TypeNamer()
|
|
347
|
-
|
|
348
|
-
def generate(self) -> str:
|
|
349
|
-
if not self._m.arguments:
|
|
350
|
-
self._make_noargs()
|
|
351
|
-
else:
|
|
352
|
-
self._make_withargs()
|
|
353
|
-
return "\n".join(self.data)
|
|
354
|
-
|
|
355
|
-
def _get_common_elms(self) -> Tuple[List[_IdlFlagType], str, str]:
|
|
356
|
-
idlflags: List[_IdlFlagType] = []
|
|
357
|
-
idlflags.append(dispid(self._m.dispid))
|
|
358
|
-
idlflags.extend(self._m.idlflags)
|
|
359
|
-
if __debug__ and self._m.doc:
|
|
360
|
-
idlflags.insert(1, helpstring(self._m.doc))
|
|
361
|
-
type_name = self._to_type_name(self._m.returns)
|
|
362
|
-
return (idlflags, type_name, self._m.name)
|
|
363
|
-
|
|
364
|
-
def _make_noargs(self) -> None:
|
|
365
|
-
flags, type_name, member_name = self._get_common_elms()
|
|
366
|
-
code = f" DISPMETHOD({flags!r}, {type_name}, '{member_name}'),"
|
|
367
|
-
if len(code) > 80:
|
|
368
|
-
code = (
|
|
369
|
-
" DISPMETHOD(\n"
|
|
370
|
-
f" {flags!r},\n"
|
|
371
|
-
f" {type_name},\n"
|
|
372
|
-
f" '{member_name}',\n"
|
|
373
|
-
" ),"
|
|
374
|
-
)
|
|
375
|
-
self.data.append(code)
|
|
376
|
-
|
|
377
|
-
def _make_withargs(self) -> None:
|
|
378
|
-
flags, type_name, member_name = self._get_common_elms()
|
|
379
|
-
code = (
|
|
380
|
-
" DISPMETHOD(\n"
|
|
381
|
-
f" {flags!r},\n"
|
|
382
|
-
f" {type_name},\n"
|
|
383
|
-
f" '{member_name}',"
|
|
384
|
-
)
|
|
385
|
-
self.data.append(code)
|
|
386
|
-
arglist = [_to_arg_definition(*i) for i in self._iter_args()]
|
|
387
|
-
self.data.append(",\n".join(arglist))
|
|
388
|
-
self.data.append(" ),")
|
|
389
|
-
|
|
390
|
-
def _iter_args(self) -> Iterator[Tuple[str, str, List[str], _DefValType]]:
|
|
391
|
-
for typ, arg_name, idlflags, default in self._m.arguments:
|
|
392
|
-
type_name = self._to_type_name(typ)
|
|
393
|
-
yield (type_name, arg_name, idlflags, default)
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
class DispPropertyGenerator(object):
|
|
397
|
-
def __init__(self, m: typedesc.DispProperty) -> None:
|
|
398
|
-
self._m = m
|
|
399
|
-
self._to_type_name = TypeNamer()
|
|
400
|
-
|
|
401
|
-
def generate(self) -> str:
|
|
402
|
-
flags, type_name, member_name = self._get_common_elms()
|
|
403
|
-
code = f" DISPPROPERTY({flags!r}, {type_name}, '{member_name}'),"
|
|
404
|
-
if len(code) > 80:
|
|
405
|
-
code = (
|
|
406
|
-
" DISPPROPERTY(\n"
|
|
407
|
-
f" {flags!r},\n"
|
|
408
|
-
f" {type_name},\n"
|
|
409
|
-
f" '{member_name}'\n"
|
|
410
|
-
" ),"
|
|
411
|
-
)
|
|
412
|
-
return code
|
|
413
|
-
|
|
414
|
-
def _get_common_elms(self) -> Tuple[List[_IdlFlagType], str, str]:
|
|
415
|
-
idlflags: List[_IdlFlagType] = []
|
|
416
|
-
idlflags.append(dispid(self._m.dispid))
|
|
417
|
-
idlflags.extend(self._m.idlflags)
|
|
418
|
-
if __debug__ and self._m.doc:
|
|
419
|
-
idlflags.insert(1, helpstring(self._m.doc))
|
|
420
|
-
type_name = self._to_type_name(self._m.typ)
|
|
421
|
-
return (idlflags, type_name, self._m.name)
|
|
422
|
-
|
|
423
|
-
|
|
424
37
|
_InterfaceTypeDesc = _UnionT[
|
|
425
38
|
typedesc.ComInterface,
|
|
426
39
|
typedesc.ComInterfaceHead,
|
|
@@ -434,9 +47,9 @@ _InterfaceTypeDesc = _UnionT[
|
|
|
434
47
|
class CodeGenerator(object):
|
|
435
48
|
def __init__(self, known_symbols=None, known_interfaces=None) -> None:
|
|
436
49
|
self.stream = io.StringIO()
|
|
437
|
-
self.imports = ImportedNamespaces()
|
|
438
|
-
self.declarations = DeclaredNamespaces()
|
|
439
|
-
self.enums = EnumerationNamespaces()
|
|
50
|
+
self.imports = namespaces.ImportedNamespaces()
|
|
51
|
+
self.declarations = namespaces.DeclaredNamespaces()
|
|
52
|
+
self.enums = namespaces.EnumerationNamespaces()
|
|
440
53
|
self.unnamed_enum_members: List[Tuple[str, int]] = []
|
|
441
54
|
self._to_type_name = TypeNamer()
|
|
442
55
|
self.known_symbols = known_symbols or {}
|
|
@@ -445,7 +58,7 @@ class CodeGenerator(object):
|
|
|
445
58
|
self.done = set() # type descriptions that have been generated
|
|
446
59
|
self.names = set() # names that have been generated
|
|
447
60
|
self.externals = [] # typelibs imported to generated module
|
|
448
|
-
self.
|
|
61
|
+
self.enum_aliases: Dict[str, str] = {}
|
|
449
62
|
self.last_item_class = False
|
|
450
63
|
|
|
451
64
|
def generate(self, item):
|
|
@@ -594,7 +207,14 @@ class CodeGenerator(object):
|
|
|
594
207
|
for n, v in self.unnamed_enum_members:
|
|
595
208
|
print(f"{n} = {v}", file=output)
|
|
596
209
|
print(file=output)
|
|
597
|
-
|
|
210
|
+
if self.enums:
|
|
211
|
+
print(self.enums.to_constants(), file=output)
|
|
212
|
+
print(file=output)
|
|
213
|
+
if self.enum_aliases:
|
|
214
|
+
print("# aliases for enums", file=output)
|
|
215
|
+
for k, v in self.enum_aliases.items():
|
|
216
|
+
print(f"{k} = {v}", file=output)
|
|
217
|
+
print(file=output)
|
|
598
218
|
print(self.stream.getvalue(), file=output)
|
|
599
219
|
print(self._make_dunder_all_part(), file=output)
|
|
600
220
|
print(file=output)
|
|
@@ -619,12 +239,12 @@ class CodeGenerator(object):
|
|
|
619
239
|
print(self._make_friendly_module_import_part(modname), file=output)
|
|
620
240
|
print(file=output)
|
|
621
241
|
print(file=output)
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
if enum_aliases:
|
|
627
|
-
for k, v in enum_aliases.items():
|
|
242
|
+
if self.enums:
|
|
243
|
+
print(self.enums.to_intflags(), file=output)
|
|
244
|
+
print(file=output)
|
|
245
|
+
print(file=output)
|
|
246
|
+
if self.enum_aliases:
|
|
247
|
+
for k, v in self.enum_aliases.items():
|
|
628
248
|
print(f"{k} = {v}", file=output)
|
|
629
249
|
print(file=output)
|
|
630
250
|
print(file=output)
|
|
@@ -662,10 +282,6 @@ class CodeGenerator(object):
|
|
|
662
282
|
part = f"from {modname} import (\n{joined_names}\n)"
|
|
663
283
|
return part
|
|
664
284
|
|
|
665
|
-
@property
|
|
666
|
-
def enum_aliases(self) -> Dict[str, str]:
|
|
667
|
-
return {k: v for k, v in self.aliases.items() if v in self.enums}
|
|
668
|
-
|
|
669
285
|
def need_VARIANT_imports(self, value):
|
|
670
286
|
text = repr(value)
|
|
671
287
|
if "Decimal(" in text:
|
|
@@ -690,7 +306,7 @@ class CodeGenerator(object):
|
|
|
690
306
|
if keyword.iskeyword(tp.name):
|
|
691
307
|
# XXX use logging!
|
|
692
308
|
if __warn_on_munge__:
|
|
693
|
-
print("# Fixing keyword as EnumValue for
|
|
309
|
+
print(f"# Fixing keyword as EnumValue for {tp.name}")
|
|
694
310
|
tp_name = self._to_type_name(tp)
|
|
695
311
|
if tp.enumeration.name:
|
|
696
312
|
self.enums.add(tp.enumeration.name, tp_name, value)
|
|
@@ -716,9 +332,11 @@ class CodeGenerator(object):
|
|
|
716
332
|
if definition in self.known_symbols:
|
|
717
333
|
self.declarations.add(tp.name, definition)
|
|
718
334
|
else:
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
335
|
+
if isinstance(tp.typ, typedesc.Enumeration):
|
|
336
|
+
self.enum_aliases[tp.name] = definition
|
|
337
|
+
else:
|
|
338
|
+
print(f"{tp.name} = {definition}", file=self.stream)
|
|
339
|
+
self.last_item_class = False
|
|
722
340
|
self.names.add(tp.name)
|
|
723
341
|
|
|
724
342
|
def FundamentalType(self, item: typedesc.FundamentalType) -> None:
|
|
@@ -842,11 +460,11 @@ class CodeGenerator(object):
|
|
|
842
460
|
# on COM interfaces:
|
|
843
461
|
if not methods:
|
|
844
462
|
try:
|
|
845
|
-
pack = calc_packing(body.struct, fields)
|
|
463
|
+
pack = packing.calc_packing(body.struct, fields)
|
|
846
464
|
if pack is not None:
|
|
847
465
|
self.last_item_class = False
|
|
848
466
|
print("%s._pack_ = %s" % (body.struct.name, pack), file=self.stream)
|
|
849
|
-
except PackingError as details:
|
|
467
|
+
except packing.PackingError as details:
|
|
850
468
|
# if packing fails, write a warning comment to the output.
|
|
851
469
|
import warnings
|
|
852
470
|
|
|
@@ -903,7 +521,7 @@ class CodeGenerator(object):
|
|
|
903
521
|
"# The size and alignment check for %s is skipped."
|
|
904
522
|
)
|
|
905
523
|
print(msg % body.struct.name, file=self.stream)
|
|
906
|
-
elif body.struct.name not in dont_assert_size:
|
|
524
|
+
elif body.struct.name not in packing.dont_assert_size:
|
|
907
525
|
print(file=self.stream)
|
|
908
526
|
size = body.struct.size // 8
|
|
909
527
|
print(
|
|
@@ -1034,14 +652,14 @@ class CodeGenerator(object):
|
|
|
1034
652
|
self.last_item_class = True
|
|
1035
653
|
|
|
1036
654
|
print("class %s(CoClass):" % coclass.name, file=self.stream)
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
print(self._to_docstring(doc), file=self.stream)
|
|
655
|
+
if coclass.doc:
|
|
656
|
+
print(self._to_docstring(coclass.doc), file=self.stream)
|
|
1040
657
|
print(" _reg_clsid_ = GUID(%r)" % coclass.clsid, file=self.stream)
|
|
1041
658
|
print(" _idlflags_ = %s" % coclass.idlflags, file=self.stream)
|
|
1042
659
|
if self.filename is not None:
|
|
1043
660
|
print(" _typelib_path_ = typelib_path", file=self.stream)
|
|
1044
|
-
# X print
|
|
661
|
+
# X print
|
|
662
|
+
# >> self.stream, "POINTER(%s).__ctypes_from_outparam__ = wrap" % coclass.name
|
|
1045
663
|
|
|
1046
664
|
libid = coclass.tlibattr.guid
|
|
1047
665
|
wMajor, wMinor = coclass.tlibattr.wMajorVerNum, coclass.tlibattr.wMinorVerNum
|
|
@@ -1052,23 +670,11 @@ class CodeGenerator(object):
|
|
|
1052
670
|
print(file=self.stream)
|
|
1053
671
|
print(file=self.stream)
|
|
1054
672
|
|
|
1055
|
-
for itf,
|
|
673
|
+
for itf, _ in coclass.interfaces:
|
|
1056
674
|
self.generate(itf.get_head())
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
for
|
|
1060
|
-
# item is (interface class, impltypeflags)
|
|
1061
|
-
if item[1] & 2: # IMPLTYPEFLAG_FSOURCE
|
|
1062
|
-
# source interface
|
|
1063
|
-
where = sources
|
|
1064
|
-
else:
|
|
1065
|
-
# sink interface
|
|
1066
|
-
where = implemented
|
|
1067
|
-
if item[1] & 1: # IMPLTYPEFLAG_FDEAULT
|
|
1068
|
-
# The default interface should be the first item on the list
|
|
1069
|
-
where.insert(0, self._to_type_name(item[0]))
|
|
1070
|
-
else:
|
|
1071
|
-
where.append(self._to_type_name(item[0]))
|
|
675
|
+
impl, src = typedesc.groupby_impltypeflags(coclass.interfaces)
|
|
676
|
+
implemented = [self._to_type_name(itf) for itf in impl]
|
|
677
|
+
sources = [self._to_type_name(itf) for itf in src]
|
|
1072
678
|
|
|
1073
679
|
if implemented:
|
|
1074
680
|
self.last_item_class = False
|
|
@@ -1169,9 +775,8 @@ class CodeGenerator(object):
|
|
|
1169
775
|
self.last_item_class = True
|
|
1170
776
|
|
|
1171
777
|
print("class %s(%s):" % (head.itf.name, basename), file=self.stream)
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
print(self._to_docstring(doc), file=self.stream)
|
|
778
|
+
if head.itf.doc:
|
|
779
|
+
print(self._to_docstring(head.itf.doc), file=self.stream)
|
|
1175
780
|
|
|
1176
781
|
print(" _case_insensitive_ = True", file=self.stream)
|
|
1177
782
|
print(" _iid_ = GUID(%r)" % head.itf.iid, file=self.stream)
|
|
@@ -1318,9 +923,8 @@ class CodeGenerator(object):
|
|
|
1318
923
|
self.last_item_class = True
|
|
1319
924
|
|
|
1320
925
|
print("class %s(%s):" % (head.itf.name, basename), file=self.stream)
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
print(self._to_docstring(doc), file=self.stream)
|
|
926
|
+
if head.itf.doc:
|
|
927
|
+
print(self._to_docstring(head.itf.doc), file=self.stream)
|
|
1324
928
|
print(" _case_insensitive_ = True", file=self.stream)
|
|
1325
929
|
print(" _iid_ = GUID(%r)" % head.itf.iid, file=self.stream)
|
|
1326
930
|
print(" _idlflags_ = %s" % head.itf.idlflags, file=self.stream)
|
|
@@ -1404,272 +1008,3 @@ class CodeGenerator(object):
|
|
|
1404
1008
|
gen = DispPropertyGenerator(prop)
|
|
1405
1009
|
print(gen.generate(), file=self.stream)
|
|
1406
1010
|
self.last_item_class = False
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
class TypeNamer(object):
|
|
1410
|
-
def __call__(self, t: Any) -> str:
|
|
1411
|
-
# Return a string, containing an expression which can be used
|
|
1412
|
-
# to refer to the type. Assumes the 'from ctypes import *'
|
|
1413
|
-
# namespace is available.
|
|
1414
|
-
if isinstance(t, typedesc.SAFEARRAYType):
|
|
1415
|
-
return "_midlSAFEARRAY(%s)" % self(t.typ)
|
|
1416
|
-
# if isinstance(t, typedesc.CoClass):
|
|
1417
|
-
# return "%s._com_interfaces_[0]" % t.name
|
|
1418
|
-
if isinstance(t, typedesc.Typedef):
|
|
1419
|
-
return t.name
|
|
1420
|
-
if isinstance(t, typedesc.PointerType):
|
|
1421
|
-
_t, pcnt = self._inspect_PointerType(t)
|
|
1422
|
-
return "%s%s%s" % ("POINTER(" * pcnt, self(_t), ")" * pcnt)
|
|
1423
|
-
elif isinstance(t, typedesc.ArrayType):
|
|
1424
|
-
return "%s * %s" % (self(t.typ), int(t.max) + 1)
|
|
1425
|
-
elif isinstance(t, typedesc.FunctionType):
|
|
1426
|
-
args = [self(x) for x in [t.returns] + list(t.iterArgTypes())]
|
|
1427
|
-
if "__stdcall__" in t.attributes:
|
|
1428
|
-
return "WINFUNCTYPE(%s)" % ", ".join(args)
|
|
1429
|
-
else:
|
|
1430
|
-
return "CFUNCTYPE(%s)" % ", ".join(args)
|
|
1431
|
-
elif isinstance(t, typedesc.CvQualifiedType):
|
|
1432
|
-
# const and volatile are ignored
|
|
1433
|
-
return "%s" % self(t.typ)
|
|
1434
|
-
elif isinstance(t, typedesc.FundamentalType):
|
|
1435
|
-
return ctypes_names[t.name]
|
|
1436
|
-
elif isinstance(t, typedesc.Structure):
|
|
1437
|
-
return t.name
|
|
1438
|
-
elif isinstance(t, typedesc.Enumeration):
|
|
1439
|
-
if t.name:
|
|
1440
|
-
return t.name
|
|
1441
|
-
return "c_int" # enums are integers
|
|
1442
|
-
elif isinstance(t, typedesc.EnumValue):
|
|
1443
|
-
if keyword.iskeyword(t.name):
|
|
1444
|
-
return t.name + "_"
|
|
1445
|
-
return t.name
|
|
1446
|
-
elif isinstance(t, typedesc.External):
|
|
1447
|
-
# t.symbol_name - symbol to generate
|
|
1448
|
-
# t.tlib - the ITypeLib pointer to the typelibrary containing the symbols definition
|
|
1449
|
-
modname = name_wrapper_module(t.tlib)
|
|
1450
|
-
return "%s.%s" % (modname, t.symbol_name)
|
|
1451
|
-
return t.name
|
|
1452
|
-
|
|
1453
|
-
def _inspect_PointerType(
|
|
1454
|
-
self, t: typedesc.PointerType, count: int = 0
|
|
1455
|
-
) -> Tuple[Any, int]:
|
|
1456
|
-
if ASSUME_STRINGS:
|
|
1457
|
-
x = get_real_type(t.typ)
|
|
1458
|
-
if isinstance(x, typedesc.FundamentalType):
|
|
1459
|
-
if x.name == "char":
|
|
1460
|
-
return typedesc.Typedef("STRING", x), count
|
|
1461
|
-
elif x.name == "wchar_t":
|
|
1462
|
-
return typedesc.Typedef("WSTRING", x), count
|
|
1463
|
-
if isinstance(t.typ, typedesc.FunctionType):
|
|
1464
|
-
return t.typ, count
|
|
1465
|
-
if isinstance(t.typ, typedesc.FundamentalType):
|
|
1466
|
-
if t.typ.name == "void":
|
|
1467
|
-
return typedesc.Typedef("c_void_p", t.typ), count
|
|
1468
|
-
if isinstance(t.typ, typedesc.PointerType):
|
|
1469
|
-
return self._inspect_PointerType(t.typ, count + 1)
|
|
1470
|
-
return t.typ, count + 1
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
class ImportedNamespaces(object):
|
|
1474
|
-
def __init__(self):
|
|
1475
|
-
self.data = {}
|
|
1476
|
-
|
|
1477
|
-
def add(self, name1, name2=None, symbols=None):
|
|
1478
|
-
"""Adds a namespace will be imported.
|
|
1479
|
-
|
|
1480
|
-
Examples:
|
|
1481
|
-
>>> imports = ImportedNamespaces()
|
|
1482
|
-
>>> imports.add('datetime')
|
|
1483
|
-
>>> imports.add('ctypes', '*')
|
|
1484
|
-
>>> imports.add('decimal', 'Decimal')
|
|
1485
|
-
>>> imports.add('GUID', symbols={'GUID': 'comtypes'})
|
|
1486
|
-
>>> for name in ('COMMETHOD', 'DISPMETHOD', 'IUnknown', 'dispid',
|
|
1487
|
-
... 'CoClass', 'BSTR', 'DISPPROPERTY'):
|
|
1488
|
-
... imports.add('comtypes', name)
|
|
1489
|
-
>>> imports.add('ctypes.wintypes')
|
|
1490
|
-
>>> print(imports.getvalue())
|
|
1491
|
-
from ctypes import *
|
|
1492
|
-
import datetime
|
|
1493
|
-
from decimal import Decimal
|
|
1494
|
-
from comtypes import (
|
|
1495
|
-
BSTR, CoClass, COMMETHOD, dispid, DISPMETHOD, DISPPROPERTY, GUID,
|
|
1496
|
-
IUnknown
|
|
1497
|
-
)
|
|
1498
|
-
import ctypes.wintypes
|
|
1499
|
-
>>> assert imports.get_symbols() == {
|
|
1500
|
-
... 'Decimal', 'GUID', 'COMMETHOD', 'DISPMETHOD', 'IUnknown',
|
|
1501
|
-
... 'dispid', 'CoClass', 'BSTR', 'DISPPROPERTY'
|
|
1502
|
-
... }
|
|
1503
|
-
"""
|
|
1504
|
-
if name2 is None:
|
|
1505
|
-
import_ = name1
|
|
1506
|
-
if not symbols:
|
|
1507
|
-
self.data[import_] = None
|
|
1508
|
-
return
|
|
1509
|
-
from_ = symbols[import_]
|
|
1510
|
-
else:
|
|
1511
|
-
from_, import_ = name1, name2
|
|
1512
|
-
self.data[import_] = from_
|
|
1513
|
-
|
|
1514
|
-
def __contains__(self, item):
|
|
1515
|
-
"""Returns item has already added.
|
|
1516
|
-
|
|
1517
|
-
Examples:
|
|
1518
|
-
>>> imports = ImportedNamespaces()
|
|
1519
|
-
>>> imports.add('datetime')
|
|
1520
|
-
>>> imports.add('ctypes', '*')
|
|
1521
|
-
>>> 'datetime' in imports
|
|
1522
|
-
True
|
|
1523
|
-
>>> ('ctypes', '*') in imports
|
|
1524
|
-
True
|
|
1525
|
-
>>> 'os' in imports
|
|
1526
|
-
False
|
|
1527
|
-
>>> 'ctypes' in imports
|
|
1528
|
-
False
|
|
1529
|
-
>>> ('ctypes', 'c_int') in imports
|
|
1530
|
-
False
|
|
1531
|
-
"""
|
|
1532
|
-
if isinstance(item, tuple):
|
|
1533
|
-
from_, import_ = item
|
|
1534
|
-
else:
|
|
1535
|
-
from_, import_ = None, item
|
|
1536
|
-
if import_ in self.data:
|
|
1537
|
-
return self.data[import_] == from_
|
|
1538
|
-
return False
|
|
1539
|
-
|
|
1540
|
-
def get_symbols(self) -> Set[str]:
|
|
1541
|
-
names = set()
|
|
1542
|
-
for key, val in self.data.items():
|
|
1543
|
-
if val is None or key == "*":
|
|
1544
|
-
continue
|
|
1545
|
-
names.add(key)
|
|
1546
|
-
return names
|
|
1547
|
-
|
|
1548
|
-
def _make_line(self, from_, imports):
|
|
1549
|
-
import_ = ", ".join(imports)
|
|
1550
|
-
code = "from %s import %s" % (from_, import_)
|
|
1551
|
-
if len(code) <= 80:
|
|
1552
|
-
return code
|
|
1553
|
-
wrapper = textwrap.TextWrapper(
|
|
1554
|
-
subsequent_indent=" ", initial_indent=" ", break_long_words=False
|
|
1555
|
-
)
|
|
1556
|
-
import_ = "\n".join(wrapper.wrap(import_))
|
|
1557
|
-
code = "from %s import (\n%s\n)" % (from_, import_)
|
|
1558
|
-
return code
|
|
1559
|
-
|
|
1560
|
-
def getvalue(self):
|
|
1561
|
-
ns = {}
|
|
1562
|
-
lines = []
|
|
1563
|
-
for key, val in self.data.items():
|
|
1564
|
-
if val is None:
|
|
1565
|
-
ns[key] = val
|
|
1566
|
-
elif key == "*":
|
|
1567
|
-
lines.append("from %s import *" % val)
|
|
1568
|
-
else:
|
|
1569
|
-
ns.setdefault(val, set()).add(key)
|
|
1570
|
-
for key, val in ns.items():
|
|
1571
|
-
if val is None:
|
|
1572
|
-
lines.append("import %s" % key)
|
|
1573
|
-
else:
|
|
1574
|
-
names = sorted(val, key=lambda s: s.lower())
|
|
1575
|
-
lines.append(self._make_line(key, names))
|
|
1576
|
-
return "\n".join(lines)
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
class DeclaredNamespaces(object):
|
|
1580
|
-
def __init__(self):
|
|
1581
|
-
self.data = {}
|
|
1582
|
-
|
|
1583
|
-
def add(self, alias, definition, comment=None):
|
|
1584
|
-
"""Adds a namespace will be declared.
|
|
1585
|
-
|
|
1586
|
-
Examples:
|
|
1587
|
-
>>> declarations = DeclaredNamespaces()
|
|
1588
|
-
>>> declarations.add('STRING', 'c_char_p')
|
|
1589
|
-
>>> declarations.add('_lcid', '0', 'change this if required')
|
|
1590
|
-
>>> print(declarations.getvalue())
|
|
1591
|
-
STRING = c_char_p
|
|
1592
|
-
_lcid = 0 # change this if required
|
|
1593
|
-
>>> assert declarations.get_symbols() == {
|
|
1594
|
-
... 'STRING', '_lcid'
|
|
1595
|
-
... }
|
|
1596
|
-
"""
|
|
1597
|
-
self.data[(alias, definition)] = comment
|
|
1598
|
-
|
|
1599
|
-
def get_symbols(self) -> Set[str]:
|
|
1600
|
-
names = set()
|
|
1601
|
-
for alias, _ in self.data.keys():
|
|
1602
|
-
names.add(alias)
|
|
1603
|
-
return names
|
|
1604
|
-
|
|
1605
|
-
def getvalue(self):
|
|
1606
|
-
lines = []
|
|
1607
|
-
for (alias, definition), comment in self.data.items():
|
|
1608
|
-
code = "%s = %s" % (alias, definition)
|
|
1609
|
-
if comment:
|
|
1610
|
-
code = code + " # %s" % comment
|
|
1611
|
-
lines.append(code)
|
|
1612
|
-
return "\n".join(lines)
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
class EnumerationNamespaces(object):
|
|
1616
|
-
def __init__(self):
|
|
1617
|
-
self.data: Dict[str, List[Tuple[str, int]]] = {}
|
|
1618
|
-
|
|
1619
|
-
def add(self, enum_name: str, member_name: str, value: int) -> None:
|
|
1620
|
-
"""Adds a namespace will be enumeration and its member.
|
|
1621
|
-
|
|
1622
|
-
Examples:
|
|
1623
|
-
<BLANKLINE> is necessary for doctest
|
|
1624
|
-
>>> enums = EnumerationNamespaces()
|
|
1625
|
-
>>> enums.add('Foo', 'ham', 1)
|
|
1626
|
-
>>> enums.add('Foo', 'spam', 2)
|
|
1627
|
-
>>> enums.add('Bar', 'bacon', 3)
|
|
1628
|
-
>>> assert 'Foo' in enums
|
|
1629
|
-
>>> assert 'Baz' not in enums
|
|
1630
|
-
>>> print(enums.to_intflags())
|
|
1631
|
-
class Foo(IntFlag):
|
|
1632
|
-
ham = 1
|
|
1633
|
-
spam = 2
|
|
1634
|
-
<BLANKLINE>
|
|
1635
|
-
<BLANKLINE>
|
|
1636
|
-
class Bar(IntFlag):
|
|
1637
|
-
bacon = 3
|
|
1638
|
-
>>> print(enums.to_constants())
|
|
1639
|
-
# values for enumeration 'Foo'
|
|
1640
|
-
ham = 1
|
|
1641
|
-
spam = 2
|
|
1642
|
-
Foo = c_int # enum
|
|
1643
|
-
<BLANKLINE>
|
|
1644
|
-
# values for enumeration 'Bar'
|
|
1645
|
-
bacon = 3
|
|
1646
|
-
Bar = c_int # enum
|
|
1647
|
-
"""
|
|
1648
|
-
self.data.setdefault(enum_name, []).append((member_name, value))
|
|
1649
|
-
|
|
1650
|
-
def __contains__(self, item: str) -> bool:
|
|
1651
|
-
return item in self.data
|
|
1652
|
-
|
|
1653
|
-
def get_symbols(self) -> Set[str]:
|
|
1654
|
-
return set(self.data)
|
|
1655
|
-
|
|
1656
|
-
def to_constants(self) -> str:
|
|
1657
|
-
blocks = []
|
|
1658
|
-
for enum_name, enum_members in self.data.items():
|
|
1659
|
-
lines = []
|
|
1660
|
-
lines.append(f"# values for enumeration '{enum_name}'")
|
|
1661
|
-
for n, v in enum_members:
|
|
1662
|
-
lines.append(f"{n} = {v}")
|
|
1663
|
-
lines.append(f"{enum_name} = c_int # enum")
|
|
1664
|
-
blocks.append("\n".join(lines))
|
|
1665
|
-
return "\n\n".join(blocks)
|
|
1666
|
-
|
|
1667
|
-
def to_intflags(self) -> str:
|
|
1668
|
-
blocks = []
|
|
1669
|
-
for enum_name, enum_members in self.data.items():
|
|
1670
|
-
lines = []
|
|
1671
|
-
lines.append(f"class {enum_name}(IntFlag):")
|
|
1672
|
-
for member_name, value in enum_members:
|
|
1673
|
-
lines.append(f" {member_name} = {value}")
|
|
1674
|
-
blocks.append("\n".join(lines))
|
|
1675
|
-
return "\n\n\n".join(blocks)
|