Skip to content

Commit

Permalink
Add type annotations to shelllink. (#611)
Browse files Browse the repository at this point in the history
* Remove wildcard imports in `shelllink`.

* Add type annotations to the high-level (overridden) functions.

* Add `Literal` to `hints.pyi`

* Add `TYPE_CHECKING` methods.
  • Loading branch information
junkmd authored Aug 31, 2024
1 parent 4ab97c2 commit 3e3977d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 21 deletions.
2 changes: 2 additions & 0 deletions comtypes/hints.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ from typing import Callable, Iterator, Sequence

if sys.version_info >= (3, 8):
from typing import Protocol
from typing import Literal as Literal
else:
from typing_extensions import Protocol
from typing_extensions import Literal as Literal
if sys.version_info >= (3, 9):
from typing import Annotated as Annotated
else:
Expand Down
93 changes: 72 additions & 21 deletions comtypes/shelllink.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
from __future__ import print_function
from ctypes import *
from ctypes import c_char_p, c_int, c_short, c_wchar_p
from ctypes import POINTER
from ctypes import byref, create_string_buffer, create_unicode_buffer
from ctypes.wintypes import DWORD, WIN32_FIND_DATAA, WIN32_FIND_DATAW, MAX_PATH
from typing import Tuple, TYPE_CHECKING

from comtypes import IUnknown, GUID, COMMETHOD, HRESULT, CoClass


if TYPE_CHECKING:
from comtypes import hints # type: ignore


# for GetPath
SLGP_SHORTPATH = 0x1
SLGP_UNCPRIORITY = 0x2
Expand Down Expand Up @@ -113,31 +122,52 @@ class IShellLinkA(IUnknown):
COMMETHOD([], HRESULT, "SetPath", (["in"], c_char_p, "pszFile")),
]

def GetPath(self, flags=SLGP_SHORTPATH):
if TYPE_CHECKING:
# fmt: off
def GetIDList(self) -> hints.Incomplete: ... # noqa
def SetIDList(self, pidl: hints.Incomplete) -> hints.Incomplete: ... # noqa
def SetDescription(self, pszName: bytes) -> hints.Incomplete: ... # noqa
def SetWorkingDirectory(self, pszDir: bytes) -> hints.Hresult: ... # noqa
def SetArguments(self, pszArgs: bytes) -> hints.Hresult: ... # noqa
@property
def Hotkey(self) -> int: ... # noqa
@Hotkey.setter
def Hotkey(self, pwHotkey: int) -> None: ... # noqa
@property
def ShowCmd(self) -> int: ... # noqa
@ShowCmd.setter
def ShowCmd(self, piShowCmd: int) -> None: ... # noqa
def SetIconLocation(self, pszIconPath: bytes, iIcon: int) -> hints.Hresult: ... # noqa
def SetRelativePath(self, pszPathRel: bytes, dwReserved: hints.Literal[0]) -> hints.Hresult: ... # noqa
def Resolve(self, hwnd: int, fFlags: int) -> hints.Hresult: ... # noqa
def SetPath(self, pszFile: bytes) -> hints.Hresult: ... # noqa
# fmt: on

def GetPath(self, flags: int = SLGP_SHORTPATH) -> bytes:
buf = create_string_buffer(MAX_PATH)
# We're not interested in WIN32_FIND_DATA
self.__com_GetPath(buf, MAX_PATH, None, flags)
self.__com_GetPath(buf, MAX_PATH, None, flags) # type: ignore
return buf.value

def GetDescription(self):
def GetDescription(self) -> bytes:
buf = create_string_buffer(1024)
self.__com_GetDescription(buf, 1024)
self.__com_GetDescription(buf, 1024) # type: ignore
return buf.value

def GetWorkingDirectory(self):
def GetWorkingDirectory(self) -> bytes:
buf = create_string_buffer(MAX_PATH)
self.__com_GetWorkingDirectory(buf, MAX_PATH)
self.__com_GetWorkingDirectory(buf, MAX_PATH) # type: ignore
return buf.value

def GetArguments(self):
def GetArguments(self) -> bytes:
buf = create_string_buffer(1024)
self.__com_GetArguments(buf, 1024)
self.__com_GetArguments(buf, 1024) # type: ignore
return buf.value

def GetIconLocation(self):
def GetIconLocation(self) -> Tuple[bytes, int]:
iIcon = c_int()
buf = create_string_buffer(MAX_PATH)
self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon))
self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon)) # type: ignore
return buf.value, iIcon.value


Expand Down Expand Up @@ -226,31 +256,52 @@ class IShellLinkW(IUnknown):
COMMETHOD([], HRESULT, "SetPath", (["in"], c_wchar_p, "pszFile")),
]

def GetPath(self, flags=SLGP_SHORTPATH):
if TYPE_CHECKING:
# fmt: off
def GetIDList(self) -> hints.Incomplete: ... # noqa
def SetIDList(self, pidl: hints.Incomplete) -> hints.Incomplete: ... # noqa
def SetDescription(self, pszName: str) -> hints.Incomplete: ... # noqa
def SetWorkingDirectory(self, pszDir: str) -> hints.Hresult: ... # noqa
def SetArguments(self, pszArgs: str) -> hints.Hresult: ... # noqa
@property
def Hotkey(self) -> int: ... # noqa
@Hotkey.setter
def Hotkey(self, pwHotkey: int) -> None: ... # noqa
@property
def ShowCmd(self) -> int: ... # noqa
@ShowCmd.setter
def ShowCmd(self, piShowCmd: int) -> None: ... # noqa
def SetIconLocation(self, pszIconPath: str, iIcon: int) -> hints.Hresult: ... # noqa
def SetRelativePath(self, pszPathRel: str, dwReserved: hints.Literal[0]) -> hints.Hresult: ... # noqa
def Resolve(self, hwnd: int, fFlags: int) -> hints.Hresult: ... # noqa
def SetPath(self, pszFile: str) -> hints.Hresult: ... # noqa
# fmt: on

def GetPath(self, flags: int = SLGP_SHORTPATH) -> str:
buf = create_unicode_buffer(MAX_PATH)
# We're not interested in WIN32_FIND_DATA
self.__com_GetPath(buf, MAX_PATH, None, flags)
self.__com_GetPath(buf, MAX_PATH, None, flags) # type: ignore
return buf.value

def GetDescription(self):
def GetDescription(self) -> str:
buf = create_unicode_buffer(1024)
self.__com_GetDescription(buf, 1024)
self.__com_GetDescription(buf, 1024) # type: ignore
return buf.value

def GetWorkingDirectory(self):
def GetWorkingDirectory(self) -> str:
buf = create_unicode_buffer(MAX_PATH)
self.__com_GetWorkingDirectory(buf, MAX_PATH)
self.__com_GetWorkingDirectory(buf, MAX_PATH) # type: ignore
return buf.value

def GetArguments(self):
def GetArguments(self) -> str:
buf = create_unicode_buffer(1024)
self.__com_GetArguments(buf, 1024)
self.__com_GetArguments(buf, 1024) # type: ignore
return buf.value

def GetIconLocation(self):
def GetIconLocation(self) -> Tuple[str, int]:
iIcon = c_int()
buf = create_unicode_buffer(MAX_PATH)
self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon))
self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon)) # type: ignore
return buf.value, iIcon.value


Expand Down

0 comments on commit 3e3977d

Please sign in to comment.