comtypes 1.1.14__zip → 1.2.1__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. {comtypes-1.1.14 → comtypes-1.2.1}/CHANGES.txt +37 -0
  2. comtypes-1.2.1/PKG-INFO +79 -0
  3. comtypes-1.2.1/README.md +59 -0
  4. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/__init__.py +302 -555
  5. comtypes-1.2.1/comtypes/_memberspec.py +520 -0
  6. comtypes-1.2.1/comtypes/_npsupport.py +143 -0
  7. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/automation.py +99 -11
  8. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/__init__.py +80 -26
  9. comtypes-1.2.1/comtypes/client/_generate.py +274 -0
  10. comtypes-1.2.1/comtypes/hints.pyi +26 -0
  11. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/persist.py +14 -0
  12. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/safearray.py +22 -21
  13. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/__init__.py +0 -7
  14. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_client.py +35 -0
  15. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dict.py +0 -4
  16. comtypes-1.2.1/comtypes/test/test_npsupport.py +343 -0
  17. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_safearray.py +2 -235
  18. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_variant.py +6 -59
  19. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/codegenerator.py +454 -337
  20. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/tlbparser.py +56 -75
  21. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/typedesc.py +31 -3
  22. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/typedesc_base.py +28 -1
  23. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/typeinfo.py +291 -121
  24. comtypes-1.2.1/comtypes.egg-info/PKG-INFO +79 -0
  25. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/SOURCES.txt +4 -1
  26. {comtypes-1.1.14 → comtypes-1.2.1}/setup.cfg +0 -1
  27. {comtypes-1.1.14 → comtypes-1.2.1}/setup.py +15 -8
  28. comtypes-1.1.14/PKG-INFO +0 -50
  29. comtypes-1.1.14/README.md +0 -31
  30. comtypes-1.1.14/comtypes/client/_generate.py +0 -257
  31. comtypes-1.1.14/comtypes/npsupport.py +0 -125
  32. comtypes-1.1.14/comtypes.egg-info/PKG-INFO +0 -50
  33. {comtypes-1.1.14 → comtypes-1.2.1}/LICENSE.txt +0 -0
  34. {comtypes-1.1.14 → comtypes-1.2.1}/MANIFEST.in +0 -0
  35. {comtypes-1.1.14 → comtypes-1.2.1}/clear_comtypes_cache.py +0 -0
  36. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/GUID.py +0 -0
  37. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_comobject.py +0 -0
  38. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_meta.py +0 -0
  39. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_safearray.py +0 -0
  40. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_code_cache.py +0 -0
  41. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_constants.py +0 -0
  42. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_events.py +0 -0
  43. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/dynamic.py +0 -0
  44. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/lazybind.py +0 -0
  45. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/connectionpoints.py +0 -0
  46. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/errorinfo.py +0 -0
  47. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/git.py +0 -0
  48. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/hresult.py +0 -0
  49. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/logutil.py +0 -0
  50. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/messageloop.py +0 -0
  51. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/patcher.py +0 -0
  52. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/__init__.py +0 -0
  53. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/automation.py +0 -0
  54. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/connectionpoints.py +0 -0
  55. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/inprocserver.py +0 -0
  56. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/localserver.py +0 -0
  57. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/register.py +0 -0
  58. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/w_getopt.py +0 -0
  59. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/shelllink.py +0 -0
  60. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.idl +0 -0
  61. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.py +0 -0
  62. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.tlb +0 -0
  63. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.idl +0 -0
  64. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.py +0 -0
  65. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.tlb +0 -0
  66. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/find_memleak.py +0 -0
  67. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/mylib.idl +0 -0
  68. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/mytypelib.idl +0 -0
  69. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/runtests.py +0 -0
  70. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/setup.py +0 -0
  71. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_BSTR.py +0 -0
  72. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_DISPPARAMS.py +0 -0
  73. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_GUID.py +0 -0
  74. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_QueryService.py +0 -0
  75. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_agilent.py +0 -0
  76. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_avmc.py +0 -0
  77. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_basic.py +0 -0
  78. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_casesensitivity.py +0 -0
  79. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_collections.py +0 -0
  80. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_comserver.py +0 -0
  81. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_createwrappers.py +0 -0
  82. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dispinterface.py +0 -0
  83. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dyndispatch.py +0 -0
  84. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_excel.py +0 -0
  85. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_findgendir.py +0 -0
  86. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_getactiveobj.py +0 -0
  87. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_ie.py +0 -0
  88. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_jscript.js +0 -0
  89. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_msscript.py +0 -0
  90. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_outparam.py +0 -0
  91. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_propputref.py +0 -0
  92. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_pump_events.py +0 -0
  93. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_sapi.py +0 -0
  94. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_server.py +0 -0
  95. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_showevents.py +0 -0
  96. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_subinterface.py +0 -0
  97. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_typeinfo.py +0 -0
  98. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_urlhistory.py +0 -0
  99. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_win32com_interop.py +0 -0
  100. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_wmi.py +0 -0
  101. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_word.py +0 -0
  102. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/__init__.py +0 -0
  103. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/util.py +0 -0
  104. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/viewobject.py +0 -0
  105. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/dependency_links.txt +0 -0
  106. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/top_level.txt +0 -0
@@ -1,16 +1,106 @@
1
- import types
2
- import sys
1
+ # comtypes version numbers follow semver (http://semver.org/) and PEP 440
2
+ __version__ = "1.2.1"
3
+
4
+ import atexit
5
+ from ctypes import *
6
+ from ctypes import _SimpleCData
7
+ from _ctypes import COMError
8
+ import logging
3
9
  import os
10
+ import sys
11
+ import types
4
12
 
