11from __future__ import print_function
22import os
33import sys
4- from ctypes import windll
5- from ctypes import c_void_p
6- from ctypes import sizeof
7- from ctypes import alignment
8-
9- from comtypes import automation
10- from comtypes import typeinfo
11- from comtypes import COMError
4+ from ctypes import alignment , c_void_p , sizeof , windll
5+
6+ from comtypes import automation , COMError , TYPE_CHECKING , typeinfo
127from comtypes .tools import typedesc
138from comtypes .client ._code_cache import _get_module_filename
149
10+ if TYPE_CHECKING :
11+ from typing import (
12+ Any , Callable , Dict , List , Optional , Type , TypeVar , Tuple ,
13+ Union as _UnionT ,
14+ )
15+ from ctypes import _CData , _Pointer
16+ from comtypes import hints
17+
1518
1619# Is the process 64-bit?
1720is_64bits = sys .maxsize > 2 ** 32
@@ -105,25 +108,26 @@ def midlSAFEARRAY(typ):
105108################################################################
106109
107110class Parser (object ):
111+ if TYPE_CHECKING :
112+ tlib = hints .AnnoField () # type: typeinfo.ITypeLib
113+ items = hints .AnnoField () # type: Dict[str, Any]
108114
109115 def make_type (self , tdesc , tinfo ):
110- try :
116+ # type: (typeinfo.TYPEDESC, typeinfo.ITypeInfo) -> Any
117+ if tdesc .vt in COMTYPES :
111118 return COMTYPES [tdesc .vt ]
112- except KeyError :
113- pass
114-
115119 if tdesc .vt == automation .VT_CARRAY :
116- typ = self .make_type (tdesc ._ .lpadesc [0 ].tdescElem , tinfo )
117- for i in range (tdesc ._ .lpadesc [0 ].cDims ):
118- typ = typedesc .ArrayType (typ ,
119- tdesc ._ .lpadesc [0 ].rgbounds [i ].lLbound ,
120- tdesc ._ .lpadesc [0 ].rgbounds [i ].cElements - 1 )
120+ arraydesc = tdesc ._ .lpadesc [0 ] # type: typeinfo.tagARRAYDESC
121+ typ = self .make_type (arraydesc .tdescElem , tinfo )
122+ for i in range (arraydesc .cDims ):
123+ typ = typedesc .ArrayType (
124+ typ , arraydesc .rgbounds [i ].lLbound , arraydesc .rgbounds [i ].cElements - 1
125+ )
121126 return typ
122-
123127 elif tdesc .vt == automation .VT_PTR :
124- typ = self .make_type (tdesc ._ .lptdesc [0 ], tinfo )
128+ ptrdesc = tdesc ._ .lptdesc [0 ] # type: typeinfo.TYPEDESC
129+ typ = self .make_type (ptrdesc , tinfo )
125130 return PTR (typ )
126-
127131 elif tdesc .vt == automation .VT_USERDEFINED :
128132 try :
129133 ti = tinfo .GetRefTypeInfo (tdesc ._ .hreftype )
@@ -136,26 +140,24 @@ def make_type(self, tdesc, tinfo):
136140 (tlib_name , details , type_name )
137141 import warnings
138142 warnings .warn (message , UserWarning );
139- result = typedesc .Structure (type_name ,
140- align = 8 ,
141- members = [], bases = [],
142- size = 0 )
143+ result = typedesc .Structure (
144+ type_name , align = 8 , members = [], bases = [], size = 0
145+ )
143146 return result
144147 result = self .parse_typeinfo (ti )
145148 assert result is not None , ti .GetDocumentation (- 1 )[0 ]
146149 return result
147-
148150 elif tdesc .vt == automation .VT_SAFEARRAY :
149151 # SAFEARRAY(<type>), see Don Box pp.331f
150- itemtype = self .make_type (tdesc ._ .lptdesc [0 ], tinfo )
151- return midlSAFEARRAY (itemtype )
152-
152+ safearraydesc = tdesc ._ .lptdesc [0 ] # type: typeinfo.TYPEDESC
153+ return midlSAFEARRAY (self .make_type (safearraydesc , tinfo ))
153154 raise NotImplementedError (tdesc .vt )
154155
155156 ################################################################
156157
157158 # TKIND_ENUM = 0
158159 def ParseEnum (self , tinfo , ta ):
160+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> typedesc.Enumeration
159161 ta = tinfo .GetTypeAttr ()
160162 enum_name = tinfo .GetDocumentation (- 1 )[0 ]
161163 enum = typedesc .Enumeration (enum_name , 32 , 32 )
@@ -165,13 +167,14 @@ def ParseEnum(self, tinfo, ta):
165167 vd = tinfo .GetVarDesc (i )
166168 name = tinfo .GetDocumentation (vd .memid )[0 ]
167169 assert vd .varkind == typeinfo .VAR_CONST
168- num_val = vd ._ .lpvarValue [0 ].value
170+ num_val = vd ._ .lpvarValue [0 ].value # type: int
169171 v = typedesc .EnumValue (name , num_val , enum )
170172 enum .add_value (v )
171173 return enum
172174
173175 # TKIND_RECORD = 1
174176 def ParseRecord (self , tinfo , ta ):
177+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> typedesc.Structure
175178 members = [] # will be filled later
176179 struct_name , doc , helpcntext , helpfile = tinfo .GetDocumentation (- 1 )
177180 struct = typedesc .Structure (struct_name ,
@@ -211,6 +214,7 @@ def ParseRecord(self, tinfo, ta):
211214
212215 # TKIND_MODULE = 2
213216 def ParseModule (self , tinfo , ta ):
217+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> None
214218 assert 0 == ta .cImplTypes
215219 # functions
216220 for i in range (ta .cFuncs ):
@@ -253,6 +257,7 @@ def ParseModule(self, tinfo, ta):
253257
254258 # TKIND_INTERFACE = 3
255259 def ParseInterface (self , tinfo , ta ):
260+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> Optional[typedesc.ComInterface]
256261 itf_name , itf_doc = tinfo .GetDocumentation (- 1 )[0 :2 ]
257262 assert ta .cImplTypes <= 1
258263 if ta .cImplTypes == 0 and itf_name != "IUnknown" :
@@ -284,7 +289,6 @@ def ParseInterface(self, tinfo, ta):
284289 members = []
285290 for i in range (ta .cFuncs ):
286291 fd = tinfo .GetFuncDesc (i )
287- ## func_name = tinfo.GetDocumentation(fd.memid)[0]
288292 func_name , func_doc = tinfo .GetDocumentation (fd .memid )[:2 ]
289293 assert fd .funckind == typeinfo .FUNC_PUREVIRTUAL
290294 returns = self .make_type (fd .elemdescFunc .tdesc , tinfo )
@@ -295,15 +299,14 @@ def ParseInterface(self, tinfo, ta):
295299 flags = self .func_flags (fd .wFuncFlags )
296300 flags += self .inv_kind (fd .invkind )
297301 mth = typedesc .ComMethod (fd .invkind , fd .memid , func_name , returns , flags , func_doc )
298- mth .oVft = fd .oVft
299302 for p in range (fd .cParams ):
300303 typ = self .make_type (fd .lprgelemdescParam [p ].tdesc , tinfo )
301304 name = names [p + 1 ]
302305 flags = fd .lprgelemdescParam [p ]._ .paramdesc .wParamFlags
303306 if flags & typeinfo .PARAMFLAG_FHASDEFAULT :
304307 # XXX should be handled by VARIANT itself
305308 var = fd .lprgelemdescParam [p ]._ .paramdesc .pparamdescex [0 ].varDefaultValue
306- default = var .value
309+ default = var .value # type: Any
307310 else :
308311 default = None
309312 mth .add_argument (typ , name , self .param_flags (flags ), default )
@@ -317,6 +320,7 @@ def ParseInterface(self, tinfo, ta):
317320
318321 # TKIND_DISPATCH = 4
319322 def ParseDispatch (self , tinfo , ta ):
323+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> typedesc.DispInterface
320324 itf_name , doc = tinfo .GetDocumentation (- 1 )[0 :2 ]
321325 assert ta .cImplTypes == 1
322326
@@ -372,27 +376,29 @@ def ParseDispatch(self, tinfo, ta):
372376 flags += self .inv_kind (fd .invkind )
373377 mth = typedesc .DispMethod (fd .memid , fd .invkind , func_name , returns , flags , func_doc )
374378 for p in range (fd .cParams ):
375- typ = self .make_type (fd .lprgelemdescParam [p ].tdesc , tinfo )
379+ descparam = fd .lprgelemdescParam [p ]
380+ typ = self .make_type (descparam .tdesc , tinfo )
376381 name = names [p + 1 ]
377- flags = fd . lprgelemdescParam [ p ] ._ .paramdesc .wParamFlags
382+ flags = descparam ._ .paramdesc .wParamFlags
378383 if flags & typeinfo .PARAMFLAG_FHASDEFAULT :
379- var = fd . lprgelemdescParam [ p ]. _ .paramdesc .pparamdescex [0 ].varDefaultValue
380- default = var .value
384+ var = descparam . _ .paramdesc .pparamdescex [0 ].varDefaultValue # type: ignore
385+ default = var .value # type: Any
381386 else :
382387 default = None
383388 mth .add_argument (typ , name , self .param_flags (flags ), default )
384389 itf .members .append (mth )
385-
386390 return itf
387391
388392 def inv_kind (self , invkind ):
393+ # type: (int) -> List[str]
389394 NAMES = {automation .DISPATCH_METHOD : [],
390395 automation .DISPATCH_PROPERTYPUT : ["propput" ],
391396 automation .DISPATCH_PROPERTYPUTREF : ["propputref" ],
392397 automation .DISPATCH_PROPERTYGET : ["propget" ]}
393398 return NAMES [invkind ]
394399
395400 def func_flags (self , flags ):
401+ # type: (int) -> List[str]
396402 # map FUNCFLAGS values to idl attributes
397403 NAMES = {typeinfo .FUNCFLAG_FRESTRICTED : "restricted" ,
398404 typeinfo .FUNCFLAG_FSOURCE : "source" ,
@@ -410,6 +416,7 @@ def func_flags(self, flags):
410416 return [NAMES [bit ] for bit in NAMES if bit & flags ]
411417
412418 def param_flags (self , flags ):
419+ # type: (int) -> List[str]
413420 # map PARAMFLAGS values to idl attributes
414421 NAMES = {typeinfo .PARAMFLAG_FIN : "in" ,
415422 typeinfo .PARAMFLAG_FOUT : "out" ,
@@ -422,6 +429,7 @@ def param_flags(self, flags):
422429 return [NAMES [bit ] for bit in NAMES if bit & flags ]
423430
424431 def coclass_type_flags (self , flags ):
432+ # type: (int) -> List[str]
425433 # map TYPEFLAGS values to idl attributes
426434 NAMES = {typeinfo .TYPEFLAG_FAPPOBJECT : "appobject" ,
427435 # typeinfo.TYPEFLAG_FCANCREATE:
@@ -444,6 +452,7 @@ def coclass_type_flags(self, flags):
444452 [NEGATIVE_NAMES [bit ] for bit in NEGATIVE_NAMES if not (bit & flags )]
445453
446454 def interface_type_flags (self , flags ):
455+ # type: (int) -> List[str]
447456 # map TYPEFLAGS values to idl attributes
448457 NAMES = {typeinfo .TYPEFLAG_FAPPOBJECT : "appobject" ,
449458 # typeinfo.TYPEFLAG_FCANCREATE:
@@ -466,6 +475,7 @@ def interface_type_flags(self, flags):
466475 [NEGATIVE_NAMES [bit ] for bit in NEGATIVE_NAMES if not (bit & flags )]
467476
468477 def var_flags (self , flags ):
478+ # type: (int) -> List[str]
469479 NAMES = {typeinfo .VARFLAG_FREADONLY : "readonly" ,
470480 typeinfo .VARFLAG_FSOURCE : "source" ,
471481 typeinfo .VARFLAG_FBINDABLE : "bindable" ,
@@ -482,9 +492,9 @@ def var_flags(self, flags):
482492 }
483493 return [NAMES [bit ] for bit in NAMES if bit & flags ]
484494
485-
486495 # TKIND_COCLASS = 5
487496 def ParseCoClass (self , tinfo , ta ):
497+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> typedesc.CoClass
488498 # possible ta.wTypeFlags: helpstring, helpcontext, licensed,
489499 # version, control, hidden, and appobject
490500 coclass_name , doc = tinfo .GetDocumentation (- 1 )[0 :2 ]
@@ -507,6 +517,7 @@ def ParseCoClass(self, tinfo, ta):
507517
508518 # TKIND_ALIAS = 6
509519 def ParseAlias (self , tinfo , ta ):
520+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> typedesc.Typedef
510521 name = tinfo .GetDocumentation (- 1 )[0 ]
511522 typ = self .make_type (ta .tdescAlias , tinfo )
512523 alias = typedesc .Typedef (name , typ )
@@ -515,6 +526,7 @@ def ParseAlias(self, tinfo, ta):
515526
516527 # TKIND_UNION = 7
517528 def ParseUnion (self , tinfo , ta ):
529+ # type: (typeinfo.ITypeInfo, typeinfo.TYPEATTR) -> typedesc.Union
518530 union_name , doc , helpcntext , helpfile = tinfo .GetDocumentation (- 1 )
519531 members = []
520532 union = typedesc .Union (union_name ,
@@ -549,13 +561,15 @@ def ParseUnion(self, tinfo, ta):
549561 ################################################################
550562
551563 def _typelib_module (self , tlib = None ):
564+ # type: (Optional[typeinfo.ITypeLib]) -> str
552565 if tlib is None :
553566 tlib = self .tlib
554567 # return a string that uniquely identifies a typelib.
555568 # The string doesn't have any meaning outside this instance.
556569 return str (tlib .GetLibAttr ())
557570
558571 def _register (self , name , value , tlib = None ):
572+ # type: (Optional[str], Any, Optional[typeinfo.ITypeLib]) -> None
559573 modname = self ._typelib_module (tlib )
560574 fullname = "%s.%s" % (modname , name )
561575 if fullname in self .items :
@@ -567,6 +581,7 @@ def _register(self, name, value, tlib=None):
567581 self .items [fullname ] = value
568582
569583 def parse_typeinfo (self , tinfo ):
584+ # type: (typeinfo.ITypeInfo) -> Any
570585 name = tinfo .GetDocumentation (- 1 )[0 ]
571586 modname = self ._typelib_module ()
572587 try :
@@ -579,11 +594,9 @@ def parse_typeinfo(self, tinfo):
579594 ta = tinfo .GetTypeAttr ()
580595 size = ta .cbSizeInstance * 8
581596 align = ta .cbAlignment * 8
582- typ = typedesc .External (tlib ,
583- name ,
584- size ,
585- align ,
586- tlib .GetDocumentation (- 1 )[:2 ])
597+ typ = typedesc .External (
598+ tlib , name , size , align , tlib .GetDocumentation (- 1 )[:2 ]
599+ )
587600 self ._register (name , typ , tlib )
588601 return typ
589602
0 commit comments