comtypes 1.3.0__zip → 1.4.0__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.3.0 → comtypes-1.4.0}/CHANGES.txt +12 -0
- {comtypes-1.3.0/comtypes.egg-info → comtypes-1.4.0}/PKG-INFO +5 -29
- {comtypes-1.3.0 → comtypes-1.4.0}/README.md +4 -28
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/__init__.py +1 -1
- comtypes-1.4.0/comtypes/hints.pyi +244 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_client.py +9 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_excel.py +10 -3
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/tools/codegenerator.py +116 -31
- comtypes-1.4.0/comtypes/tools/typeannotator.py +319 -0
- {comtypes-1.3.0 → comtypes-1.4.0/comtypes.egg-info}/PKG-INFO +5 -29
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes.egg-info/SOURCES.txt +1 -0
- comtypes-1.3.0/comtypes/hints.pyi +0 -4
- {comtypes-1.3.0 → comtypes-1.4.0}/LICENSE.txt +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/MANIFEST.in +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/GUID.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/_comobject.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/_memberspec.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/_meta.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/_npsupport.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/_safearray.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/automation.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/clear_cache.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/client/__init__.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/client/_code_cache.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/client/_constants.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/client/_events.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/client/_generate.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/client/lazybind.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/connectionpoints.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/errorinfo.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/git.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/hresult.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/logutil.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/messageloop.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/patcher.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/persist.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/safearray.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/server/__init__.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/server/automation.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/server/connectionpoints.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/server/inprocserver.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/server/localserver.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/server/register.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/server/w_getopt.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/shelllink.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/TestComServer.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/TestDispServer.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/__init__.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/find_memleak.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/runtests.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/setup.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_BSTR.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_GUID.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_agilent.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_avmc.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_basic.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_casesensitivity.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_clear_cache.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_client_dynamic.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_collections.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_comserver.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_createwrappers.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_dispinterface.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_dyndispatch.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_findgendir.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_ie.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_ienum.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_imfattributes.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_inout_args.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_npsupport.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_outparam.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_propputref.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_safearray.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_server.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_showevents.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_typeinfo.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_urlhistory.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_variant.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_win32com_interop.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_wmi.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/test/test_word.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/tools/tlbparser.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/tools/typedesc.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/tools/typedesc_base.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/typeinfo.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/util.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes/viewobject.py +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/setup.cfg +0 -0
- {comtypes-1.3.0 → comtypes-1.4.0}/setup.py +0 -0
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
Comtypes CHANGELOG
|
|
2
2
|
==================
|
|
3
3
|
|
|
4
|
+
Release 1.4.0
|
|
5
|
+
--------------
|
|
6
|
+
* Add enumeration definitions in generated friendly modules. By @junkmd.
|
|
7
|
+
* Add descriptions to ``index.rst`` about the enumeration types. By @junkmd.
|
|
8
|
+
* Add GitHub Actions auto-test workflow. By @junkmd.
|
|
9
|
+
|
|
10
|
+
Release 1.3.1
|
|
11
|
+
--------------
|
|
12
|
+
* Add type annotations to dynamically generated modules. By @junkmd.
|
|
13
|
+
* Bring back Excel early-bind test. By @junkmd.
|
|
14
|
+
* update ``README.md``. By @junkmd.
|
|
15
|
+
|
|
4
16
|
Release 1.3.0
|
|
5
17
|
--------------
|
|
6
18
|
* Improve error message on non Windows environments. By @CristiFati.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: comtypes
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Pure Python COM package
|
|
5
5
|
Home-page: https://github.com/enthought/comtypes
|
|
6
6
|
Download-URL: https://github.com/enthought/comtypes/releases
|
|
@@ -19,13 +19,14 @@ License-File: LICENSE.txt
|
|
|
19
19
|
|
|
20
20
|
# comtypes
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
[
|
|
23
|
+
[](https://pypi.org/project/comtypes/) [](https://pypi.org/project/comtypes/) [](https://pypi.org/project/comtypes/) [](https://pypi.org/project/comtypes/)
|
|
24
|
+
[](https://github.com/enthought/comtypes/stargazers) [](https://github.com/enthought/comtypes/network/members)
|
|
24
25
|
[](https://tidelift.com/subscription/pkg/pypi-comtypes?utm_source=pypi-comtypes&utm_medium=readme)
|
|
25
26
|
|
|
26
27
|
## About
|
|
27
28
|
|
|
28
|
-
`comtypes` is a lightweight `Python` COM package, based on the [`ctypes`](https://docs.python.org/library/ctypes.html) FFI library.
|
|
29
|
+
`comtypes` is a lightweight `Python` [COM](https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal) package, based on the [`ctypes`](https://docs.python.org/library/ctypes.html) FFI library.
|
|
29
30
|
|
|
30
31
|
`comtypes` allows to define, call, and implement custom and dispatch-based COM interfaces in pure `Python`.
|
|
31
32
|
|
|
@@ -66,31 +67,6 @@ But these third-parties are not required as a prerequisite for runtime.
|
|
|
66
67
|
Tracking issues, reporting bugs and contributing to the codebase and documentation are on GitHub at:
|
|
67
68
|
https://github.com/enthought/comtypes
|
|
68
69
|
|
|
69
|
-
<a id="ongoing-plans"></a>
|
|
70
|
-
### Ongoing plans
|
|
71
|
-
#### `GetModule` will also generate static typing for methods and properties
|
|
72
|
-
`comtypes.client.GetModule` generates `Python` wrapper modules from a COM type library, containing interface classes, coclasses, constants, and structures. The `.py` files are generated in the `comtypes.gen` package.
|
|
73
|
-
|
|
74
|
-
In the current `comtypes` specification, type checkers could not infer static type information from generated modules codebase, since methods and properties were mostly defined and implemented by metaclasses.
|
|
75
|
-
In future release, in generated modules, static typing will be added to part of methods and properties.
|
|
76
|
-
|
|
77
|
-
Static type information is added only under [`if TYPE_CHECKING:`](https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING) blocks. Consequently, it will **not** override any methods defined with metaclasses at runtime, ensuring that the runtime behavior remains unchanged.
|
|
78
|
-
|
|
79
|
-
Please refer to [the GitHub issue](https://github.com/enthought/comtypes/issues/400) for details.
|
|
80
|
-
|
|
81
|
-
#### In friendly modules, the names that were used as aliases for `ctypes.c_int` will be used for enumeration types implemented with `enum`
|
|
82
|
-
`comtypes.client.GetModule` generates two `Python` modules in the `comtypes.gen` package with a single call.
|
|
83
|
-
|
|
84
|
-
A first wrapper module is created with a long name that is derived from the type library guid, version number and lcid. It contains interface classes, coclasses, constants, and structures.
|
|
85
|
-
A second friendly module is created with a shorter name derived from the type library name itself. It imports items from the wrapper module, and will be the module returned from `GetModule`.
|
|
86
|
-
|
|
87
|
-
In the current `comtypes` specification, if a COM type kind is defined as an enumeration type, that type name is used as an alias for [`ctypes.c_int`](https://docs.python.org/3/library/ctypes.html#ctypes.c_int) in the wrapper module, and that symbol is imported into the friendly module.
|
|
88
|
-
In future release, in friendly modules, their names will no longer be aliases for `c_int`. Instead, they will be defined as enumerations implemented with [`enum`](https://docs.python.org/3/library/enum.html).
|
|
89
|
-
|
|
90
|
-
When imported into the friendly module, the wrapper module will be aliased with an abstracted name (`__wrapper_module__`). This allows users to continue using the old definitions by modifying the import sections of their codebase.
|
|
91
|
-
|
|
92
|
-
Please refer to [the GitHub issue](https://github.com/enthought/comtypes/issues/345) for details.
|
|
93
|
-
|
|
94
70
|
## For Enterprise
|
|
95
71
|
|
|
96
72
|
Available as part of the Tidelift Subscription.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# comtypes
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[
|
|
4
|
+
[](https://pypi.org/project/comtypes/) [](https://pypi.org/project/comtypes/) [](https://pypi.org/project/comtypes/) [](https://pypi.org/project/comtypes/)
|
|
5
|
+
[](https://github.com/enthought/comtypes/stargazers) [](https://github.com/enthought/comtypes/network/members)
|
|
5
6
|
[](https://tidelift.com/subscription/pkg/pypi-comtypes?utm_source=pypi-comtypes&utm_medium=readme)
|
|
6
7
|
|
|
7
8
|
## About
|
|
8
9
|
|
|
9
|
-
`comtypes` is a lightweight `Python` COM package, based on the [`ctypes`](https://docs.python.org/library/ctypes.html) FFI library.
|
|
10
|
+
`comtypes` is a lightweight `Python` [COM](https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal) package, based on the [`ctypes`](https://docs.python.org/library/ctypes.html) FFI library.
|
|
10
11
|
|
|
11
12
|
`comtypes` allows to define, call, and implement custom and dispatch-based COM interfaces in pure `Python`.
|
|
12
13
|
|
|
@@ -47,31 +48,6 @@ But these third-parties are not required as a prerequisite for runtime.
|
|
|
47
48
|
Tracking issues, reporting bugs and contributing to the codebase and documentation are on GitHub at:
|
|
48
49
|
https://github.com/enthought/comtypes
|
|
49
50
|
|
|
50
|
-
<a id="ongoing-plans"></a>
|
|
51
|
-
### Ongoing plans
|
|
52
|
-
#### `GetModule` will also generate static typing for methods and properties
|
|
53
|
-
`comtypes.client.GetModule` generates `Python` wrapper modules from a COM type library, containing interface classes, coclasses, constants, and structures. The `.py` files are generated in the `comtypes.gen` package.
|
|
54
|
-
|
|
55
|
-
In the current `comtypes` specification, type checkers could not infer static type information from generated modules codebase, since methods and properties were mostly defined and implemented by metaclasses.
|
|
56
|
-
In future release, in generated modules, static typing will be added to part of methods and properties.
|
|
57
|
-
|
|
58
|
-
Static type information is added only under [`if TYPE_CHECKING:`](https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING) blocks. Consequently, it will **not** override any methods defined with metaclasses at runtime, ensuring that the runtime behavior remains unchanged.
|
|
59
|
-
|
|
60
|
-
Please refer to [the GitHub issue](https://github.com/enthought/comtypes/issues/400) for details.
|
|
61
|
-
|
|
62
|
-
#### In friendly modules, the names that were used as aliases for `ctypes.c_int` will be used for enumeration types implemented with `enum`
|
|
63
|
-
`comtypes.client.GetModule` generates two `Python` modules in the `comtypes.gen` package with a single call.
|
|
64
|
-
|
|
65
|
-
A first wrapper module is created with a long name that is derived from the type library guid, version number and lcid. It contains interface classes, coclasses, constants, and structures.
|
|
66
|
-
A second friendly module is created with a shorter name derived from the type library name itself. It imports items from the wrapper module, and will be the module returned from `GetModule`.
|
|
67
|
-
|
|
68
|
-
In the current `comtypes` specification, if a COM type kind is defined as an enumeration type, that type name is used as an alias for [`ctypes.c_int`](https://docs.python.org/3/library/ctypes.html#ctypes.c_int) in the wrapper module, and that symbol is imported into the friendly module.
|
|
69
|
-
In future release, in friendly modules, their names will no longer be aliases for `c_int`. Instead, they will be defined as enumerations implemented with [`enum`](https://docs.python.org/3/library/enum.html).
|
|
70
|
-
|
|
71
|
-
When imported into the friendly module, the wrapper module will be aliased with an abstracted name (`__wrapper_module__`). This allows users to continue using the old definitions by modifying the import sections of their codebase.
|
|
72
|
-
|
|
73
|
-
Please refer to [the GitHub issue](https://github.com/enthought/comtypes/issues/345) for details.
|
|
74
|
-
|
|
75
51
|
## For Enterprise
|
|
76
52
|
|
|
77
53
|
Available as part of the Tidelift Subscription.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# This stub contains...
|
|
2
|
+
# - symbols those what might occur recursive imports in runtime.
|
|
3
|
+
# - utilities for type hints.
|
|
4
|
+
import sys
|
|
5
|
+
from typing import (
|
|
6
|
+
Any,
|
|
7
|
+
Callable,
|
|
8
|
+
Generic,
|
|
9
|
+
Iterator,
|
|
10
|
+
List,
|
|
11
|
+
NoReturn,
|
|
12
|
+
Tuple,
|
|
13
|
+
Type,
|
|
14
|
+
TypeVar,
|
|
15
|
+
Optional,
|
|
16
|
+
overload,
|
|
17
|
+
Union as _UnionT,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if sys.version_info >= (3, 8):
|
|
21
|
+
from typing import Protocol
|
|
22
|
+
else:
|
|
23
|
+
from typing_extensions import Protocol
|
|
24
|
+
if sys.version_info >= (3, 10):
|
|
25
|
+
from typing import Concatenate, ParamSpec
|
|
26
|
+
else:
|
|
27
|
+
from typing_extensions import Concatenate, ParamSpec
|
|
28
|
+
if sys.version_info >= (3, 11):
|
|
29
|
+
from typing import Self
|
|
30
|
+
else:
|
|
31
|
+
from typing_extensions import Self
|
|
32
|
+
|
|
33
|
+
from comtypes.automation import IDispatch as IDispatch, VARIANT as VARIANT
|
|
34
|
+
from comtypes.server import IClassFactory as IClassFactory
|
|
35
|
+
from comtypes.typeinfo import ITypeInfo as ITypeInfo
|
|
36
|
+
|
|
37
|
+
class _MethodTypeDesc(Protocol):
|
|
38
|
+
arguments: List[Tuple[Any, str, List[str], Optional[Any]]]
|
|
39
|
+
idlflags: List[str]
|
|
40
|
+
name: str
|
|
41
|
+
|
|
42
|
+
_P_Put = ParamSpec("_P_Put")
|
|
43
|
+
_R_Put = TypeVar("_R_Put")
|
|
44
|
+
_P_PutRef = ParamSpec("_P_PutRef")
|
|
45
|
+
_R_PutRef = TypeVar("_R_PutRef")
|
|
46
|
+
|
|
47
|
+
def put_or_putref(
|
|
48
|
+
put: Callable[_P_Put, _R_Put], putref: Callable[_P_PutRef, _R_PutRef]
|
|
49
|
+
) -> _UnionT[Callable[_P_Put, _R_Put], Callable[_P_PutRef, _R_PutRef]]: ...
|
|
50
|
+
|
|
51
|
+
_T_Inst = TypeVar("_T_Inst")
|
|
52
|
+
_T_SetVal = TypeVar("_T_SetVal")
|
|
53
|
+
_P_Get = ParamSpec("_P_Get")
|
|
54
|
+
_R_Get = TypeVar("_R_Get")
|
|
55
|
+
_P_Set = ParamSpec("_P_Set")
|
|
56
|
+
|
|
57
|
+
class _GetSetNormalProperty(Generic[_T_Inst, _R_Get, _T_SetVal]):
|
|
58
|
+
fget: Callable[[_T_Inst], Any]
|
|
59
|
+
fset: Callable[[_T_Inst, _T_SetVal], Any]
|
|
60
|
+
|
|
61
|
+
@overload
|
|
62
|
+
def __get__(self, instance: None, owner: Type[_T_Inst]) -> Self: ...
|
|
63
|
+
@overload
|
|
64
|
+
def __get__(self, instance: _T_Inst, owner: Optional[Type[_T_Inst]]) -> _R_Get: ...
|
|
65
|
+
def __set__(self, instance: _T_Inst, value: _T_SetVal) -> None: ...
|
|
66
|
+
|
|
67
|
+
class _GetOnlyNormalProperty(Generic[_T_Inst, _R_Get]):
|
|
68
|
+
fget: Callable[[_T_Inst], Any]
|
|
69
|
+
|
|
70
|
+
@overload
|
|
71
|
+
def __get__(self, instance: None, owner: Type[_T_Inst]) -> Self: ...
|
|
72
|
+
@overload
|
|
73
|
+
def __get__(self, instance: _T_Inst, owner: Optional[Type[_T_Inst]]) -> _R_Get: ...
|
|
74
|
+
def __set__(self, instance: _T_Inst, value: Any) -> NoReturn: ...
|
|
75
|
+
|
|
76
|
+
class _SetOnlyNormalProperty(Generic[_T_Inst, _T_SetVal]):
|
|
77
|
+
fget: Callable[[_T_Inst], Any]
|
|
78
|
+
fset: Callable[[_T_Inst, _T_SetVal], Any]
|
|
79
|
+
|
|
80
|
+
@overload
|
|
81
|
+
def __get__(self, instance: None, owner: Type[_T_Inst]) -> Self: ...
|
|
82
|
+
@overload
|
|
83
|
+
def __get__(
|
|
84
|
+
self, instance: _T_Inst, owner: Optional[Type[_T_Inst]]
|
|
85
|
+
) -> NoReturn: ...
|
|
86
|
+
def __set__(self, instance: _T_Inst, value: _T_SetVal) -> None: ...
|
|
87
|
+
|
|
88
|
+
@overload
|
|
89
|
+
def normal_property(
|
|
90
|
+
fget: Callable[[_T_Inst], _R_Get],
|
|
91
|
+
) -> _GetOnlyNormalProperty[_T_Inst, _R_Get]: ...
|
|
92
|
+
@overload
|
|
93
|
+
def normal_property(
|
|
94
|
+
*, fset: Callable[[_T_Inst, _T_SetVal], Any]
|
|
95
|
+
) -> _SetOnlyNormalProperty[_T_Inst, _T_SetVal]: ...
|
|
96
|
+
@overload
|
|
97
|
+
def normal_property(
|
|
98
|
+
fget: Callable[[_T_Inst], _R_Get], fset: Callable[[_T_Inst, _T_SetVal], Any]
|
|
99
|
+
) -> _GetSetNormalProperty[_T_Inst, _R_Get, _T_SetVal]: ...
|
|
100
|
+
|
|
101
|
+
class _GetSetBoundNamedProperty(Generic[_T_Inst, _P_Get, _R_Get, _P_Set]):
|
|
102
|
+
name: str
|
|
103
|
+
fget: Callable[Concatenate[_T_Inst, _P_Get], _R_Get]
|
|
104
|
+
fset: Callable[Concatenate[_T_Inst, _P_Set], Any]
|
|
105
|
+
__doc__: Optional[str]
|
|
106
|
+
def __getitem__(self, index: Any) -> _R_Get: ...
|
|
107
|
+
def __call__(self, *args: _P_Get.args, **kwargs: _P_Get.kwargs) -> _R_Get: ...
|
|
108
|
+
def __setitem__(self, index: Any, value: Any) -> None: ...
|
|
109
|
+
def __iter__(self) -> NoReturn: ...
|
|
110
|
+
|
|
111
|
+
class _GetSetNamedProperty(Generic[_T_Inst, _P_Get, _R_Get, _P_Set]):
|
|
112
|
+
name: str
|
|
113
|
+
fget: Callable[Concatenate[_T_Inst, _P_Get], _R_Get]
|
|
114
|
+
fset: Callable[Concatenate[_T_Inst, _P_Set], Any]
|
|
115
|
+
__doc__: Optional[str]
|
|
116
|
+
|
|
117
|
+
@overload
|
|
118
|
+
def __get__(self, instance: None, owner: Type[_T_Inst]) -> Self: ...
|
|
119
|
+
@overload
|
|
120
|
+
def __get__(
|
|
121
|
+
self, instance: _T_Inst, owner: Optional[Type[_T_Inst]]
|
|
122
|
+
) -> _GetSetBoundNamedProperty[_T_Inst, _P_Get, _R_Get, _P_Set]: ...
|
|
123
|
+
def __set__(self, instance: _T_Inst, value: Any) -> NoReturn: ...
|
|
124
|
+
|
|
125
|
+
class _GetOnlyBoundNamedProperty(Generic[_T_Inst, _P_Get, _R_Get]):
|
|
126
|
+
name: str
|
|
127
|
+
fget: Callable[Concatenate[_T_Inst, _P_Get], _R_Get]
|
|
128
|
+
__doc__: Optional[str]
|
|
129
|
+
def __getitem__(self, index: Any) -> _R_Get: ...
|
|
130
|
+
def __call__(self, *args: _P_Get.args, **kwargs: _P_Get.kwargs) -> _R_Get: ...
|
|
131
|
+
def __setitem__(self, index: Any, value: Any) -> NoReturn: ...
|
|
132
|
+
def __iter__(self) -> NoReturn: ...
|
|
133
|
+
|
|
134
|
+
class _GetOnlyNamedProperty(Generic[_T_Inst, _P_Get, _R_Get]):
|
|
135
|
+
name: str
|
|
136
|
+
fget: Callable[Concatenate[_T_Inst, _P_Get], _R_Get]
|
|
137
|
+
__doc__: Optional[str]
|
|
138
|
+
|
|
139
|
+
@overload
|
|
140
|
+
def __get__(self, instance: None, owner: Type[_T_Inst]) -> Self: ...
|
|
141
|
+
@overload
|
|
142
|
+
def __get__(
|
|
143
|
+
self, instance: _T_Inst, owner: Optional[Type[_T_Inst]]
|
|
144
|
+
) -> _GetOnlyBoundNamedProperty[_T_Inst, _P_Get, _R_Get]: ...
|
|
145
|
+
def __set__(self, instance: _T_Inst, value: Any) -> NoReturn: ...
|
|
146
|
+
|
|
147
|
+
class _SetOnlyBoundNamedProperty(Generic[_T_Inst, _P_Set]):
|
|
148
|
+
name: str
|
|
149
|
+
fset: Callable[Concatenate[_T_Inst, _P_Set], Any]
|
|
150
|
+
__doc__: Optional[str]
|
|
151
|
+
def __getitem__(self, index: Any) -> NoReturn: ...
|
|
152
|
+
def __call__(self, *args: Any, **kwargs: Any) -> NoReturn: ...
|
|
153
|
+
def __setitem__(self, index: Any, value: Any) -> None: ...
|
|
154
|
+
def __iter__(self) -> NoReturn: ...
|
|
155
|
+
|
|
156
|
+
class _SetOnlyNamedProperty(Generic[_T_Inst, _P_Set]):
|
|
157
|
+
name: str
|
|
158
|
+
fset: Callable[Concatenate[_T_Inst, _P_Set], Any]
|
|
159
|
+
__doc__: Optional[str]
|
|
160
|
+
|
|
161
|
+
@overload
|
|
162
|
+
def __get__(self, instance: None, owner: Type[_T_Inst]) -> Self: ...
|
|
163
|
+
@overload
|
|
164
|
+
def __get__(
|
|
165
|
+
self, instance: _T_Inst, owner: Optional[Type[_T_Inst]]
|
|
166
|
+
) -> _SetOnlyBoundNamedProperty[_T_Inst, _P_Set]: ...
|
|
167
|
+
def __set__(self, instance: _T_Inst, value: Any) -> NoReturn: ...
|
|
168
|
+
|
|
169
|
+
@overload
|
|
170
|
+
def named_property(
|
|
171
|
+
name: str, fget: Callable[Concatenate[_T_Inst, _P_Get], _R_Get]
|
|
172
|
+
) -> _GetOnlyNamedProperty[_T_Inst, _P_Get, _R_Get]: ...
|
|
173
|
+
@overload
|
|
174
|
+
def named_property(
|
|
175
|
+
name: str, *, fset: Callable[Concatenate[_T_Inst, _P_Set], Any]
|
|
176
|
+
) -> _SetOnlyNamedProperty[_T_Inst, _P_Set]: ...
|
|
177
|
+
@overload
|
|
178
|
+
def named_property(
|
|
179
|
+
name: str,
|
|
180
|
+
fget: Callable[Concatenate[_T_Inst, _P_Get], _R_Get],
|
|
181
|
+
fset: Callable[Concatenate[_T_Inst, _P_Set], Any],
|
|
182
|
+
) -> _GetSetNamedProperty[_T_Inst, _P_Get, _R_Get, _P_Set]: ...
|
|
183
|
+
|
|
184
|
+
# for dunder methods those what be patched to ComInterface by metaclasses.
|
|
185
|
+
|
|
186
|
+
class _Descriptor(Protocol[_T_Inst, _R_Get]):
|
|
187
|
+
@overload
|
|
188
|
+
def __get__(self, instance: None, owner: Type[_T_Inst]) -> Self: ...
|
|
189
|
+
@overload
|
|
190
|
+
def __get__(self, instance: _T_Inst, owner: Optional[Type[_T_Inst]]) -> _R_Get: ...
|
|
191
|
+
|
|
192
|
+
# `__len__` for objects with `Count`
|
|
193
|
+
@overload
|
|
194
|
+
def to_dunder_len(count: _Descriptor[_T_Inst, int]) -> Callable[[_T_Inst], int]: ...
|
|
195
|
+
@overload
|
|
196
|
+
def to_dunder_len(count: Any) -> Callable[..., NoReturn]: ...
|
|
197
|
+
|
|
198
|
+
# `__iter__` for objects with `_NewEnum`
|
|
199
|
+
_T_E = TypeVar("_T_E")
|
|
200
|
+
|
|
201
|
+
@overload
|
|
202
|
+
def to_dunder_iter(
|
|
203
|
+
newenum: _UnionT[
|
|
204
|
+
_Descriptor[_T_Inst, Iterator[_T_E]], Callable[[_T_Inst], Iterator[_T_E]]
|
|
205
|
+
]
|
|
206
|
+
) -> Callable[[_T_Inst], Iterator[_T_E]]: ...
|
|
207
|
+
@overload
|
|
208
|
+
def to_dunder_iter(newenum: Any) -> Callable[..., NoReturn]: ...
|
|
209
|
+
|
|
210
|
+
# ... for objects with `Item`
|
|
211
|
+
# `__call__`
|
|
212
|
+
@overload
|
|
213
|
+
def to_dunder_call(
|
|
214
|
+
item: _UnionT[
|
|
215
|
+
_GetSetNamedProperty[_T_Inst, _P_Get, _R_Get, ...],
|
|
216
|
+
_GetOnlyNamedProperty[_T_Inst, _P_Get, _R_Get],
|
|
217
|
+
Callable[Concatenate[_T_Inst, _P_Get], _R_Get],
|
|
218
|
+
]
|
|
219
|
+
) -> Callable[Concatenate[_T_Inst, _P_Get], _R_Get]: ...
|
|
220
|
+
@overload
|
|
221
|
+
def to_dunder_call(item: Any) -> Callable[..., NoReturn]: ...
|
|
222
|
+
|
|
223
|
+
# `__getitem__`
|
|
224
|
+
@overload
|
|
225
|
+
def to_dunder_getitem(
|
|
226
|
+
item: _UnionT[
|
|
227
|
+
_GetSetNamedProperty[_T_Inst, _P_Get, _R_Get, ...],
|
|
228
|
+
_GetOnlyNamedProperty[_T_Inst, _P_Get, _R_Get],
|
|
229
|
+
Callable[Concatenate[_T_Inst, _P_Get], _R_Get],
|
|
230
|
+
]
|
|
231
|
+
) -> Callable[Concatenate[_T_Inst, _P_Get], _R_Get]: ...
|
|
232
|
+
@overload
|
|
233
|
+
def to_dunder_getitem(item: Any) -> Callable[..., NoReturn]: ...
|
|
234
|
+
|
|
235
|
+
# `__setitem__`
|
|
236
|
+
@overload
|
|
237
|
+
def to_dunder_setitem(
|
|
238
|
+
item: _UnionT[
|
|
239
|
+
_GetSetNamedProperty[_T_Inst, ..., Any, _P_Set],
|
|
240
|
+
_SetOnlyNamedProperty[_T_Inst, _P_Set],
|
|
241
|
+
]
|
|
242
|
+
) -> Callable[Concatenate[_T_Inst, _P_Set], Any]: ...
|
|
243
|
+
@overload
|
|
244
|
+
def to_dunder_setitem(item: Any) -> Callable[..., NoReturn]: ...
|
|
@@ -229,6 +229,15 @@ class Test_Constants(ut.TestCase):
|
|
|
229
229
|
self.assertEqual(consts.TextCompare, Scripting.TextCompare)
|
|
230
230
|
self.assertEqual(consts.DatabaseCompare, Scripting.DatabaseCompare)
|
|
231
231
|
|
|
232
|
+
def test_enums_in_friendly_mod(self):
|
|
233
|
+
consts = comtypes.client.Constants("scrrun.dll")
|
|
234
|
+
comtypes.client.GetModule("scrrun.dll")
|
|
235
|
+
from comtypes.gen import Scripting
|
|
236
|
+
|
|
237
|
+
for e in Scripting.StandardStreamTypes:
|
|
238
|
+
self.assertIn(e.name, consts.StandardStreamTypes)
|
|
239
|
+
self.assertEqual(consts.StandardStreamTypes[e.name], e.value)
|
|
240
|
+
|
|
232
241
|
def test_returns_other_than_enum_members(self):
|
|
233
242
|
obj = comtypes.client.CreateObject("SAPI.SpVoice")
|
|
234
243
|
from comtypes.gen import SpeechLib as sapi
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import print_function
|
|
3
3
|
|
|
4
4
|
import datetime
|
|
5
|
+
import sys
|
|
5
6
|
import unittest
|
|
6
7
|
|
|
7
8
|
from comtypes.client import CreateObject, GetModule
|
|
@@ -112,10 +113,16 @@ class BaseBindTest(object):
|
|
|
112
113
|
sh.Range[sh.Cells.Item[4, 1], sh.Cells.Item[6, 3]].Select()
|
|
113
114
|
|
|
114
115
|
|
|
116
|
+
PY_VER = "Python {0}.{1}.{2}".format(*sys.version_info[:3])
|
|
117
|
+
|
|
118
|
+
|
|
115
119
|
@unittest.skipIf(IMPORT_FAILED, "This depends on Excel.")
|
|
116
|
-
@unittest.
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
@unittest.skipIf(
|
|
121
|
+
sys.version_info[:2] == (3, 8)
|
|
122
|
+
or sys.version_info[:2] == (3, 9)
|
|
123
|
+
or (sys.version_info[:2] == (3, 10) and sys.version_info < (3, 10, 10))
|
|
124
|
+
or (sys.version_info[:2] == (3, 11) and sys.version_info < (3, 11, 2)),
|
|
125
|
+
f"This fails in {PY_VER}. See https://github.com/enthought/comtypes/issues/212",
|
|
119
126
|
)
|
|
120
127
|
class Test_EarlyBind(BaseBindTest, unittest.TestCase):
|
|
121
128
|
dynamic = False
|
|
@@ -22,7 +22,7 @@ import io
|
|
|
22
22
|
|
|
23
23
|
import comtypes
|
|
24
24
|
from comtypes import typeinfo
|
|
25
|
-
from comtypes.tools import tlbparser, typedesc
|
|
25
|
+
from comtypes.tools import tlbparser, typedesc, typeannotator
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
version = comtypes.__version__
|
|
@@ -423,12 +423,14 @@ class CodeGenerator(object):
|
|
|
423
423
|
self.stream = io.StringIO()
|
|
424
424
|
self.imports = ImportedNamespaces()
|
|
425
425
|
self.declarations = DeclaredNamespaces()
|
|
426
|
+
self.enums = EnumerationNamespaces()
|
|
426
427
|
self._to_type_name = TypeNamer()
|
|
427
428
|
self.known_symbols = known_symbols or {}
|
|
428
429
|
|
|
429
430
|
self.done = set() # type descriptions that have been generated
|
|
430
431
|
self.names = set() # names that have been generated
|
|
431
432
|
self.externals = [] # typelibs imported to generated module
|
|
433
|
+
self.aliases: Dict[str, str] = {}
|
|
432
434
|
self.last_item_class = False
|
|
433
435
|
|
|
434
436
|
def generate(self, item):
|
|
@@ -561,18 +563,17 @@ class CodeGenerator(object):
|
|
|
561
563
|
print("# -*- coding: mbcs -*-", file=output)
|
|
562
564
|
print(file=output)
|
|
563
565
|
print(self.imports.getvalue(), file=output)
|
|
566
|
+
print("from typing import TYPE_CHECKING", file=output)
|
|
567
|
+
print(file=output)
|
|
568
|
+
print("if TYPE_CHECKING:", file=output)
|
|
569
|
+
print(" from typing import Any, Tuple", file=output)
|
|
570
|
+
print(" from comtypes import hints", file=output)
|
|
571
|
+
print(file=output)
|
|
564
572
|
print(file=output)
|
|
565
573
|
print(self.declarations.getvalue(), file=output)
|
|
566
574
|
print(file=output)
|
|
567
575
|
print(self.stream.getvalue(), file=output)
|
|
568
|
-
|
|
569
|
-
dunder_all = "__all__ = [%s]" % names
|
|
570
|
-
if len(dunder_all) > 80:
|
|
571
|
-
wrapper = textwrap.TextWrapper(
|
|
572
|
-
subsequent_indent=" ", initial_indent=" ", break_long_words=False
|
|
573
|
-
)
|
|
574
|
-
dunder_all = "__all__ = [\n%s\n]" % "\n".join(wrapper.wrap(names))
|
|
575
|
-
print(dunder_all, file=output)
|
|
576
|
+
print(self._make_dunder_all_part(), file=output)
|
|
576
577
|
print(file=output)
|
|
577
578
|
if tlib_mtime is not None:
|
|
578
579
|
print("_check_version(%r, %f)" % (version, tlib_mtime), file=output)
|
|
@@ -589,29 +590,59 @@ class CodeGenerator(object):
|
|
|
589
590
|
Such as "comtypes.gen.stdole" and "comtypes.gen.Excel".
|
|
590
591
|
"""
|
|
591
592
|
output = io.StringIO()
|
|
593
|
+
print("from enum import IntFlag", file=output)
|
|
594
|
+
print(file=output)
|
|
592
595
|
print(f"import {modname} as __wrapper_module__", file=output)
|
|
593
|
-
|
|
594
|
-
subsequent_indent=" ", initial_indent=" ", break_long_words=False
|
|
595
|
-
)
|
|
596
|
-
importing_symbols = set(self.names)
|
|
597
|
-
importing_symbols.update(self.imports.get_symbols())
|
|
598
|
-
importing_symbols.update(self.declarations.get_symbols())
|
|
599
|
-
joined_names = ", ".join(str(n) for n in importing_symbols)
|
|
600
|
-
symbols = f"from {modname} import {joined_names}"
|
|
601
|
-
if len(symbols) > 80:
|
|
602
|
-
wrapped_names = "\n".join(txtwrapper.wrap(joined_names))
|
|
603
|
-
symbols = f"from {modname} import (\n{wrapped_names}\n)"
|
|
604
|
-
print(symbols, file=output)
|
|
596
|
+
print(self._make_friendly_module_import_part(modname), file=output)
|
|
605
597
|
print(file=output)
|
|
606
598
|
print(file=output)
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
599
|
+
print(self.enums.getvalue(), file=output)
|
|
600
|
+
print(file=output)
|
|
601
|
+
print(file=output)
|
|
602
|
+
enum_aliases = self.enum_aliases
|
|
603
|
+
if enum_aliases:
|
|
604
|
+
for k, v in enum_aliases.items():
|
|
605
|
+
print(f"{k} = {v}", file=output)
|
|
606
|
+
print(file=output)
|
|
607
|
+
print(file=output)
|
|
608
|
+
print(self._make_dunder_all_part(), file=output)
|
|
613
609
|
return output.getvalue()
|
|
614
610
|
|
|
611
|
+
def _make_dunder_all_part(self) -> str:
|
|
612
|
+
joined_names = ", ".join(repr(str(n)) for n in self.names)
|
|
613
|
+
dunder_all = f"__all__ = [{joined_names}]"
|
|
614
|
+
if len(dunder_all) > 80:
|
|
615
|
+
txtwrapper = textwrap.TextWrapper(
|
|
616
|
+
subsequent_indent=" ", initial_indent=" ", break_long_words=False
|
|
617
|
+
)
|
|
618
|
+
joined_names = "\n".join(txtwrapper.wrap(joined_names))
|
|
619
|
+
dunder_all = f"__all__ = [\n{joined_names}\n]"
|
|
620
|
+
return dunder_all
|
|
621
|
+
|
|
622
|
+
def _make_friendly_module_import_part(self, modname: str) -> str:
|
|
623
|
+
# The `modname` is the wrapper module name like `comtypes.gen._xxxx..._x_x_x`
|
|
624
|
+
txtwrapper = textwrap.TextWrapper(
|
|
625
|
+
subsequent_indent=" ", initial_indent=" ", break_long_words=False
|
|
626
|
+
)
|
|
627
|
+
symbols = set(self.names)
|
|
628
|
+
symbols.update(self.imports.get_symbols())
|
|
629
|
+
symbols.update(self.declarations.get_symbols())
|
|
630
|
+
symbols -= set(self.enums.get_symbols())
|
|
631
|
+
symbols -= set(self.enum_aliases)
|
|
632
|
+
joined_names = ", ".join(str(n) for n in symbols)
|
|
633
|
+
part = f"from {modname} import {joined_names}"
|
|
634
|
+
if len(part) > 80:
|
|
635
|
+
txtwrapper = textwrap.TextWrapper(
|
|
636
|
+
subsequent_indent=" ", initial_indent=" ", break_long_words=False
|
|
637
|
+
)
|
|
638
|
+
joined_names = "\n".join(txtwrapper.wrap(joined_names))
|
|
639
|
+
part = f"from {modname} import (\n{joined_names}\n)"
|
|
640
|
+
return part
|
|
641
|
+
|
|
642
|
+
@property
|
|
643
|
+
def enum_aliases(self) -> Dict[str, str]:
|
|
644
|
+
return {k: v for k, v in self.aliases.items() if v in self.enums}
|
|
645
|
+
|
|
615
646
|
def need_VARIANT_imports(self, value):
|
|
616
647
|
text = repr(value)
|
|
617
648
|
if "Decimal(" in text:
|
|
@@ -639,6 +670,8 @@ class CodeGenerator(object):
|
|
|
639
670
|
print("# Fixing keyword as EnumValue for %s" % tp.name)
|
|
640
671
|
tp_name = self._to_type_name(tp)
|
|
641
672
|
print("%s = %d" % (tp_name, value), file=self.stream)
|
|
673
|
+
if tp.enumeration.name:
|
|
674
|
+
self.enums.add(tp.enumeration.name, tp_name)
|
|
642
675
|
self.names.add(tp_name)
|
|
643
676
|
|
|
644
677
|
def Enumeration(self, tp: typedesc.Enumeration) -> None:
|
|
@@ -647,10 +680,6 @@ class CodeGenerator(object):
|
|
|
647
680
|
print("# values for enumeration '%s'" % tp.name, file=self.stream)
|
|
648
681
|
else:
|
|
649
682
|
print("# values for unnamed enumeration", file=self.stream)
|
|
650
|
-
# Some enumerations have the same name for the enum type
|
|
651
|
-
# and an enum value. Excel's XlDisplayShapes is such an example.
|
|
652
|
-
# Since we don't have separate namespaces for the type and the values,
|
|
653
|
-
# we generate the TYPE last, overwriting the value. XXX
|
|
654
683
|
for item in tp.values:
|
|
655
684
|
self.generate(item)
|
|
656
685
|
if tp.name:
|
|
@@ -669,6 +698,7 @@ class CodeGenerator(object):
|
|
|
669
698
|
self.declarations.add(tp.name, definition)
|
|
670
699
|
else:
|
|
671
700
|
print("%s = %s" % (tp.name, definition), file=self.stream)
|
|
701
|
+
self.aliases[tp.name] = definition
|
|
672
702
|
self.last_item_class = False
|
|
673
703
|
self.names.add(tp.name)
|
|
674
704
|
|
|
@@ -1100,6 +1130,12 @@ class CodeGenerator(object):
|
|
|
1100
1130
|
print(" return item", file=self.stream)
|
|
1101
1131
|
print(" raise IndexError(index)", file=self.stream)
|
|
1102
1132
|
|
|
1133
|
+
annotaions = typeannotator.ComInterfaceMembersAnnotator(head.itf).generate()
|
|
1134
|
+
if annotaions:
|
|
1135
|
+
print(file=self.stream)
|
|
1136
|
+
print(" if TYPE_CHECKING: # commembers", file=self.stream)
|
|
1137
|
+
print(annotaions, file=self.stream, end="")
|
|
1138
|
+
|
|
1103
1139
|
print(file=self.stream)
|
|
1104
1140
|
print(file=self.stream)
|
|
1105
1141
|
|
|
@@ -1221,6 +1257,13 @@ class CodeGenerator(object):
|
|
|
1221
1257
|
print(" _iid_ = GUID(%r)" % head.itf.iid, file=self.stream)
|
|
1222
1258
|
print(" _idlflags_ = %s" % head.itf.idlflags, file=self.stream)
|
|
1223
1259
|
print(" _methods_ = []", file=self.stream)
|
|
1260
|
+
|
|
1261
|
+
annotaions = typeannotator.DispInterfaceMembersAnnotator(head.itf).generate()
|
|
1262
|
+
if annotaions:
|
|
1263
|
+
print(file=self.stream)
|
|
1264
|
+
print(" if TYPE_CHECKING: # dispmembers", file=self.stream)
|
|
1265
|
+
print(annotaions, file=self.stream, end="")
|
|
1266
|
+
|
|
1224
1267
|
print(file=self.stream)
|
|
1225
1268
|
print(file=self.stream)
|
|
1226
1269
|
|
|
@@ -1499,3 +1542,45 @@ class DeclaredNamespaces(object):
|
|
|
1499
1542
|
code = code + " # %s" % comment
|
|
1500
1543
|
lines.append(code)
|
|
1501
1544
|
return "\n".join(lines)
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
class EnumerationNamespaces(object):
|
|
1548
|
+
def __init__(self):
|
|
1549
|
+
self.data: Dict[str, List[str]] = {}
|
|
1550
|
+
|
|
1551
|
+
def add(self, enum_name: str, member_name: str) -> None:
|
|
1552
|
+
"""Adds a namespace will be enumeration and its member.
|
|
1553
|
+
|
|
1554
|
+
Examples:
|
|
1555
|
+
>>> enums = EnumerationNamespaces()
|
|
1556
|
+
>>> enums.add('Foo', 'ham')
|
|
1557
|
+
>>> enums.add('Foo', 'spam')
|
|
1558
|
+
>>> enums.add('Bar', 'bacon')
|
|
1559
|
+
>>> assert 'Foo' in enums
|
|
1560
|
+
>>> assert 'Baz' not in enums
|
|
1561
|
+
>>> print(enums.getvalue()) # <BLANKLINE> is necessary for doctest
|
|
1562
|
+
class Foo(IntFlag):
|
|
1563
|
+
ham = __wrapper_module__.ham
|
|
1564
|
+
spam = __wrapper_module__.spam
|
|
1565
|
+
<BLANKLINE>
|
|
1566
|
+
<BLANKLINE>
|
|
1567
|
+
class Bar(IntFlag):
|
|
1568
|
+
bacon = __wrapper_module__.bacon
|
|
1569
|
+
"""
|
|
1570
|
+
self.data.setdefault(enum_name, []).append(member_name)
|
|
1571
|
+
|
|
1572
|
+
def __contains__(self, item: str) -> bool:
|
|
1573
|
+
return item in self.data
|
|
1574
|
+
|
|
1575
|
+
def get_symbols(self) -> Set[str]:
|
|
1576
|
+
return set(self.data)
|
|
1577
|
+
|
|
1578
|
+
def getvalue(self) -> str:
|
|
1579
|
+
blocks = []
|
|
1580
|
+
for enum_name, enum_members in self.data.items():
|
|
1581
|
+
lines = []
|
|
1582
|
+
lines.append(f"class {enum_name}(IntFlag):")
|
|
1583
|
+
for member_name in enum_members:
|
|
1584
|
+
lines.append(f" {member_name} = __wrapper_module__.{member_name}")
|
|
1585
|
+
blocks.append("\n".join(lines))
|
|
1586
|
+
return "\n\n\n".join(blocks)
|