5
- # comtypes version numbers follow semver (http://semver.org/) and PEP 440
6
- __version__ = "1.1.14"
13
+ ################################################################
14
+
15
+ def add_metaclass(metaclass):
16
+ """Class decorator from six.py for creating a class with a metaclass.
17
+
18
+ Copyright (c) 2010-2020 Benjamin Peterson
19
+
20
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
21
+ this software and associated documentation files (the "Software"), to deal in
22
+ the Software without restriction, including without limitation the rights to
23
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
24
+ the Software, and to permit persons to whom the Software is furnished to do so,
25
+ subject to the following conditions:
26
+
27
+ The above copyright notice and this permission notice shall be included in all
28
+ copies or substantial portions of the Software.
7
29
 
30
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
32
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
33
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
34
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36
+ """
37
+ def wrapper(cls):
38
+ orig_vars = cls.__dict__.copy()
39
+ slots = orig_vars.get('__slots__')
40
+ if slots is not None:
41
+ if isinstance(slots, text_type):
42
+ slots = [slots]
43
+ for slots_var in slots:
44
+ orig_vars.pop(slots_var)
45
+ orig_vars.pop('__dict__', None)
46
+ orig_vars.pop('__weakref__', None)
47
+ if hasattr(cls, '__qualname__'):
48
+ orig_vars['__qualname__'] = cls.__qualname__
49
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
50
+ return wrapper
51
+
52
+ ################################################################
53
+
54
+ # type hinting symbols
55
+ #
56
+ # `if TYPE_CHECKING:` code block must not be executed because `TYPE_CHECKING`
57
+ # is always `False` in runtime.
58
+ # see https://peps.python.org/pep-0484/#runtime-or-type-checking
59
+ #
60
+ if sys.version_info >= (3, 5):
61
+ from typing import TYPE_CHECKING
62
+ else: # typehints in this package don't support Py<3.5 due to importing symbols.
63
+ TYPE_CHECKING = False
64
+ #
65
+ # Annotations must be placed in a `# type:` comment in according to PEP484.
66
+ # see https://peps.python.org/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
67
+ # - `NameError` never raises by using those symbols.
68
+ # - It is not able to use any runtime introspections, such as
69
+ # `typing.get_type_hints` or `typing.get_origin`.
70
+ #
71
+ if TYPE_CHECKING:
72
+ from ctypes import _CData # only in `typeshed`, private in runtime
73
+ # _CData = _SimpleCData.__mro__[:-1][-1] # defining in runtime
74
+ from ctypes import _Pointer
75
+ from typing import Any, ClassVar, overload, TypeVar
76
+ # XXX: symbols for backward compatibility.
77
+ # instead of `builtins`. see PEP585.
78
+ from typing import Dict, List, Tuple, Type
79
+ # instead of `collections.abc`. see PEP585.
80
+ from typing import Callable, Iterable, Iterator
81
+ # instead of `A | B` and `None | A`. see PEP604.
82
+ from typing import Union as _UnionT # avoiding confusion with `ctypes.Union`
83
+ from typing import Optional
84
+ # utilities or workarounds for annotations.
85
+ from comtypes import hints as hints
86
+
87
+ ################################################################
88
+
89
+ from comtypes.GUID import GUID
90
+ from comtypes import patcher
91
+ from comtypes._npsupport import interop as npsupport
92
+ from comtypes._memberspec import (
93
+ ComMemberGenerator, _ComMemberSpec, DispMemberGenerator, _DispMemberSpec,
94
+ _encode_idl, _resolve_argspec,
95
+ )
96
+
97
+ ################################################################
8
98
  if sys.version_info >= (3, 0):
9
99
  text_type = str
10
100
  else:
11
101
  text_type = unicode
102
+ _all_slice = slice(None, None, None)
12
103
 
13
- import logging
14
104
  class NullHandler(logging.Handler):
15
105
  """A Handler that does nothing."""
16
106
  def emit(self, record):
@@ -24,9 +114,6 @@ logger = logging.getLogger(__name__)
24
114
  # when logging is not configured and logger.error() is called.
25
115
  logger.addHandler(NullHandler())
26
116
 
27
- from ctypes import *
28
- from _ctypes import COMError
29
- from comtypes import patcher
30
117
 
31
118
  def _check_version(actual, tlib_cached_mtime=None):
32
119
  from comtypes.tools.codegenerator import version as required
@@ -42,25 +129,6 @@ def _check_version(actual, tlib_cached_mtime=None):
42
129
  if not tlib_cached_mtime or abs(tlib_curr_mtime - tlib_cached_mtime) >= 1:
43
130
  raise ImportError("Typelib different than module")
44
131
 
45
- try:
46
- COMError()
47
- except TypeError:
48
- pass
49
- else:
50
- # Python 2.5 and 2.5.1 have a bug in the COMError implementation:
51
- # The type has no __init__ method, and no hresult, text, and
52
- # details instance vars. Work around this bug by monkeypatching
53
- # COMError.
54
- def monkeypatch_COMError():
55
- def __init__(self, hresult, text, details):
56
- self.hresult = hresult
57
- self.text = text
58
- self.details = details
59
- super(COMError, self).__init__(hresult, text, details)
60
- COMError.__init__ = __init__
61
- monkeypatch_COMError()
62
- del monkeypatch_COMError
63
-
64
132
  if sys.version_info >= (3, 0):
65
133
  pythonapi.PyInstanceMethod_New.argtypes = [py_object]
66
134
  pythonapi.PyInstanceMethod_New.restype = py_object
@@ -85,7 +153,6 @@ class ReturnHRESULT(Exception):
85
153
  ##class IDLWarning(UserWarning):
86
154
  ## "Warn about questionable type information"
87
155
 
88
- from comtypes.GUID import GUID
89
156
  _GUID = GUID
90
157
  IID = GUID
91
158
  DWORD = c_ulong
