From b55fed42ed4b62a106bbf29c10d5bc6f19a473f6 Mon Sep 17 00:00:00 2001 From: Fares Ahmed Date: Thu, 24 Feb 2022 00:10:20 +0200 Subject: [PATCH] Add stubs for `pynput` package (#7177) Fixes #4328 --- stubs/pynput/METADATA.toml | 2 + stubs/pynput/pynput/__init__.pyi | 1 + stubs/pynput/pynput/_info.pyi | 2 + stubs/pynput/pynput/_util.pyi | 70 +++++++++++++ stubs/pynput/pynput/keyboard/__init__.pyi | 30 ++++++ stubs/pynput/pynput/keyboard/_base.pyi | 122 ++++++++++++++++++++++ stubs/pynput/pynput/keyboard/_dummy.pyi | 1 + stubs/pynput/pynput/mouse/__init__.pyi | 29 +++++ stubs/pynput/pynput/mouse/_base.pyi | 39 +++++++ stubs/pynput/pynput/mouse/_dummy.pyi | 1 + 10 files changed, 297 insertions(+) create mode 100644 stubs/pynput/METADATA.toml create mode 100644 stubs/pynput/pynput/__init__.pyi create mode 100644 stubs/pynput/pynput/_info.pyi create mode 100644 stubs/pynput/pynput/_util.pyi create mode 100644 stubs/pynput/pynput/keyboard/__init__.pyi create mode 100644 stubs/pynput/pynput/keyboard/_base.pyi create mode 100644 stubs/pynput/pynput/keyboard/_dummy.pyi create mode 100644 stubs/pynput/pynput/mouse/__init__.pyi create mode 100644 stubs/pynput/pynput/mouse/_base.pyi create mode 100644 stubs/pynput/pynput/mouse/_dummy.pyi diff --git a/stubs/pynput/METADATA.toml b/stubs/pynput/METADATA.toml new file mode 100644 index 000000000..0e0a8a353 --- /dev/null +++ b/stubs/pynput/METADATA.toml @@ -0,0 +1,2 @@ +version = "1.7.*" +stubtest = false # A display server (e.g. X11) is required to import pynput diff --git a/stubs/pynput/pynput/__init__.pyi b/stubs/pynput/pynput/__init__.pyi new file mode 100644 index 000000000..1b92738f9 --- /dev/null +++ b/stubs/pynput/pynput/__init__.pyi @@ -0,0 +1 @@ +from . import keyboard as keyboard, mouse as mouse diff --git a/stubs/pynput/pynput/_info.pyi b/stubs/pynput/pynput/_info.pyi new file mode 100644 index 000000000..e6655bdd2 --- /dev/null +++ b/stubs/pynput/pynput/_info.pyi @@ -0,0 +1,2 @@ +__author__: str +__version__: tuple[int, int, int] diff --git a/stubs/pynput/pynput/_util.pyi b/stubs/pynput/pynput/_util.pyi new file mode 100644 index 000000000..417d00ac3 --- /dev/null +++ b/stubs/pynput/pynput/_util.pyi @@ -0,0 +1,70 @@ +import sys +import threading +from _typeshed import Self +from collections.abc import Callable +from queue import Queue +from types import ModuleType, TracebackType +from typing import Any, ClassVar, Generic, TypeVar +from typing_extensions import ParamSpec, TypedDict + +_T = TypeVar("_T") +_AbstractListener_T = TypeVar("_AbstractListener_T", bound=AbstractListener) +_P = ParamSpec("_P") + +class _RESOLUTIONS(TypedDict): + darwin: str + uinput: str + xorg: str + +RESOLUTIONS: _RESOLUTIONS + +def backend(package: str) -> ModuleType: ... +def prefix(base: type | tuple[type | tuple[Any, ...], ...], cls: type) -> str | None: ... + +class AbstractListener(threading.Thread): + class StopException(Exception): ... + _HANDLED_EXCEPTIONS: ClassVar[tuple[type | tuple[Any, ...], ...]] # undocumented + _suppress: bool # undocumented + _running: bool # undocumented + _thread: threading.Thread # undocumented + _condition: threading.Condition # undocumented + _ready: bool # undocumented + _queue: Queue[sys._OptExcInfo | None] # undocumented + daemon: bool + def __init__(self, suppress: bool = ..., **kwargs: Callable[..., bool | None] | None) -> None: ... + @property + def suppress(self) -> bool: ... + @property + def running(self) -> bool: ... + def stop(self) -> None: ... + def __enter__(self: Self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> None: ... + def wait(self) -> None: ... + def run(self) -> None: ... + @classmethod + def _emitter(cls, f: Callable[_P, _T]) -> Callable[_P, _T]: ... # undocumented + def _mark_ready(self) -> None: ... # undocumented + def _run(self) -> None: ... # undocumented + def _stop_platform(self) -> None: ... # undocumented + def join(self, *args: Any) -> None: ... + +class Events(Generic[_T, _AbstractListener_T]): + _Listener: type[_AbstractListener_T] | None # undocumented + + class Event: + def __eq__(self, other: object) -> bool: ... + _event_queue: Queue[_T] # undocumented + _sentinel: object # undocumented + _listener: _AbstractListener_T # undocumented + start: Callable[[], None] + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + def __enter__(self: Self) -> Self: ... + def __exit__(self, *args: Any) -> None: ... + def __iter__(self: Self) -> Self: ... + def __next__(self) -> _T: ... + def get(self, timeout: float | None = ...) -> _T | None: ... + def _event_mapper(self, event: Callable[_P, None]) -> Callable[_P, None]: ... + +class NotifierMixin: ... diff --git a/stubs/pynput/pynput/keyboard/__init__.pyi b/stubs/pynput/pynput/keyboard/__init__.pyi new file mode 100644 index 000000000..e470b5883 --- /dev/null +++ b/stubs/pynput/pynput/keyboard/__init__.pyi @@ -0,0 +1,30 @@ +from _typeshed import SupportsItems +from collections.abc import Callable +from typing import Any + +from pynput import _util + +from ._base import Controller as Controller, Key as Key, KeyCode as KeyCode, Listener as Listener + +class Events(_util.Events[Any, Listener]): + class Press(_util.Events.Event): + key: Key | KeyCode | None + def __init__(self, key: Key | KeyCode | None) -> None: ... + + class Release(_util.Events.Event): + key: Key | KeyCode | None + def __init__(self, key: Key | KeyCode | None) -> None: ... + + def __init__(self) -> None: ... + def __next__(self) -> Press | Release: ... + def get(self, timeout: float | None = ...) -> Press | Release | None: ... + +class HotKey: + def __init__(self, keys: list[KeyCode], on_activate: Callable[[], None]) -> None: ... + @staticmethod + def parse(keys: str) -> list[KeyCode]: ... + def press(self, key: Key | KeyCode) -> None: ... + def release(self, key: Key | KeyCode) -> None: ... + +class GlobalHotKeys(Listener): + def __init__(self, hotkeys: SupportsItems[str, Callable[[], None]], *args: Any, **kwargs: Any) -> None: ... diff --git a/stubs/pynput/pynput/keyboard/_base.pyi b/stubs/pynput/pynput/keyboard/_base.pyi new file mode 100644 index 000000000..6c10ba3ce --- /dev/null +++ b/stubs/pynput/pynput/keyboard/_base.pyi @@ -0,0 +1,122 @@ +import contextlib +import enum +from _typeshed import Self +from collections.abc import Callable, Iterable, Iterator +from typing import Any, ClassVar + +from pynput._util import AbstractListener + +class KeyCode: + _PLATFORM_EXTENSIONS: ClassVar[Iterable[str]] # undocumented + vk: int | None + char: str | None + is_dead: bool | None + combining: str | None + def __init__(self, vk: str | None = ..., char: str | None = ..., is_dead: bool = ..., **kwargs: str) -> None: ... + def __eq__(self, other: object) -> bool: ... + def __hash__(self) -> int: ... + def join(self: Self, key: Self) -> Self: ... + @classmethod + def from_vk(cls: type[Self], vk: int, **kwargs: Any) -> Self: ... + @classmethod + def from_char(cls: type[Self], char: str, **kwargs: Any) -> Self: ... + @classmethod + def from_dead(cls: type[Self], char: str, **kwargs: Any) -> Self: ... + +class Key(enum.Enum): + alt: int + alt_l: int + alt_r: int + alt_gr: int + backspace: int + caps_lock: int + cmd: int + cmd_l: int + cmd_r: int + ctrl: int + ctrl_l: int + ctrl_r: int + delete: int + down: int + end: int + enter: int + esc: int + f1: int + f2: int + f3: int + f4: int + f5: int + f6: int + f7: int + f8: int + f9: int + f10: int + f11: int + f12: int + f13: int + f14: int + f15: int + f16: int + f17: int + f18: int + f19: int + f20: int + home: int + left: int + page_down: int + page_up: int + right: int + shift: int + shift_l: int + shift_r: int + space: int + tab: int + up: int + media_play_pause: int + media_volume_mute: int + media_volume_down: int + media_volume_up: int + media_previous: int + media_next: int + insert: int + menu: int + num_lock: int + pause: int + print_screen: int + scroll_lock: int + +class Controller: + _KeyCode: ClassVar[KeyCode] # undocumented + _Key: ClassVar[Key] # undocumented + + class InvalidKeyException(Exception): ... + class InvalidCharacterException(Exception): ... + + def __init__(self) -> None: ... + def press(self, key: str | Key | KeyCode) -> None: ... + def release(self, key: str | Key | KeyCode) -> None: ... + def tap(self, key: str | Key | KeyCode) -> None: ... + def touch(self, key: str | Key | KeyCode, is_press: bool) -> None: ... + @contextlib.contextmanager + def pressed(self, *args: str | Key | KeyCode) -> Iterator[None]: ... + def type(self, string: str) -> None: ... + @property + def modifiers(self) -> contextlib.AbstractContextManager[Iterator[set[Key]]]: ... + @property + def alt_pressed(self) -> bool: ... + @property + def alt_gr_pressed(self) -> bool: ... + @property + def ctrl_pressed(self) -> bool: ... + @property + def shift_pressed(self) -> bool: ... + +class Listener(AbstractListener): + def __init__( + self, + on_press: Callable[[Key | KeyCode | None], None] | None = ..., + on_release: Callable[[Key | KeyCode | None], None] | None = ..., + suppress: bool = ..., + **kwargs: Any, + ) -> None: ... + def canonical(self, key: Key | KeyCode) -> Key | KeyCode: ... diff --git a/stubs/pynput/pynput/keyboard/_dummy.pyi b/stubs/pynput/pynput/keyboard/_dummy.pyi new file mode 100644 index 000000000..f49ca4777 --- /dev/null +++ b/stubs/pynput/pynput/keyboard/_dummy.pyi @@ -0,0 +1 @@ +from ._base import Controller as Controller, Key as Key, KeyCode as KeyCode, Listener as Listener diff --git a/stubs/pynput/pynput/mouse/__init__.pyi b/stubs/pynput/pynput/mouse/__init__.pyi new file mode 100644 index 000000000..ad9546c84 --- /dev/null +++ b/stubs/pynput/pynput/mouse/__init__.pyi @@ -0,0 +1,29 @@ +from typing import Any + +from pynput import _util + +from ._base import Button as Button, Controller as Controller, Listener as Listener + +class Events(_util.Events[Any, Listener]): + class Move(_util.Events.Event): + x: int + y: int + def __init__(self, x: int, y: int) -> None: ... + + class Click(_util.Events.Event): + x: int + y: int + button: Button + pressed: bool + def __init__(self, x: int, y: int, button: Button, pressed: bool) -> None: ... + + class Scroll(_util.Events.Event): + x: int + y: int + dx: int + dy: int + def __init__(self, x: int, y: int, dx: int, dy: int) -> None: ... + + def __init__(self) -> None: ... + def __next__(self) -> Move | Click | Scroll: ... + def get(self, timeout: float | None = ...) -> Move | Click | Scroll | None: ... diff --git a/stubs/pynput/pynput/mouse/_base.pyi b/stubs/pynput/pynput/mouse/_base.pyi new file mode 100644 index 000000000..181dea5a0 --- /dev/null +++ b/stubs/pynput/pynput/mouse/_base.pyi @@ -0,0 +1,39 @@ +import enum +from _typeshed import Self +from collections.abc import Callable +from types import TracebackType +from typing import Any + +from pynput._util import AbstractListener + +class Button(enum.Enum): + unknown: int + left: int + middle: int + right: int + +class Controller: + def __init__(self) -> None: ... + @property + def position(self) -> tuple[int, int]: ... + @position.setter + def position(self, position: tuple[int, int]) -> None: ... + def scroll(self, dx: int, dy: int) -> None: ... + def press(self, button: Button) -> None: ... + def release(self, button: Button) -> None: ... + def move(self, dx: int, dy: int) -> None: ... + def click(self, button: Button, count: int = ...) -> None: ... + def __enter__(self: Self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> None: ... + +class Listener(AbstractListener): + def __init__( + self, + on_move: Callable[[int, int], bool | None] | None = ..., + on_click: Callable[[int, int, Button, bool], bool | None] | None = ..., + on_scroll: Callable[[int, int, int, int], bool | None] | None = ..., + suppress: bool = ..., + **kwargs: Any, + ) -> None: ... diff --git a/stubs/pynput/pynput/mouse/_dummy.pyi b/stubs/pynput/pynput/mouse/_dummy.pyi new file mode 100644 index 000000000..c799f582b --- /dev/null +++ b/stubs/pynput/pynput/mouse/_dummy.pyi @@ -0,0 +1 @@ +from ._base import Button as Button, Controller as Controller, Listener as Listener