Skip to content

Commit bd40642

Browse files
authored
Improve typings in server/register.py. (#734)
* Add more type annotations to `server/register.py`. * Remove `Set = set` from `server/register.py` * Fix `_non_zero`. Because "The object that this function returns will be returned from the foreign function call". https://docs.python.org/3/library/ctypes.html#ctypes._CFuncPtr.errcheck * Add `# type: ignore`. * Improve importing `_ctypes`.
1 parent 781e8e2 commit bd40642

File tree

1 file changed

+20
-22
lines changed

1 file changed

+20
-22
lines changed

comtypes/server/register.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@
3636
python mycomobj.py /nodebug
3737
"""
3838

39+
import _ctypes
3940
import ctypes
4041
import logging
4142
import os
4243
import sys
4344
import winreg
4445
from ctypes import WinError, windll
45-
from typing import Iterator, Tuple
46+
from typing import Iterator, List, Optional, Tuple, Type, Union
4647

4748
import comtypes
4849
import comtypes.server.inprocserver
@@ -58,7 +59,7 @@
5859
_debug = logging.getLogger(__name__).debug
5960

6061

61-
def get_winerror(exception):
62+
def get_winerror(exception: OSError) -> Optional[int]:
6263
try:
6364
return exception.winerror
6465
except AttributeError:
@@ -69,14 +70,13 @@ def get_winerror(exception):
6970
def _non_zero(retval, func, args):
7071
if retval:
7172
raise WinError(retval)
73+
return retval
7274

7375

7476
SHDeleteKey = windll.shlwapi.SHDeleteKeyW
7577
SHDeleteKey.errcheck = _non_zero
7678
SHDeleteKey.argtypes = ctypes.c_ulong, ctypes.c_wchar_p
7779

78-
Set = set
79-
8080

8181
_KEYS = {
8282
winreg.HKEY_CLASSES_ROOT: "HKCR",
@@ -85,7 +85,7 @@ def _non_zero(retval, func, args):
8585
}
8686

8787

88-
def _explain(hkey):
88+
def _explain(hkey: int) -> Union[str, int]:
8989
return _KEYS.get(hkey, hkey)
9090

9191

@@ -99,7 +99,7 @@ class Registrar(object):
9999
work.
100100
"""
101101

102-
def nodebug(self, cls):
102+
def nodebug(self, cls: Type) -> None:
103103
"""Delete logging entries from the registry."""
104104
clsid = cls._reg_clsid_
105105
try:
@@ -113,7 +113,7 @@ def nodebug(self, cls):
113113
if get_winerror(detail) != 2:
114114
raise
115115

116-
def debug(self, cls, levels, format):
116+
def debug(self, cls: Type, levels: List[str], format: Optional[str]) -> None:
117117
"""Write entries in the registry to setup logging for this clsid."""
118118
# handlers
119119
# format
@@ -140,7 +140,7 @@ def debug(self, cls, levels, format):
140140
if get_winerror(detail) != 2:
141141
raise
142142

143-
def register(self, cls, executable=None):
143+
def register(self, cls: Type, executable: Optional[str] = None) -> None:
144144
"""Register the COM server class."""
145145
# First, we unregister the object with force=True, to force removal
146146
# of all registry entries, even if we would not write them.
@@ -153,7 +153,7 @@ def register(self, cls, executable=None):
153153
self._unregister(cls, force=True)
154154
self._register(cls, executable)
155155

156-
def _register(self, cls, executable=None):
156+
def _register(self, cls: Type, executable: Optional[str] = None) -> None:
157157
table = sorted(RegistryEntries(cls))
158158
_debug("Registering %s", cls)
159159
for hkey, subkey, valuename, value in table:
@@ -179,15 +179,15 @@ def _register(self, cls, executable=None):
179179
LoadTypeLibEx(path, REGKIND_REGISTER)
180180
_debug("Done")
181181

182-
def unregister(self, cls, force=False):
182+
def unregister(self, cls: Type, force: bool = False) -> None:
183183
"""Unregister the COM server class."""
184184
mth = getattr(cls, "_unregister", None)
185185
if mth is not None:
186186
mth(self)
187187
else:
188188
self._unregister(cls, force=force)
189189

190-
def _unregister(self, cls, force=False):
190+
def _unregister(self, cls: Type, force: bool = False) -> None:
191191
# If force==False, we only remove those entries that we
192192
# actually would have written. It seems ATL does the same.
193193
table = [t[:2] for t in RegistryEntries(cls)]
@@ -221,31 +221,29 @@ def _unregister(self, cls, force=False):
221221
_debug("Done")
222222

223223

224-
def _get_serverdll():
224+
def _get_serverdll() -> str:
225225
"""Return the pathname of the dll hosting the COM object."""
226226
handle = getattr(sys, "frozendllhandle", None)
227227
if handle is not None:
228228
return GetModuleFileName(handle, 260)
229-
import _ctypes
230-
231229
return _ctypes.__file__
232230

233231

234232
class RegistryEntries(object):
235-
def __init__(self, cls):
233+
def __init__(self, cls: Type) -> None:
236234
self._cls = cls
237235

238-
def _get_full_classname(self, cls):
236+
def _get_full_classname(self, cls: Type) -> str:
239237
"""Return <modulename>.<classname> for 'cls'."""
240238
modname = cls.__module__
241239
if modname == "__main__":
242240
modname = os.path.splitext(os.path.basename(sys.argv[0]))[0]
243241
return f"{modname}.{cls.__name__}"
244242

245-
def _get_pythonpath(self, cls):
243+
def _get_pythonpath(self, cls: Type) -> str:
246244
"""Return the filesystem path of the module containing 'cls'."""
247245
modname = cls.__module__
248-
dirname = os.path.dirname(sys.modules[modname].__file__)
246+
dirname = os.path.dirname(sys.modules[modname].__file__) # type: ignore
249247
return os.path.abspath(dirname)
250248

251249
def __iter__(self) -> Iterator[Tuple[int, str, str, str]]:
@@ -321,7 +319,7 @@ def __iter__(self) -> Iterator[Tuple[int, str, str, str]]:
321319
if not hasattr(sys, "frozen"):
322320
if not __debug__:
323321
exe = f"{exe} -O"
324-
script = os.path.abspath(sys.modules[cls.__module__].__file__)
322+
script = os.path.abspath(sys.modules[cls.__module__].__file__) # type: ignore
325323
if " " in script:
326324
script = f'"{script}"'
327325
yield (HKCR, rf"CLSID\{reg_clsid}\LocalServer32", "", f"{exe} {script}")
@@ -367,15 +365,15 @@ def __iter__(self) -> Iterator[Tuple[int, str, str, str]]:
367365
################################################################
368366

369367

370-
def register(cls):
368+
def register(cls: Type) -> None:
371369
Registrar().register(cls)
372370

373371

374-
def unregister(cls):
372+
def unregister(cls: Type) -> None:
375373
Registrar().unregister(cls)
376374

377375

378-
def UseCommandLine(*classes):
376+
def UseCommandLine(*classes: Type) -> int:
379377
usage = f"""Usage: {sys.argv[0]} [-regserver] [-unregserver] [-nodebug] [-f logformat] [-l loggername=level]"""
380378
opts, args = w_getopt.w_getopt(
381379
sys.argv[1:], "regserver unregserver embedding l: f: nodebug"

0 commit comments

Comments
 (0)