@@ -192,7 +259,6 @@ def _shutdown(func=_ole32_nohresult.CoUninitialize,
192
259
  _cominterface_meta._com_shutting_down = True
193
260
  _debug("CoUninitialize() done.")
194
261
 
195
- import atexit
196
262
  atexit.register(_shutdown)
197
263
 
198
264
  ################################################################
@@ -225,6 +291,11 @@ class _cominterface_meta(type):
225
291
  """Metaclass for COM interfaces. Automatically creates high level
226
292
  methods from COMMETHOD lists.
227
293
  """
294
+ if TYPE_CHECKING:
295
+ _case_insensitive_ = hints.AnnoField() # type: bool
296
+ _iid_ = hints.AnnoField() # type: GUID
297
+ _methods_ = hints.AnnoField() # type: List[_ComMemberSpec]
298
+ _disp_methods_ = hints.AnnoField() # type: List[_DispMemberSpec]
228
299
 
229
300
  # This flag is set to True by the atexit handler which calls
230
301
  # CoUninitialize.
@@ -443,135 +514,28 @@ class _cominterface_meta(type):
443
514
  self.__map_case__ = d
444
515
 
445
516
  def _make_dispmethods(self, methods):
517
+ # type: (List[_DispMemberSpec]) -> None
446
518
  if self._case_insensitive_:
447
519
  self._make_case_insensitive()
448
-
449
520
  # create dispinterface methods and properties on the interface 'self'
450
- properties = {}
521
+ member_gen = DispMemberGenerator(self.__name__)
451
522
  for m in methods:
452
- what, name, idlflags, restype, argspec = m
453
-
454
- # is it a property set or property get?
455
- is_prop = False
456
-
457
- # argspec is a sequence of tuples, each tuple is:
458
- # ([paramflags], type, name)
459
- try:
460
- memid = [x for x in idlflags if isinstance(x, int)][0]
461
- except IndexError:
462
- raise TypeError("no dispid found in idlflags")
463
- if what == "DISPPROPERTY": # DISPPROPERTY
464
- assert not argspec # XXX does not yet work for properties with parameters
465
- accessor = self._disp_property(memid, idlflags)
466
- is_prop = True
467
- setattr(self, name, accessor)
468
- elif what == "DISPMETHOD": # DISPMETHOD
469
- # argspec is a tuple of (idlflags, type, name[,
470
- # defval]) items.
471
- method = self._disp_method(memid, name, idlflags, restype, argspec)
472
- ## not in 2.3 method.__name__ = name
473
- if 'propget' in idlflags:
474
- nargs = len(argspec)
475
- properties.setdefault((name, nargs), [None, None, None])[0] = method
476
- is_prop = True
477
- elif 'propput' in idlflags:
478
- nargs = len(argspec)-1
479
- properties.setdefault((name, nargs), [None, None, None])[1] = method
480
- is_prop = True
481
- elif 'propputref' in idlflags:
482
- nargs = len(argspec)-1
483
- properties.setdefault((name, nargs), [None, None, None])[2] = method
484
- is_prop = True
485
- else:
486
- setattr(self, name, method)
523
+ member_gen.add(m)
524
+ for name, func_or_prop, is_prop in member_gen.items():
525
+ setattr(self, name, func_or_prop)
487
526
  # COM is case insensitive.
488
- #
489
527
  # For a method, this is the real name. For a property,
490
528
  # this is the name WITHOUT the _set_ or _get_ prefix.
491
529
  if self._case_insensitive_:
492
530
  self.__map_case__[name.lower()] = name
493
531
  if is_prop:
494
532
  self.__map_case__[name[5:].lower()] = name[5:]
495
-
496
- for (name, nargs), methods in properties.items():
497
- # methods contains [propget or None, propput or None, propputref or None]
498
- if methods[1] is not None and methods[2] is not None:
499
- # both propput and propputref.
500
- #
501
- # Create a setter method that examines the argument type
502
- # and calls 'propputref' if it is an Object (in the VB
503
- # sense), or call 'propput' otherwise.
504
- propput = methods[1]
505
- propputref = methods[2]
506
- def put_or_putref(self, *args):
507
- if _is_object(args[-1]):
508
- return propputref(self, *args)
509
- else:
510
- return propput(self, *args)
511
- methods[1] = put_or_putref
512
- del methods[2]
513
- elif methods[2] is not None:
514
- # use propputref
515
- del methods[1]
516
- else:
517
- # use propput (if any)
518
- del methods[2]
519
- if nargs:
520
- setattr(self, name, named_property("%s.%s" % (self.__name__, name), *methods))
521
- else:
522
- assert len(methods) <= 2
523
- setattr(self, name, property(*methods))
524
-
533
+ for name, accessor in member_gen.properties():
534
+ setattr(self, name, accessor)
525
535
  # COM is case insensitive
526
536
  if self._case_insensitive_:
527
537
  self.__map_case__[name.lower()] = name
528
538
 
529
- # Some ideas, (not only) related to disp_methods:
530
- #
531
- # Should the functions/methods we create have restype and/or
532
- # argtypes attributes?
533
-
534
- def _disp_method(self, memid, name, idlflags, restype, argspec):
535
- if 'propget' in idlflags:
536
- def getfunc(obj, *args, **kw):
537
- return self.Invoke(obj, memid, _invkind=2, *args, **kw) # DISPATCH_PROPERTYGET
538
- return getfunc
539
- elif 'propput' in idlflags:
540
- def putfunc(obj, *args, **kw):
541
- return self.Invoke(obj, memid, _invkind=4, *args, **kw) # DISPATCH_PROPERTYPUT
542
- return putfunc
543
- elif 'propputref' in idlflags:
544
- def putfunc(obj, *args, **kw):
545
- return self.Invoke(obj, memid, _invkind=8, *args, **kw) # DISPATCH_PROPERTYPUTREF
546
- return putfunc
547
- # a first attempt to make use of the restype. Still, support
548
- # for named arguments and default argument values should be
549
- # added.
550
- if hasattr(restype, "__com_interface__"):
551
- interface = restype.__com_interface__
552
- def func(s, *args, **kw):
553
- result = self.Invoke(s, memid, _invkind=1, *args, **kw)
554
- if result is None:
555
- return
556
- return result.QueryInterface(interface)
557
- else:
558
- def func(obj, *args, **kw):
559
- return self.Invoke(obj, memid, _invkind=1, *args, **kw) # DISPATCH_METHOD
560
- return func
561
-
562
- def _disp_property(self, memid, idlflags):
563
- # XXX doc string missing in property
564
- def _get(obj):
565
- return obj.Invoke(memid, _invkind=2) # DISPATCH_PROPERTYGET
566
- if "readonly" in idlflags:
567
- return property(_get)
568
- def _set(obj, value):
569
- # Detect whether to use DISPATCH_PROPERTYPUT or
570
- # DISPATCH_PROPERTYPUTREF
571
- invkind = 8 if _is_object(value) else 4
572
- return obj.Invoke(memid, value, _invkind=invkind)
573
- return property(_get, _set)
574
-
575
539
  def __get_baseinterface_methodcount(self):
576
540
  "Return the number of com methods in the base interfaces"
577
541
  try:
@@ -585,353 +549,47 @@ class _cominterface_meta(type):
585
549
  raise TypeError("baseinterface '%s' has no _methods_" % itf.__name__)
586
550
  raise
587
551
 
588
- def _fix_inout_args(self, func, argtypes, paramflags):
589
- # This function provides a workaround for a bug in ctypes.
590
- # [in, out] parameters must be converted with the argtype's
591
- # .from_param() method BEFORE they are passed to the _ctypes
592
- # build_callargs() function in Modules/_ctypes/_ctypes.c.
593
- #
594
- # For details see below.
595
- #
596
- # TODO: The workaround should be disabled when a ctypes
597
- # version is used where the bug is fixed.
598
- SIMPLETYPE = type(c_int)
599
- BYREFTYPE = type(byref(c_int()))
600
- def call_with_inout(self_, *args, **kw):
601
- args = list(args)
602
- # Indexed by order in the output
603
- outargs = {}
604
- outnum = 0
605
- for i, info in enumerate(paramflags):
606
- direction = info[0]
607
- if direction & 3 == 3:
608
- # This is an [in, out] parameter.
609
- #
610
- # Determine name and required type of the parameter.
611
- name = info[1]
612
- # [in, out] parameters are passed as pointers,
613
- # this is the pointed-to type:
614
- atyp = argtypes[i]._type_
615
-
616
- # Get the actual parameter, either as positional or
617
- # keyword arg.
618
- try:
619
- try:
620
- v = args[i]
621
- except IndexError:
622
- v = kw[name]
623
- except KeyError:
624
- # no parameter was passed, make an empty one
625
- # of the required type
626
- v = atyp()
627
- else:
628
- # parameter was passed, call .from_param() to
629
- # convert it to a ctypes type.
630
- if getattr(v, "_type_", None) is atyp:
631
- # Array of or pointer to type 'atyp' was
632
- # passed, pointer to 'atyp' expected.
633
- pass
634
- elif type(atyp) is SIMPLETYPE:
635
- # The from_param method of simple types
636
- # (c_int, c_double, ...) returns a byref()
637
- # object which we cannot use since later
638
- # it will be wrapped in a pointer. Simply
639
- # call the constructor with the argument
640
- # in that case.
641
- v = atyp(v)
642
- else:
643
- v = atyp.from_param(v)
644
- assert not isinstance(v, BYREFTYPE)
645
- outargs[outnum] = v
646
- outnum += 1
647
- if len(args) > i:
648
- args[i] = v
649
- else:
650
- kw[name] = v
651
- elif direction & 2 == 2:
652
- outnum += 1
653
-
654
- rescode = func(self_, *args, **kw)
655
- # If there is only a single output value, then do not expect it to
656
- # be iterable.
657
- if outnum == 1: # rescode is not iterable
658
- if len(outargs) == 1:
659
- rescode = rescode.__ctypes_from_outparam__()
660
- return rescode
661
-
662
- rescode = list(rescode)
663
- for outnum, o in outargs.items():
664
- rescode[outnum] = o.__ctypes_from_outparam__()
665
- return rescode
666
- return call_with_inout
667
-
668
552
  def _make_methods(self, methods):
553
+ # type: (List[_ComMemberSpec]) -> None
669
554
  if self._case_insensitive_:
670
555
  self._make_case_insensitive()
671
-
672
- # we insist on an _iid_ in THIS class!
556
+ # register com interface. we insist on an _iid_ in THIS class!
673
557
  try:
674
558
  iid = self.__dict__["_iid_"]
675
559
  except KeyError:
676
560
  raise AttributeError("this class must define an _iid_")
677
561
  else:
678
- iid = text_type(iid)
679
- ## if iid in com_interface_registry:
680
- ## # Warn when multiple interfaces are defined with identical iids.
681
- ## # This would also trigger if we reload() a module that contains
682
- ## # interface types, so suppress the warning in this case.
683
- ## other = com_interface_registry[iid]
684
- ## if self.__name__ != other.__name__ or self.__module__ != other.__module__:
685
- ## text = "Multiple interface defn: %s, %s" % (self, other)
686
- ## warnings.warn(text, UserWarning)
687
- com_interface_registry[iid] = self
688
- del iid
562
+ com_interface_registry[text_type(iid)] = self
563
+ # create members
689
564
  vtbl_offset = self.__get_baseinterface_methodcount()
690
-
691
- properties = {}
692
-
565
+ member_gen = ComMemberGenerator(self.__name__, vtbl_offset, self._iid_)
693
566
  # create private low level, and public high level methods
694
- for i, item in enumerate(methods):
695
- restype, name, argtypes, paramflags, idlflags, doc = item
696
- # the function prototype
697
- prototype = WINFUNCTYPE(restype, *argtypes)
698
-
699
- # a low level unbound method calling the com method.
700
- # attach it with a private name (__com_AddRef, for example),
701
- # so that custom method implementations can call it.
702
-
703
- # If the method returns a HRESULT, we pass the interface iid,
704
- # so that we can request error info for the interface.
705
- if restype == HRESULT:
706
- ## print "%s.%s" % (self.__name__, name)
707
- raw_func = prototype(i + vtbl_offset, name, None, self._iid_)
708
- func = prototype(i + vtbl_offset, name, paramflags, self._iid_)
709
- else:
710
- raw_func = prototype(i + vtbl_offset, name, None, None)
711
- func = prototype(i + vtbl_offset, name, paramflags, None)
712
- setattr(self,
713
- "_%s__com_%s" % (self.__name__, name),
714
- instancemethod(raw_func, None, self))
715
-
716
- if paramflags:
717
- # see comment in the _fix_inout_args method
718
- dirflags = [(p[0]&3) for p in paramflags]
719
- if 3 in dirflags:
720
- ## fullname = "%s::%s" % (self.__name__, name)
721
- ## print "FIX %s" % fullname
722
- func = self._fix_inout_args(func, argtypes, paramflags)
723
-
724
- # 'func' is a high level function calling the COM method
725
- func.__doc__ = doc
726
- try:
727
- func.__name__ = name # for pyhelp
728
- except TypeError:
729
- # In Python 2.3, __name__ is a readonly attribute
730
- pass
731
- # make it an unbound method. Remember, 'self' is a type here.
567
+ for m in methods:
568
+ member_gen.add(m)
569
+ for name, func, raw_func, is_prop in member_gen.methods():
570
+ raw_mth = instancemethod(raw_func, None, self)
571
+ setattr(self, "_%s__com_%s" % (self.__name__, name), raw_mth)
732
572
  mth = instancemethod(func, None, self)
733
-
734
- # is it a property set or property get?
735
- is_prop = False
736
-
737
- # XXX Hm. What, when paramflags is None?
738
- # Or does have '0' values?
739
- # Seems we loose then, at least for properties...
740
-
741
- # The following code assumes that the docstrings for
742
- # propget and propput are identical.
743
- if "propget" in idlflags:
744
- assert name.startswith("_get_")
745
- nargs = len([flags for flags in paramflags
746
- if flags[0] & 7 in (0, 1)])
747
- # XXX or should we do this?
748
- # nargs = len([flags for flags in paramflags
749
- # if (flags[0] & 1) or (flags[0] == 0)])
750
- propname = name[len("_get_"):]
751
- properties.setdefault((propname, doc, nargs), [None, None, None])[0] = func
752
- is_prop = True
753
- elif "propput" in idlflags:
754
- assert name.startswith("_set_")
755
- nargs = len([flags for flags in paramflags
756
- if flags[0] & 7 in (0, 1)]) - 1
757
- propname = name[len("_set_"):]
758
- properties.setdefault((propname, doc, nargs), [None, None, None])[1] = func
759
- is_prop = True
760
- elif "propputref" in idlflags:
761
- assert name.startswith("_setref_")
762
- nargs = len([flags for flags in paramflags
763
- if flags[0] & 7 in (0, 1)]) - 1
764
- propname = name[len("_setref_"):]
765
- properties.setdefault((propname, doc, nargs), [None, None, None])[2] = func
766
- is_prop = True
767
-
768
- # We install the method in the class, except when it's a
769
- # property accessor. And we make sure we don't overwrite
770
- # a property that's already present in the class.
771
573
  if not is_prop:
772
- if hasattr(self, name):
773
- setattr(self, "_" + name, mth)
774
- else:
775
- setattr(self, name, mth)
776
-
777
- # COM is case insensitive.
778
- #
779
- # For a method, this is the real name. For a property,
780
- # this is the name WITHOUT the _set_ or _get_ prefix.
574
+ # We install the method in the class, except when it's a property.
575
+ # And we make sure we don't overwrite a property that's already present.
576
+ mthname = name if not hasattr(self, name) else ("_%s" % name)
577
+ setattr(self, mthname, mth)
578
+ # For a method, this is the real name.
579
+ # For a property, this is the name WITHOUT the _set_ or _get_ prefix.
781
580
  if self._case_insensitive_:
782
581
  self.__map_case__[name.lower()] = name
783
582
  if is_prop:
784
583
  self.__map_case__[name[5:].lower()] = name[5:]
785
-
786
584
  # create public properties / attribute accessors
787
- for (name, doc, nargs), methods in properties.items():
788
- # methods contains [propget or None, propput or None, propputref or None]
789
- if methods[1] is not None and methods[2] is not None:
790
- # both propput and propputref.
791
- #
792
- # Create a setter method that examines the argument type
793
- # and calls 'propputref' if it is an Object (in the VB
794
- # sense), or call 'propput' otherwise.
795
- propput = methods[1]
796
- propputref = methods[2]
797
- def put_or_putref(self, *args):
798
- if _is_object(args[-1]):
799
- return propputref(self, *args)
800
- else:
801
- return propput(self, *args)
802
- methods[1] = put_or_putref
803
- del methods[2]
804
- elif methods[2] is not None:
805
- # use propputref
806
- del methods[1]
807
- else:
808
- # use propput (if any)
809
- del methods[2]
810
- if nargs == 0:
811
- prop = property(*methods + [None, doc])
812
- else:
813
- # Hm, must be a descriptor where the __get__ method
814
- # returns a bound object having __getitem__ and
815
- # __setitem__ methods.
816
- prop = named_property("%s.%s" % (self.__name__, name), *methods + [doc])
817
- # Again, we should not overwrite class attributes that are
818
- # already present.
819
- if hasattr(self, name):
820
- setattr(self, "_" + name, prop)
821
- else:
822
- setattr(self, name, prop)
823
-
585
+ for name, accessor in member_gen.properties():
586
+ # Again, we should not overwrite class attributes that are already present.
587
+ propname = name if not hasattr(self, name) else ("_%s" % name)
588
+ setattr(self, propname, accessor)
824
589
  # COM is case insensitive
825
590
  if self._case_insensitive_:
826
591
  self.__map_case__[name.lower()] = name
827
592
 
828
-
829
- ################################################################
830
- # helper classes for COM propget / propput
831
- # Should they be implemented in C for speed?
832
-
833
- _all_slice = slice(None, None, None)
834
-
835
-
836
- class bound_named_property(object):
837
- def __init__(self, name, fget, fset, instance):
838
- self.name = name
839
- self.instance = instance
840
- self.fget = fget
841
- self.fset = fset
842
-
843
- def __getitem__(self, index):
844
- if self.fget is None:
845
- raise TypeError("unsubscriptable object")
846
- if isinstance(index, tuple):
847
- return self.fget(self.instance, *index)
848
- elif index == _all_slice:
849
- return self.fget(self.instance)
850
- else:
851
- return self.fget(self.instance, index)
852
-
853
- def __call__(self, *args):
854
- if self.fget is None:
855
- raise TypeError("object is not callable")
856
- return self.fget(self.instance, *args)
857
-
858
- def __setitem__(self, index, value):
859
- if self.fset is None:
860
- raise TypeError("object does not support item assignment")
861
- if isinstance(index, tuple):
862
- self.fset(self.instance, *(index + (value,)))
863
- elif index == _all_slice:
864
- self.fset(self.instance, value)
865
- else:
866
- self.fset(self.instance, index, value)
867
-
868
- def __repr__(self):
869
- return "<bound_named_property %r at %x>" % (self.name, id(self))
870
-
871
- def __iter__(self):
872
- """ Explicitly disallow iteration. """
873
- msg = "%r is not iterable" % self.name
874
- raise TypeError(msg)
875
-
876
-
877
- class named_property(object):
878
- def __init__(self, name, fget=None, fset=None, doc=None):
879
- self.name = name
880
- self.fget = fget
881
- self.fset = fset
882
- self.__doc__ = doc
883
-
884
- def __get__(self, instance, owner=None):
885
- if instance is None:
886
- return self
887
- return bound_named_property(self.name, self.fget, self.fset, instance)
888
-
889
- # Make this a data descriptor
890
- def __set__(self, instance):
891
- raise AttributeError("Unsettable attribute")
892
-
893
- def __repr__(self):
894
- return "<named_property %r at %x>" % (self.name, id(self))
895
-
896
- ################################################################
897
-
898
- def add_metaclass(metaclass):
899
- """Class decorator from six.py for creating a class with a metaclass.
900
-
901
- Copyright (c) 2010-2020 Benjamin Peterson
902
-
903
- Permission is hereby granted, free of charge, to any person obtaining a copy of
904
- this software and associated documentation files (the "Software"), to deal in
905
- the Software without restriction, including without limitation the rights to
906
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
907
- the Software, and to permit persons to whom the Software is furnished to do so,
908
- subject to the following conditions:
909
-
910
- The above copyright notice and this permission notice shall be included in all
911
- copies or substantial portions of the Software.
912
-
913
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
914
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
915
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
916
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
917
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
918
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
919
- """
920
- def wrapper(cls):
921
- orig_vars = cls.__dict__.copy()
922
- slots = orig_vars.get('__slots__')
923
- if slots is not None:
924
- if isinstance(slots, text_type):
925
- slots = [slots]
926
- for slots_var in slots:
927
- orig_vars.pop(slots_var)
928
- orig_vars.pop('__dict__', None)
929
- orig_vars.pop('__weakref__', None)
930
- if hasattr(cls, '__qualname__'):
931
- orig_vars['__qualname__'] = cls.__qualname__
932
- return metaclass(cls.__name__, cls.__bases__, orig_vars)
933
- return wrapper
934
-
935
593
  ################################################################
936
594
 
937
595
  class _compointer_meta(type(c_void_p), _cominterface_meta):
@@ -1027,8 +685,6 @@ class _compointer_base(c_void_p):
1027
685
 
1028
686
  ################################################################
1029
687
 
1030
- from ctypes import _SimpleCData
1031
-
1032
688
  class BSTR(_SimpleCData):
1033
689
  "The windows BSTR data type"
1034
690
  _type_ = "X"
@@ -1072,102 +728,74 @@ class dispid(int):
1072
728
  "Specifies the DISPID of a method or property."
1073
729
 
1074
730
  # XXX STDMETHOD, COMMETHOD, DISPMETHOD, and DISPPROPERTY should return
1075
- # instances with methods, or at least accessors instead of tuple.
731
+ # instances with more methods or properties, and should not behave as an unpackable.
1076
732
 
1077
733
  def STDMETHOD(restype, name, argtypes=()):
1078
734
  "Specifies a COM method slot without idlflags"
1079
- # restype, name, argtypes, paramflags, idlflags, docstring
1080
- return restype, name, argtypes, None, (), None
735
+ return _ComMemberSpec(restype, name, argtypes, None, (), None)
1081
736
 
1082
737
  def DISPMETHOD(idlflags, restype, name, *argspec):
1083
738
  "Specifies a method of a dispinterface"
1084
- return "DISPMETHOD", name, idlflags, restype, argspec
739
+ return _DispMemberSpec("DISPMETHOD", name, tuple(idlflags), restype, argspec)
1085
740
 
1086
741
  def DISPPROPERTY(idlflags, proptype, name):
1087
742
  "Specifies a property of a dispinterface"
1088
- return "DISPPROPERTY", name, idlflags, proptype, ()#, argspec
743
+ return _DispMemberSpec("DISPPROPERTY", name, tuple(idlflags), proptype, ())
1089
744
 
1090
- # COMMETHOD returns:
1091
- # restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext
1092
- #
1093
- # paramflags is a sequence of (flags (integer), paramname (string)
1094
745
  # tuple(idlflags) is for the method itself: (dispid, 'readonly')
1095
- #
1096
- # Example: (HRESULT, 'Width', (c_long,), (2, 'rhs'), (4, 'readonly'), None)
1097
-
1098
- ## sample generated code:
1099
- ## DISPPROPERTY([5, 'readonly'], OLE_YSIZE_HIMETRIC, 'Height'),
1100
- ## DISPMETHOD([6], None, 'Render',
1101
- ## ( [], c_int, 'hdc' ),
1102
- ## ( [], c_int, 'x' ),
1103
- ## ( [], c_int, 'y' ))
1104
-
1105
- ################################################################
1106
746
 
1107
- _PARAMFLAGS = {
1108
- "in": 1,
1109
- "out": 2,
1110
- "lcid": 4,
1111
- "retval": 8,
1112
- "optional": 16,
1113
- }
1114
-
1115
- def _encode_idl(names):
1116
- # sum up all values found in _PARAMFLAGS, ignoring all others.
1117
- return sum([_PARAMFLAGS.get(n, 0) for n in names])
1118
-
1119
- _NOTHING = object()
1120
- def _unpack_argspec(idl, typ, name=None, defval=_NOTHING):
1121
- return idl, typ, name, defval
747
+ # sample generated code:
748
+ # DISPPROPERTY([5, 'readonly'], OLE_YSIZE_HIMETRIC, 'Height'),
749
+ # DISPMETHOD(
750
+ # [6], None, 'Render', ([], c_int, 'hdc'), ([], c_int, 'x'), ([], c_int, 'y')
751
+ # )
1122
752
 
1123
753
  def COMMETHOD(idlflags, restype, methodname, *argspec):
1124
754
  """Specifies a COM method slot with idlflags.
1125
755
 
1126
756
  XXX should explain the sematics of the arguments.
1127
757
  """
1128
- paramflags = []
1129
- argtypes = []
1130
-
1131
758
  # collect all helpstring instances
1132
759
  # We should suppress docstrings when Python is started with -OO
1133
- helptext = [t for t in idlflags if isinstance(t, helpstring)]
1134
760
  # join them together(does this make sense?) and replace by None if empty.
1135
- helptext = "".join(helptext) or None
1136
-
1137
- from comtypes.automation import VARIANT
1138
-
1139
- for item in argspec:
1140
- idl, typ, argname, defval = _unpack_argspec(*item)
1141
- pflags = _encode_idl(idl)
1142
- if "optional" in idl:
1143
- if defval is _NOTHING:
1144
- if typ is VARIANT:
1145
- defval = VARIANT.missing
1146
- elif typ is POINTER(VARIANT):
1147
- defval = pointer(VARIANT.missing)
1148
- else:
1149
- ## msg = ("'optional' only allowed for VARIANT and VARIANT*, not for %s"
1150
- ## % typ.__name__)
1151
- ## warnings.warn(msg, IDLWarning, stacklevel=2)
1152
- defval = typ()
1153
- if defval is _NOTHING:
1154
- paramflags.append((pflags, argname))
1155
- else:
1156
- paramflags.append((pflags, argname, defval))
1157
- argtypes.append(typ)
761
+ helptext = "".join(t for t in idlflags if isinstance(t, helpstring)) or None
762
+ paramflags, argtypes = _resolve_argspec(argspec)
1158
763
  if "propget" in idlflags:
1159
- methodname = "_get_%s" % methodname
764
+ name = "_get_%s" % methodname
1160
765
  elif "propput" in idlflags:
1161
- methodname = "_set_%s" % methodname
766
+ name = "_set_%s" % methodname
1162
767
  elif "propputref" in idlflags:
1163
- methodname = "_setref_%s" % methodname
1164
- return restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext
768
+ name = "_setref_%s" % methodname
769
+ else:
770
+ name = methodname
771
+ return _ComMemberSpec(
772
+ restype, name, argtypes, paramflags, tuple(idlflags), helptext
773
+ )
774
+
1165
775
 
1166
776
  ################################################################
1167
777
  # IUnknown, the root of all evil...
1168
778
 
779
+ if TYPE_CHECKING:
780
+ _T_IUnknown = TypeVar("_T_IUnknown", bound="IUnknown")
781
+
782
+ class _IUnknown_Base(c_void_p):
783
+ """This is workaround to avoid false-positive of static type checking.
784
+
785
+ `IUnknown` behaves as a ctypes type, and `POINTER` can take it.
786
+ This behavior is defined by some metaclasses in runtime.
787
+
788
+ In runtime, this symbol in the namespace is just alias for
789
+ `builtins.object`.
790
+ """
791
+ __com_QueryInterface = hints.AnnoField() # type: Callable[[Any, Any], int]
792
+ __com_AddRef = hints.AnnoField() # type: Callable[[], int]
793
+ __com_Release = hints.AnnoField() # type: Callable[[], int]
794
+ else:
795
+ _IUnknown_Base = object
796
+
1169
797
  @add_metaclass(_cominterface_meta)
1170
- class IUnknown(object):
798
+ class IUnknown(_IUnknown_Base):
1171
799
  """The most basic COM interface.
1172
800
 
1173
801
  Each subclasses of IUnknown must define these class attributes:
@@ -1179,18 +807,24 @@ class IUnknown(object):
1179
807
  The _methods_ list must in VTable order. Methods are specified
1180
808
  with STDMETHOD or COMMETHOD calls.
1181
809
  """
1182
- _case_insensitive_ = False
1183
- _iid_ = GUID("{00000000-0000-0000-C000-000000000046}")
810
+ _case_insensitive_ = False # type: ClassVar[bool]
811
+ _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") # type: ClassVar[GUID]
1184
812
 
1185
813
  _methods_ = [
1186
814
  STDMETHOD(HRESULT, "QueryInterface",
1187
815
  [POINTER(GUID), POINTER(c_void_p)]),
1188
816
  STDMETHOD(c_ulong, "AddRef"),
1189
817
  STDMETHOD(c_ulong, "Release")
1190
- ]
818
+ ] # type: ClassVar[List[_ComMemberSpec]]
1191
819
 
820
+ # NOTE: Why not `QueryInterface(T) -> _Pointer[T]`?
821
+ # Any static type checkers is not able to provide members of `T` from `_Pointer[T]`,
822
+ # regardless of the pointer is able to access members of contents in runtime.
823
+ # And if `isinstance(p, POINTER(T))` is `True`, then `isinstance(p, T)` is also `True`.
824
+ # So returning `T` is not a lie, and good way to know what members the class has.
1192
825
  def QueryInterface(self, interface, iid=None):
1193
- "QueryInterface(interface) -> instance"
826
+ # type: (Type[_T_IUnknown], Optional[GUID]) -> _T_IUnknown
827
+ """QueryInterface(interface) -> instance"""
1194
828
  p = POINTER(interface)()
1195
829
  if iid is None:
1196
830
  iid = interface._iid_
@@ -1198,18 +832,22 @@ class IUnknown(object):
1198
832
  clsid = self.__dict__.get('__clsid')
1199
833
  if clsid is not None:
1200
834
  p.__dict__['__clsid'] = clsid
1201
- return p
835
+ return p # type: ignore
1202
836
 
1203
837
  # these are only so that they get a docstring.
1204
838
  # XXX There should be other ways to install a docstring.
1205
839
  def AddRef(self):
1206
- "Increase the internal refcount by one and return it."
840
+ # type: () -> int
841
+ """Increase the internal refcount by one and return it."""
1207
842
  return self.__com_AddRef()
1208
843
 
1209
844
  def Release(self):
1210
- "Decrease the internal refcount by one and return it."
845
+ # type: () -> int
846
+ """Decrease the internal refcount by one and return it."""
1211
847
  return self.__com_Release()
1212
848
 
849
+
850
+ ################################################################
1213
851
  # IPersist is a trivial interface, which allows to ask an object about
1214
852
  # its clsid.
1215
853
  class IPersist(IUnknown):
@@ -1219,16 +857,23 @@ class IPersist(IUnknown):
1219
857
  COMMETHOD([], HRESULT, 'GetClassID',
1220
858
  ( ['out'], POINTER(GUID), 'pClassID' )),
1221
859
  ]
860
+ if TYPE_CHECKING:
861
+ # Returns the CLSID that uniquely represents an object class that
862
+ # defines the code that can manipulate the object's data.
863
+ GetClassID = hints.AnnoField() # type: Callable[[], GUID]
864
+
1222
865
 
1223
866
  class IServiceProvider(IUnknown):
1224
867
  _iid_ = GUID('{6D5140C1-7436-11CE-8034-00AA006009FA}')
1225
-
868
+ if TYPE_CHECKING:
869
+ _QueryService = hints.AnnoField() # type: Callable[[Any, Any, Any], int]
1226
870
  # Overridden QueryService to make it nicer to use (passing it an
1227
871
  # interface and it returns a pointer to that interface)
1228
872
  def QueryService(self, serviceIID, interface):
873
+ # type: (GUID, Type[_T_IUnknown]) -> _T_IUnknown
1229
874
  p = POINTER(interface)()
1230
875
  self._QueryService(byref(serviceIID), byref(interface._iid_), byref(p))
1231
- return p
876
+ return p # type: ignore
1232
877
 
1233
878
  _methods_ = [
1234
879
  COMMETHOD([], HRESULT, 'QueryService',
@@ -1238,7 +883,19 @@ class IServiceProvider(IUnknown):
1238
883
  ]
1239
884
 
1240
885
  ################################################################
886
+
887
+ if TYPE_CHECKING:
888
+ @overload
889
+ def CoGetObject(displayname, interface): # `interface` can't be missing
890
+ # type: (str, None) -> IUnknown
891
+ pass
892
+ @overload
893
+ def CoGetObject(displayname, interface): # it should be called this way
894
+ # type: (str, Type[_T_IUnknown]) -> _T_IUnknown
895
+ pass
896
+
1241
897
  def CoGetObject(displayname, interface):
898
+ # type: (str, Optional[Type[IUnknown]]) -> IUnknown
1242
899
  """Convert a displayname to a moniker, then bind and return the object
1243
900
  identified by the moniker."""
1244
901
  if interface is None:
@@ -1249,9 +906,23 @@ def CoGetObject(displayname, interface):
1249
906
  None,
1250
907
  byref(interface._iid_),
1251
908
  byref(punk))
1252
- return punk
909
+ return punk # type: ignore
910
+
911
+
912
+ if TYPE_CHECKING:
913
+ pUnkOuter = Type[_Pointer[IUnknown]]
914
+
915
+ @overload
916
+ def CoCreateInstance(clsid, interface=None, clsctx=None, punkouter=None):
917
+ # type: (GUID, None, Optional[int], Optional[pUnkOuter]) -> IUnknown
918
+ pass
919
+ @overload
920
+ def CoCreateInstance(clsid, interface, clsctx=None, punkouter=None):
921
+ # type: (GUID, Type[_T_IUnknown], Optional[int], Optional[pUnkOuter]) -> _T_IUnknown
922
+ pass
1253
923
 
1254
924
  def CoCreateInstance(clsid, interface=None, clsctx=None, punkouter=None):
925
+ # type: (GUID, Optional[Type[IUnknown]], Optional[int], Optional[pUnkOuter]) -> IUnknown
1255
926
  """The basic windows api to create a COM class object and return a
1256
927
  pointer to an interface.
1257
928
  """
@@ -1262,9 +933,21 @@ def CoCreateInstance(clsid, interface=None, clsctx=None, punkouter=None):
1262
933
  p = POINTER(interface)()
1263
934
  iid = interface._iid_
1264
935
  _ole32.CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p))
1265
- return p
936
+ return p # type: ignore
937
+
938
+
939
+ if TYPE_CHECKING:
940
+ @overload
941
+ def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
942
+ # type: (GUID, Optional[int], Optional[COSERVERINFO], None) -> hints.IClassFactory
943
+ pass
944
+ @overload
945
+ def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
946
+ # type: (GUID, Optional[int], Optional[COSERVERINFO], Type[_T_IUnknown]) -> _T_IUnknown
947
+ pass
1266
948
 
1267
949
  def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
950
+ # type: (GUID, Optional[int], Optional[COSERVERINFO], Optional[Type[IUnknown]]) -> IUnknown
1268
951
  if clsctx is None:
1269
952
  clsctx = CLSCTX_SERVER
1270
953
  if interface is None:
@@ -1276,20 +959,37 @@ def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
1276
959
  pServerInfo,
1277
960
  interface._iid_,
1278
961
  byref(p))
1279
- return p
962
+ return p # type: ignore
963
+
964
+
965
+ if TYPE_CHECKING:
966
+ @overload
967
+ def GetActiveObject(clsid, interface=None):
968
+ # type: (GUID, None) -> IUnknown
969
+ pass
970
+ @overload
971
+ def GetActiveObject(clsid, interface):
972
+ # type: (GUID, Type[_T_IUnknown]) -> _T_IUnknown
973
+ pass
1280
974
 
1281
975
  def GetActiveObject(clsid, interface=None):
976
+ # type: (GUID, Optional[Type[IUnknown]]) -> IUnknown
1282
977
  """Retrieves a pointer to a running object"""
1283
978
  p = POINTER(IUnknown)()
1284
979
  oledll.oleaut32.GetActiveObject(byref(clsid), None, byref(p))
1285
980
  if interface is not None:
1286
- p = p.QueryInterface(interface)
1287
- return p
981
+ p = p.QueryInterface(interface) # type: ignore
982
+ return p # type: ignore
983
+
1288
984
 
1289
985
  class MULTI_QI(Structure):
1290
986
  _fields_ = [("pIID", POINTER(GUID)),
1291
987
  ("pItf", POINTER(c_void_p)),
1292
988
  ("hr", HRESULT)]
989
+ if TYPE_CHECKING:
990
+ pIID = hints.AnnoField() # type: GUID
991
+ pItf = hints.AnnoField() # type: _Pointer[c_void_p]
992
+ hr = hints.AnnoField() # type: HRESULT
1293
993
 
1294
994
  class _COAUTHIDENTITY(Structure):
1295
995
  _fields_ = [
@@ -1322,6 +1022,11 @@ class _COSERVERINFO(Structure):
1322
1022
  ('pAuthInfo', POINTER(_COAUTHINFO)),
1323
1023
  ('dwReserved2', c_ulong),
1324
1024
  ]
1025
+ if TYPE_CHECKING:
1026
+ dwReserved1 = hints.AnnoField() # type: int
1027
+ pwszName = hints.AnnoField() # type: Optional[str]
1028
+ pAuthInfo = hints.AnnoField() # type: _COAUTHINFO
1029
+ dwReserved2 = hints.AnnoField() # type: int
1325
1030
  COSERVERINFO = _COSERVERINFO
1326
1031
  _CoGetClassObject = _ole32.CoGetClassObject
1327
1032
  _CoGetClassObject.argtypes = [POINTER(GUID), DWORD, POINTER(COSERVERINFO),
@@ -1380,10 +1085,24 @@ class _SOLE_AUTHENTICATION_LIST(Structure):
1380
1085
  ]
1381
1086
  SOLE_AUTHENTICATION_LIST = _SOLE_AUTHENTICATION_LIST
1382
1087
 
1088
+
1089
+ if TYPE_CHECKING:
1090
+ @overload
1091
+ def CoCreateInstanceEx(
1092
+ clsid, interface=None, clsctx=None, machine=None, pServerInfo=None):
1093
+ # type: (GUID, None, Optional[int], Optional[str], Optional[COSERVERINFO]) -> IUnknown
1094
+ pass
1095
+ @overload
1096
+ def CoCreateInstanceEx(
1097
+ clsid, interface=None, clsctx=None, machine=None, pServerInfo=None):
1098
+ # type: (GUID, Type[_T_IUnknown], Optional[int], Optional[str], Optional[COSERVERINFO]) -> _T_IUnknown
1099
+ pass
1100
+
1383
1101
  def CoCreateInstanceEx(clsid, interface=None,
1384
1102
  clsctx=None,
1385
1103
  machine=None,
1386
1104
  pServerInfo=None):
1105
+ # type: (GUID, Optional[Type[IUnknown]], Optional[int], Optional[str], Optional[COSERVERINFO]) -> IUnknown
1387
1106
  """The basic windows api to create a COM class object and return a
1388
1107
  pointer to an interface, possibly on another machine.
1389
1108
 
@@ -1400,19 +1119,19 @@ def CoCreateInstanceEx(clsid, interface=None,
1400
1119
  elif machine is not None:
1401
1120
  serverinfo = COSERVERINFO()
1402
1121
  serverinfo.pwszName = machine
1403
- pServerInfo = byref(serverinfo)
1122
+ pServerInfo = byref(serverinfo) # type: ignore
1404
1123
 
1405
1124
  if interface is None:
1406
1125
  interface = IUnknown
1407
1126
  multiqi = MULTI_QI()
1408
- multiqi.pIID = pointer(interface._iid_)
1127
+ multiqi.pIID = pointer(interface._iid_) # type: ignore
1409
1128
  _ole32.CoCreateInstanceEx(byref(clsid),
1410
1129
  None,
1411
1130
  clsctx,
1412
1131
  pServerInfo,
1413
1132
  1,
1414
1133
  byref(multiqi))
1415
- return cast(multiqi.pItf, POINTER(interface))
1134
+ return cast(multiqi.pItf, POINTER(interface)) # type: ignore
1416
1135
 
1417
1136
 
1418
1137
  ################################################################
@@ -1428,3 +1147,31 @@ from comtypes._meta import _coclass_meta
1428
1147
  class CoClass(COMObject):
1429
1148
  pass
1430
1149
  ################################################################
1150
+
1151
+
1152
+ __known_symbols__ = [
1153
+ 'BIND_OPTS', 'tagBIND_OPTS', 'BINDOPTS2', 'tagBIND_OPTS2', 'BSTR',
1154
+ '_check_version', 'CLSCTX', 'tagCLSCTX', 'CLSCTX_ALL',
1155
+ 'CLSCTX_DISABLE_AAA', 'CLSCTX_ENABLE_AAA', 'CLSCTX_ENABLE_CODE_DOWNLOAD',
1156
+ 'CLSCTX_FROM_DEFAULT_CONTEXT', 'CLSCTX_INPROC', 'CLSCTX_INPROC_HANDLER',
1157
+ 'CLSCTX_INPROC_HANDLER16', 'CLSCTX_INPROC_SERVER',
1158
+ 'CLSCTX_INPROC_SERVER16', 'CLSCTX_LOCAL_SERVER', 'CLSCTX_NO_CODE_DOWNLOAD',
1159
+ 'CLSCTX_NO_CUSTOM_MARSHAL', 'CLSCTX_NO_FAILURE_LOG',
1160
+ 'CLSCTX_REMOTE_SERVER', 'CLSCTX_RESERVED1', 'CLSCTX_RESERVED2',
1161
+ 'CLSCTX_RESERVED3', 'CLSCTX_RESERVED4', 'CLSCTX_RESERVED5',
1162
+ 'CLSCTX_SERVER', '_COAUTHIDENTITY', 'COAUTHIDENTITY', '_COAUTHINFO',
1163
+ 'COAUTHINFO', 'CoClass', 'CoCreateInstance', 'CoCreateInstanceEx',
1164
+ '_CoGetClassObject', 'CoGetClassObject', 'CoGetObject',
1165
+ 'COINIT_APARTMENTTHREADED', 'COINIT_DISABLE_OLE1DDE',
1166
+ 'COINIT_MULTITHREADED', 'COINIT_SPEED_OVER_MEMORY', 'CoInitialize',
1167
+ 'CoInitializeEx', 'COMError', 'COMMETHOD', 'COMObject', '_COSERVERINFO',
1168
+ 'COSERVERINFO', 'CoUninitialize', 'dispid', 'DISPMETHOD', 'DISPPROPERTY',
1169
+ 'DWORD', 'EOAC_NONE', 'GetActiveObject', '_GUID', 'GUID', 'helpstring',
1170
+ 'IID', 'IPersist', 'IServiceProvider', 'IUnknown', 'MULTI_QI',
1171
+ 'ReturnHRESULT', 'RPC_C_AUTHN_LEVEL_CONNECT', 'RPC_C_AUTHN_WINNT',
1172
+ 'RPC_C_AUTHZ_NONE', 'RPC_C_IMP_LEVEL_IMPERSONATE',
1173
+ '_SEC_WINNT_AUTH_IDENTITY', 'SEC_WINNT_AUTH_IDENTITY',
1174
+ 'SEC_WINNT_AUTH_IDENTITY_UNICODE', '_SOLE_AUTHENTICATION_INFO',
1175
+ 'SOLE_AUTHENTICATION_INFO', '_SOLE_AUTHENTICATION_LIST',
1176
+ 'SOLE_AUTHENTICATION_LIST', 'STDMETHOD', 'wireHWND',
1177
+ ]