From 72c7ec434047a0dc6f8bc9467fb06a867867f506 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 1 Sep 2022 16:05:52 -0400 Subject: [PATCH 01/17] Added type stub for keyboard --- pyrightconfig.stricter.json | 1 + stubs/keyboard/@tests/stubtests_allowlist.txt | 8 + stubs/keyboard/METADATA.toml | 4 + stubs/keyboard/keyboard/__init__.pyi | 174 ++++++++++++ stubs/keyboard/keyboard/_canonical_names.pyi | 6 + stubs/keyboard/keyboard/_darwinkeyboard.pyi | 52 ++++ stubs/keyboard/keyboard/_darwinmouse.pyi | 44 +++ stubs/keyboard/keyboard/_generic.pyi | 23 ++ stubs/keyboard/keyboard/_keyboard_event.pyi | 30 +++ stubs/keyboard/keyboard/_mouse_event.pyi | 41 +++ stubs/keyboard/keyboard/_nixcommon.pyi | 45 ++++ stubs/keyboard/keyboard/_nixkeyboard.pyi | 37 +++ stubs/keyboard/keyboard/_nixmouse.pyi | 68 +++++ stubs/keyboard/keyboard/_winkeyboard.pyi | 250 ++++++++++++++++++ stubs/keyboard/keyboard/_winmouse.pyi | 129 +++++++++ stubs/keyboard/keyboard/mouse.pyi | 78 ++++++ stubs/pynput/pynput/keyboard/_base.pyi | 2 +- 17 files changed, 991 insertions(+), 1 deletion(-) create mode 100644 stubs/keyboard/@tests/stubtests_allowlist.txt create mode 100644 stubs/keyboard/METADATA.toml create mode 100644 stubs/keyboard/keyboard/__init__.pyi create mode 100644 stubs/keyboard/keyboard/_canonical_names.pyi create mode 100644 stubs/keyboard/keyboard/_darwinkeyboard.pyi create mode 100644 stubs/keyboard/keyboard/_darwinmouse.pyi create mode 100644 stubs/keyboard/keyboard/_generic.pyi create mode 100644 stubs/keyboard/keyboard/_keyboard_event.pyi create mode 100644 stubs/keyboard/keyboard/_mouse_event.pyi create mode 100644 stubs/keyboard/keyboard/_nixcommon.pyi create mode 100644 stubs/keyboard/keyboard/_nixkeyboard.pyi create mode 100644 stubs/keyboard/keyboard/_nixmouse.pyi create mode 100644 stubs/keyboard/keyboard/_winkeyboard.pyi create mode 100644 stubs/keyboard/keyboard/_winmouse.pyi create mode 100644 stubs/keyboard/keyboard/mouse.pyi diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index 2a335d75f698..08de0060f412 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -51,6 +51,7 @@ "stubs/invoke", "stubs/jmespath", "stubs/jsonschema", + "stubs/keyboard", "stubs/ldap3", "stubs/Markdown", "stubs/mock", diff --git a/stubs/keyboard/@tests/stubtests_allowlist.txt b/stubs/keyboard/@tests/stubtests_allowlist.txt new file mode 100644 index 000000000000..1a6f7d1c0234 --- /dev/null +++ b/stubs/keyboard/@tests/stubtests_allowlist.txt @@ -0,0 +1,8 @@ +# MacOs: ModuleNotFoundError: No module named 'Quartz' +keyboard._darwinkeyboard +keyboard._darwinmouse +# Exposing CFunctionType as a Callable +keyboard._winkeyboard.LowLevelKeyboardProc +keyboard._winmouse.LowLevelMouseProc +# Defaults don't align with possible values +keyboard.mouse.wait diff --git a/stubs/keyboard/METADATA.toml b/stubs/keyboard/METADATA.toml new file mode 100644 index 000000000000..18912b609ed8 --- /dev/null +++ b/stubs/keyboard/METADATA.toml @@ -0,0 +1,4 @@ +version = "0.13.*" + +[tool.stubtest] +ignore_missing_stub = false diff --git a/stubs/keyboard/keyboard/__init__.pyi b/stubs/keyboard/keyboard/__init__.pyi new file mode 100644 index 000000000000..588567aabbaa --- /dev/null +++ b/stubs/keyboard/keyboard/__init__.pyi @@ -0,0 +1,174 @@ +from collections import Counter, defaultdict, deque +from collections.abc import Callable, Generator, Sequence +from queue import Queue +from threading import Event as _UninterruptibleEvent +from typing import Optional, Tuple, Union +from typing_extensions import Literal, ParamSpec, TypeAlias + +from ._canonical_names import all_modifiers as all_modifiers, sided_modifiers as sided_modifiers +from ._generic import GenericListener as _GenericListener +from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent + +_Key: TypeAlias = int | str +_ScanCodeList: TypeAlias = list[int] | Tuple[int, ...] +_ParseableHotkey: TypeAlias = _Key | list[Union[int, _ScanCodeList]] | Tuple[Union[int, _ScanCodeList], ...] +_Callback: TypeAlias = Callable[[KeyboardEvent], Optional[bool]] | Callable[[], Optional[bool]] +_P = ParamSpec("_P") + +version: str + +class _Event(_UninterruptibleEvent): + def wait(self) -> None: ... # type: ignore[override] # Actual implementation + +def is_modifier(key: _Key) -> bool: ... + +class _KeyboardListener(_GenericListener): + transition_table: dict[ + tuple[Literal["free"], Literal["up"], Literal["modifier"]] + | tuple[Literal["free"], Literal["down"], Literal["modifier"]] + | tuple[Literal["pending"], Literal["up"], Literal["modifier"]] + | tuple[Literal["pending"], Literal["down"], Literal["modifier"]] + | tuple[Literal["suppressed"], Literal["up"], Literal["modifier"]] + | tuple[Literal["suppressed"], Literal["down"], Literal["modifier"]] + | tuple[Literal["allowed"], Literal["up"], Literal["modifier"]] + | tuple[Literal["allowed"], Literal["down"], Literal["modifier"]] + | tuple[Literal["free"], Literal["up"], Literal["hotkey"]] + | tuple[Literal["free"], Literal["down"], Literal["hotkey"]] + | tuple[Literal["pending"], Literal["up"], Literal["hotkey"]] + | tuple[Literal["pending"], Literal["down"], Literal["hotkey"]] + | tuple[Literal["suppressed"], Literal["up"], Literal["hotkey"]] + | tuple[Literal["suppressed"], Literal["down"], Literal["hotkey"]] + | tuple[Literal["allowed"], Literal["up"], Literal["hotkey"]] + | tuple[Literal["allowed"], Literal["down"], Literal["hotkey"]] + | tuple[Literal["free"], Literal["up"], Literal["other"]] + | tuple[Literal["free"], Literal["down"], Literal["other"]] + | tuple[Literal["pending"], Literal["up"], Literal["other"]] + | tuple[Literal["pending"], Literal["down"], Literal["other"]] + | tuple[Literal["suppressed"], Literal["up"], Literal["other"]] + | tuple[Literal["suppressed"], Literal["down"], Literal["other"]] + | tuple[Literal["allowed"], Literal["up"], Literal["other"]] + | tuple[Literal["allowed"], Literal["down"], Literal["other"]], + tuple[Literal[False], Literal[True], Literal["free"]] + | tuple[Literal[False], Literal[False], Literal["pending"]] + | tuple[Literal[True], Literal[True], Literal["free"]] + | tuple[Literal[False], Literal[True], Literal["allowed"]] + | tuple[Literal[False], Literal[False], Literal["free"]] + | tuple[Literal[False], Literal[False], Literal["suppressed"]] + | tuple[Literal[False], None, Literal["free"]] + | tuple[Literal[False], None, Literal["suppressed"]] + | tuple[Literal[False], None, Literal["allowed"]] + | tuple[Literal[True], Literal[True], Literal["allowed"]] + | tuple[Literal[False], Literal[False], Literal["allowed"]], + ] + active_modifiers: set[int] + blocking_hooks: list[_Callback] + blocking_keys: defaultdict[int, list[_Callback]] + nonblocking_keys: defaultdict[int, list[_Callback]] + blocking_hotkeys: defaultdict[Tuple[int, ...], list[_Callback]] + nonblocking_hotkeys: defaultdict[Tuple[int, ...], list[_Callback]] + filtered_modifiers: Counter[int] + is_replaying: bool + modifier_states: dict[_Key, str] + def init(self) -> None: ... + def pre_process_event(self, event): ... + def direct_callback(self, event): ... + def listen(self) -> None: ... + +def key_to_scan_codes(key: _Key, error_if_missing: bool = ...) -> Tuple[int, ...]: ... +def parse_hotkey(hotkey: _ParseableHotkey) -> Tuple[Tuple[Tuple[int, ...], ...], ...]: ... +def send(hotkey: _ParseableHotkey, do_press: bool = ..., do_release: bool = ...) -> None: ... + +press_and_release = send + +def press(hotkey: _ParseableHotkey) -> None: ... +def release(hotkey: _ParseableHotkey) -> None: ... + +# is_pressed cannot check multi-step hotkeys + +def is_pressed(hotkey: _Key | _ScanCodeList) -> bool: ... + +# TODO: how to make args: _P.args ? +_P_args: TypeAlias = tuple[object, ...] + +def call_later(fn: Callable[_P, None], args: tuple[object, ...] = ..., delay: float = ...) -> None: ... +def hook(callback: _Callback, suppress: bool = ..., on_remove: Callable[[], None] = ...) -> Callable[[], None]: ... +def on_press(callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def on_release(callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def hook_key(key: _Key, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def on_press_key(key: _Key, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def on_release_key(key: _Key, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def unhook(remove: _Callback) -> None: ... + +unhook_key = unhook + +def unhook_all() -> None: ... +def block_key(key: _Key) -> Callable[[], None]: ... + +unblock_key = unhook_key + +def remap_key(src: _Key, dst: _ParseableHotkey) -> Callable[[], None]: ... + +unremap_key = unhook_key + +def parse_hotkey_combinations(hotkey: _ParseableHotkey) -> Tuple[Tuple[Tuple[int, ...], ...], ...]: ... + +# TODO: how to make args: _P.args ? + +def add_hotkey( + hotkey: _ParseableHotkey, + callback: Callable[_P, bool | None], + args: _P_args = ..., + suppress: bool = ..., + timeout: float = ..., + trigger_on_release: bool = ..., +) -> Callable[[], None]: ... + +register_hotkey = add_hotkey + +def remove_hotkey(hotkey_or_callback: _ParseableHotkey | _Callback) -> None: ... + +unregister_hotkey = remove_hotkey +clear_hotkey = remove_hotkey + +def unhook_all_hotkeys() -> None: ... + +unregister_all_hotkeys = unhook_all_hotkeys +remove_all_hotkeys = unhook_all_hotkeys +clear_all_hotkeys = unhook_all_hotkeys + +def remap_hotkey( + src: _ParseableHotkey, dst: _ParseableHotkey, suppress: bool = ..., trigger_on_release: bool = ... +) -> Callable[[], None]: ... + +unremap_hotkey = remove_hotkey + +def stash_state() -> list[int]: ... +def restore_state(scan_codes: Sequence[int]) -> None: ... +def restore_modifiers(scan_codes: Sequence[int]) -> None: ... +def write(text: str, delay: float = ..., restore_state_after: bool = ..., exact: bool | None = ...) -> None: ... +def wait(hotkey: _ParseableHotkey | None = ..., suppress: bool = ..., trigger_on_release: bool = ...) -> None: ... +def get_hotkey_name(names: Sequence[str] | None = ...) -> str: ... +def read_event(suppress: bool = ...) -> KeyboardEvent: ... +def read_key(suppress: bool = ...) -> _Key: ... +def read_hotkey(suppress: bool = ...) -> str: ... +def get_typed_strings(events: Sequence[KeyboardEvent], allow_backspace: bool = ...) -> Generator[str, None, None]: ... +def start_recording( + recorded_events_queue: Queue[KeyboardEvent] | None = ..., +) -> tuple[Queue[KeyboardEvent], Callable[[], None]]: ... +def stop_recording() -> list[deque[KeyboardEvent]]: ... +def record(until: str = ..., suppress: bool = ..., trigger_on_release: bool = ...) -> list[deque[KeyboardEvent]]: ... +def play(events: Sequence[KeyboardEvent], speed_factor: float = ...) -> None: ... + +replay = play + +def add_word_listener( + word: str, callback: _Callback, triggers: Sequence[str] = ..., match_suffix: bool = ..., timeout: float = ... +) -> Callable[[], None]: ... +def remove_word_listener(word_or_handler: str | _Callback) -> None: ... +def add_abbreviation( + source_text: str, replacement_text: str, match_suffix: bool = ..., timeout: float = ... +) -> Callable[[], None]: ... + +register_word_listener = add_word_listener +register_abbreviation = add_abbreviation +remove_abbreviation = remove_word_listener diff --git a/stubs/keyboard/keyboard/_canonical_names.pyi b/stubs/keyboard/keyboard/_canonical_names.pyi new file mode 100644 index 000000000000..1bfd90779708 --- /dev/null +++ b/stubs/keyboard/keyboard/_canonical_names.pyi @@ -0,0 +1,6 @@ +basestring = str +canonical_names: dict[str, str] +sided_modifiers: set[str] +all_modifiers: set[str] + +def normalize_name(name: str) -> str: ... diff --git a/stubs/keyboard/keyboard/_darwinkeyboard.pyi b/stubs/keyboard/keyboard/_darwinkeyboard.pyi new file mode 100644 index 000000000000..79f8b4eccbd7 --- /dev/null +++ b/stubs/keyboard/keyboard/_darwinkeyboard.pyi @@ -0,0 +1,52 @@ +from _typeshed import Incomplete +from collections.abc import Callable, Generator, Sequence +from ctypes import CDLL +from typing import TypeVar +from typing_extensions import TypeAlias + +from ._canonical_names import normalize_name as normalize_name +from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent + +_Unused: TypeAlias = object + +# https://github.com/ronaldoussoren/pyobjc/milestone/3 +_CGEventTap: TypeAlias = Incomplete # Quartz.CGEventTap +_kCGEvent: TypeAlias = Incomplete # Quartz.kCGEvent +_T = TypeVar("_T") + +unichr = chr +Carbon: CDLL + +class KeyMap: + non_layout_keys: dict[int, str] + layout_specific_keys: dict[int, tuple[str, str]] + def character_to_vk(self, character: str) -> tuple[int, list[str]]: ... + def vk_to_character(self, vk: int, modifiers: Sequence[str] = ...): ... + +class KeyController: + key_map: KeyMap + current_modifiers: dict[str, bool] + media_keys: dict[str, int] + def press(self, key_code: int) -> None: ... + def release(self, key_code: int) -> None: ... + def map_char(self, character: str) -> tuple[int, list[str]]: ... + def map_scan_code(self, scan_code: int) -> int | str | None: ... + +class KeyEventListener: + blocking: bool + callback: Callable[[KeyboardEvent], None] + listening: bool + tap: _CGEventTap + def __init__(self, callback: Callable[[KeyboardEvent], None], blocking: bool = ...) -> None: ... + def run(self) -> None: ... + def handler(self, proxy: _Unused, e_type: _kCGEvent, event: _T, refcon: _Unused) -> _T: ... + +key_controller: KeyController + +def init() -> None: ... +def press(scan_code: int) -> None: ... +def release(scan_code: int) -> None: ... +def map_name(name: str) -> Generator[tuple[int, list[str]], None, None]: ... +def name_from_scancode(scan_code: int) -> int | str | None: ... +def listen(callback: Callable[[KeyboardEvent], None]) -> None: ... +def type_unicode(character: str) -> None: ... diff --git a/stubs/keyboard/keyboard/_darwinmouse.pyi b/stubs/keyboard/keyboard/_darwinmouse.pyi new file mode 100644 index 000000000000..4cf320410ae7 --- /dev/null +++ b/stubs/keyboard/keyboard/_darwinmouse.pyi @@ -0,0 +1,44 @@ +from _typeshed import Incomplete +from collections.abc import Callable +from queue import Queue +from typing import TypeVar +from typing_extensions import TypeAlias + +from ._keyboard_event import KeyboardEvent +from ._mouse_event import ( + DOWN as DOWN, + LEFT as LEFT, + MIDDLE as MIDDLE, + RIGHT as RIGHT, + UP as UP, + X2 as X2, + ButtonEvent as ButtonEvent, + MoveEvent as MoveEvent, + WheelEvent as WheelEvent, + X as X, + _MouseButton, +) + +_Unused: TypeAlias = object + +# https://github.com/ronaldoussoren/pyobjc/milestone/3 +_CGEventTap: TypeAlias = Incomplete # Quartz.CGEventTap +_kCGEventKey: TypeAlias = Incomplete # Quartz.kCGEventKey +_T = TypeVar("_T") + +class MouseEventListener: + blocking: bool + callback: Callable[[KeyboardEvent], None] + listening: bool + def __init__(self, callback: Callable[[KeyboardEvent], None], blocking: bool = ...) -> None: ... + tap: _CGEventTap + def run(self) -> None: ... + def handler(self, proxy: _Unused, e_type: _kCGEventKey, event: _T, refcon: _Unused) -> _T: ... + +def init() -> None: ... +def listen(queue: Queue[KeyboardEvent]) -> None: ... +def press(button: _MouseButton = ...) -> None: ... +def release(button: _MouseButton = ...) -> None: ... +def wheel(delta: int = ...) -> None: ... +def move_to(x: int, y: int) -> None: ... +def get_position() -> tuple[int, int]: ... diff --git a/stubs/keyboard/keyboard/_generic.pyi b/stubs/keyboard/keyboard/_generic.pyi new file mode 100644 index 000000000000..dd6a6d2fbf19 --- /dev/null +++ b/stubs/keyboard/keyboard/_generic.pyi @@ -0,0 +1,23 @@ +from collections.abc import Callable +from queue import Queue +from threading import Lock, Thread +from typing_extensions import Literal, TypeAlias + +from ._keyboard_event import KeyboardEvent +from ._mouse_event import ButtonEvent, MoveEvent, WheelEvent + +_Event: TypeAlias = KeyboardEvent | ButtonEvent | WheelEvent | MoveEvent + +class GenericListener: + lock: Lock + handlers: list[Callable[[_Event], bool | None]] + listening: bool + queue: Queue[_Event] + listening_thread: Thread | None + processing_thread: Thread | None + def invoke_handlers(self, event: _Event) -> Literal[1] | None: ... + def start_if_necessary(self) -> None: ... + def pre_process_event(self, event: _Event) -> None: ... + def process(self) -> None: ... + def add_handler(self, handler: Callable[[_Event], bool | None]) -> None: ... + def remove_handler(self, handler: Callable[[_Event], bool | None]) -> None: ... diff --git a/stubs/keyboard/keyboard/_keyboard_event.pyi b/stubs/keyboard/keyboard/_keyboard_event.pyi new file mode 100644 index 000000000000..efe8573cf300 --- /dev/null +++ b/stubs/keyboard/keyboard/_keyboard_event.pyi @@ -0,0 +1,30 @@ +from typing import Tuple +from typing_extensions import Literal + +from ._canonical_names import canonical_names as canonical_names, normalize_name as normalize_name + +basestring = str +KEY_DOWN: Literal["down"] +KEY_UP: Literal["up"] + +class KeyboardEvent: + event_type: Literal["down", "up"] | None + scan_code: int | None + name: str | None + time: float | None + device: str | None + modifiers: Tuple[str, ...] | None + is_keypad: bool | None + + def __init__( + self, + event_type: Literal["down", "up"] | None, + scan_code: int | None, + name: str | None = ..., + time: float | None = ..., + device: str | None = ..., + modifiers: Tuple[str, ...] | None = ..., + is_keypad: bool | None = ..., + ) -> None: ... + def to_json(self, ensure_ascii: bool = ...) -> str: ... + def __eq__(self, other: object) -> bool: ... diff --git a/stubs/keyboard/keyboard/_mouse_event.pyi b/stubs/keyboard/keyboard/_mouse_event.pyi new file mode 100644 index 000000000000..6089b32b40ba --- /dev/null +++ b/stubs/keyboard/keyboard/_mouse_event.pyi @@ -0,0 +1,41 @@ +import sys +from typing import NamedTuple +from typing_extensions import Literal, TypeAlias + +LEFT: Literal["left"] +RIGHT: Literal["right"] +MIDDLE: Literal["middle"] +X: Literal["x"] +X2: Literal["x2"] + +UP: Literal["up"] +DOWN: Literal["down"] +DOUBLE: Literal["double"] +WHEEL: Literal["wheel"] + +VERTICAL: Literal["vertical"] +HORIZONTAL: Literal["horizontal"] + +if sys.platform == "linux" or sys.platform == "win32": + _MouseButton: TypeAlias = Literal["left", "right", "middle", "x", "x2"] +else: + _MouseButton: TypeAlias = Literal["left", "right", "middle"] + +if sys.platform == "win32": + _MouseEvent: TypeAlias = Literal["up", "down", "double", "wheel"] +else: + _MouseEvent: TypeAlias = Literal["up", "down"] + +class ButtonEvent(NamedTuple): + event_type: _MouseEvent + button: _MouseButton + time: float + +class WheelEvent(NamedTuple): + delta: int + time: float + +class MoveEvent(NamedTuple): + x: int + y: int + time: float diff --git a/stubs/keyboard/keyboard/_nixcommon.pyi b/stubs/keyboard/keyboard/_nixcommon.pyi new file mode 100644 index 000000000000..5a77e8ceecec --- /dev/null +++ b/stubs/keyboard/keyboard/_nixcommon.pyi @@ -0,0 +1,45 @@ +from _typeshed import Incomplete +from collections.abc import Generator, Sequence +from io import BufferedReader, BufferedWriter +from queue import Queue +from typing import NamedTuple +from typing_extensions import Literal + +event_bin_format: Literal["llHHI"] +EV_SYN: Literal[0] +EV_KEY: Literal[1] +EV_REL: Literal[2] +EV_ABS: Literal[3] +EV_MSC: Literal[4] + +def make_uinput() -> BufferedWriter: ... + +class EventDevice: + path: str + def __init__(self, path: str) -> None: ... + @property + def input_file(self) -> BufferedReader: ... + @property + def output_file(self) -> BufferedWriter: ... + def read_event(self) -> tuple[float, Incomplete, Incomplete, Incomplete, str]: ... + def write_event(self, type, code, value) -> None: ... + +class AggregatedEventDevice: + event_queue: Queue[tuple[float, Incomplete, Incomplete, Incomplete, str]] + devices: Sequence[EventDevice] + output: EventDevice + def __init__(self, devices: Sequence[EventDevice], output: EventDevice | None = ...) -> None: ... + def read_event(self) -> EventDevice: ... + def write_event(self, type, code, value) -> None: ... + +class DeviceDescription(NamedTuple): + event_file: str + is_mouse: bool + is_keyboard: bool + +device_pattern: str + +def list_devices_from_proc(type_name: str) -> Generator[EventDevice, None, None]: ... +def list_devices_from_by_id(name_suffix: str, by_id: bool = ...) -> Generator[EventDevice, None, None]: ... +def aggregate_devices(type_name: str) -> AggregatedEventDevice | EventDevice: ... +def ensure_root() -> None: ... diff --git a/stubs/keyboard/keyboard/_nixkeyboard.pyi b/stubs/keyboard/keyboard/_nixkeyboard.pyi new file mode 100644 index 000000000000..8f872b802dd3 --- /dev/null +++ b/stubs/keyboard/keyboard/_nixkeyboard.pyi @@ -0,0 +1,37 @@ +from collections import defaultdict, namedtuple as namedtuple +from collections.abc import Callable, Generator +from typing import Tuple + +from ._canonical_names import all_modifiers as all_modifiers, normalize_name as normalize_name +from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent +from ._nixcommon import ( + EV_KEY as EV_KEY, + AggregatedEventDevice, + EventDevice, + aggregate_devices as aggregate_devices, + ensure_root as ensure_root, +) + +def cleanup_key(name: str) -> tuple[str, bool]: ... +def cleanup_modifier(modifier: str) -> str: ... + +to_name: defaultdict[tuple[int, Tuple[str, ...]], list[str] | str] +from_name: defaultdict[str, list[tuple[int, Tuple[str, ...]]]] +keypad_scan_codes: set[str] + +def register_key(key_and_modifiers: tuple[int, Tuple[str, ...]], name: str) -> None: ... +def build_tables() -> None: ... + +device: AggregatedEventDevice | EventDevice | None + +def build_device() -> None: ... +def init() -> None: ... + +pressed_modifiers: set[str] + +def listen(callback: Callable[[KeyboardEvent], None]) -> None: ... +def write_event(scan_code: int, is_down: bool | int) -> None: ... +def map_name(name: str) -> Generator[tuple[int, Tuple[str, ...]], None, None]: ... +def press(scan_code: int) -> None: ... +def release(scan_code: int) -> None: ... +def type_unicode(character: str | bytes | bytearray) -> None: ... diff --git a/stubs/keyboard/keyboard/_nixmouse.pyi b/stubs/keyboard/keyboard/_nixmouse.pyi new file mode 100644 index 000000000000..cdf932c9bba9 --- /dev/null +++ b/stubs/keyboard/keyboard/_nixmouse.pyi @@ -0,0 +1,68 @@ +from _typeshed import Incomplete +from ctypes import CDLL +from queue import Queue +from subprocess import check_output as check_output +from typing_extensions import Literal, TypeAlias + +from ._mouse_event import ( + DOWN as DOWN, + LEFT as LEFT, + MIDDLE as MIDDLE, + RIGHT as RIGHT, + UP as UP, + X2 as X2, + ButtonEvent as ButtonEvent, + MoveEvent as MoveEvent, + WheelEvent as WheelEvent, + X as X, + _MouseButton, +) +from ._nixcommon import ( + EV_ABS as EV_ABS, + EV_KEY as EV_KEY, + EV_MSC as EV_MSC, + EV_REL as EV_REL, + EV_SYN as EV_SYN, + AggregatedEventDevice, + EventDevice, + aggregate_devices as aggregate_devices, + ensure_root as ensure_root, +) + +x11: CDLL | None +display: TypeAlias = Incomplete # x11.XOpenDisplay(None) +window: TypeAlias = Incomplete # x11.XDefaultRootWindow(display) + +def build_display() -> None: ... +def get_position() -> tuple[int, int]: ... +def move_to(x, y) -> None: ... + +REL_X: Literal[0] +REL_Y: Literal[1] +REL_Z: Literal[2] +REL_HWHEEL: Literal[6] +REL_WHEEL: Literal[8] + +ABS_X: Literal[0] +ABS_Y: Literal[1] + +BTN_MOUSE: Literal[272] +BTN_LEFT: Literal[272] +BTN_RIGHT: Literal[273] +BTN_MIDDLE: Literal[274] +BTN_SIDE: Literal[275] +BTN_EXTRA: Literal[276] + +button_by_code: dict[int, str] +code_by_button: dict[str, int] +device: AggregatedEventDevice | EventDevice | None + +def build_device() -> None: ... + +init = build_device + +def listen(queue: Queue[ButtonEvent | WheelEvent | MoveEvent]) -> None: ... +def press(button: _MouseButton = ...) -> None: ... +def release(button: _MouseButton = ...) -> None: ... +def move_relative(x: int, y: int) -> None: ... +def wheel(delta: int = ...) -> None: ... diff --git a/stubs/keyboard/keyboard/_winkeyboard.pyi b/stubs/keyboard/keyboard/_winkeyboard.pyi new file mode 100644 index 000000000000..a7368f9f9920 --- /dev/null +++ b/stubs/keyboard/keyboard/_winkeyboard.pyi @@ -0,0 +1,250 @@ +from _typeshed import Incomplete +from collections import defaultdict +from collections.abc import Callable, Generator, Sequence +from ctypes import ( + Array, + Structure, + Union, + WinDLL, + c_char as c_char, + c_int, + c_int32 as c_int32, + c_long, + c_short, + c_uint, + c_uint8, + c_uint32 as c_uint32, + c_wchar, +) +from ctypes.wintypes import ( + BOOL, + DWORD, + HHOOK, + HMODULE, + LONG, + LPARAM, + LPCWSTR, + LPDWORD, + LPMSG as LPMSG, + LPWSTR, + WCHAR, + WORD, + WPARAM, +) +from threading import Lock +from typing import Tuple +from typing_extensions import Literal, TypeAlias + +from ._canonical_names import normalize_name as normalize_name +from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent + +ULONG_PTR: TypeAlias = LPDWORD +kernel32: WinDLL +GetModuleHandleW: Callable[[LPCWSTR | None], HMODULE] +user32: WinDLL +VK_PACKET: Literal[231] +INPUT_MOUSE: Literal[0] +INPUT_KEYBOARD: Literal[1] +INPUT_HARDWARE: Literal[2] +KEYEVENTF_KEYUP: Literal[2] +KEYEVENTF_UNICODE: Literal[4] + +class KBDLLHOOKSTRUCT(Structure): + vk_code: DWORD + scan_code: DWORD + flags: DWORD + time: c_int + dwExtraInfo: ULONG_PTR + +class MOUSEINPUT(Structure): + dx: LONG + dy: LONG + mouseData: DWORD + dwFlags: DWORD + time: DWORD + dwExtraInfo: ULONG_PTR + +class KEYBDINPUT(Structure): + wVk: WORD + wScan: WORD + dwFlags: DWORD + time: DWORD + dwExtraInfo: ULONG_PTR + +class HARDWAREINPUT(Structure): + uMsg: DWORD + wParamL: WORD + wParamH: WORD + +class _INPUTunion(Union): + mi: MOUSEINPUT + ki: KEYBDINPUT + hi: HARDWAREINPUT + +class INPUT(Structure): + type: DWORD + union: _INPUTunion + +_POINTER_KBDLLHOOKSTRUCT: TypeAlias = Incomplete # POINTER(KBDLLHOOKSTRUCT) +_LRESULT: TypeAlias = Incomplete +_POINTER_INPUT: TypeAlias = Incomplete # POINTER(INPUT) +_LowLevelKeyboardProc: TypeAlias = Callable[[Callable[[c_int, WPARAM, LPARAM], c_int]], _POINTER_KBDLLHOOKSTRUCT] +LowLevelKeyboardProc: _LowLevelKeyboardProc +SetWindowsHookEx: Callable[[c_int, _LowLevelKeyboardProc, c_int, c_int], HHOOK] +CallNextHookEx: Callable[[c_int, c_int, WPARAM, LPARAM], c_int] +UnhookWindowsHookEx: Callable[[HHOOK], BOOL] +GetMessage: Callable[[LPMSG, c_int, c_int, c_int], BOOL] +TranslateMessage: Callable[[LPMSG], BOOL] +DispatchMessage: Callable[[LPMSG], _LRESULT] +_keyboard_state_type: TypeAlias = Array[c_uint8] +keyboard_state_type: _keyboard_state_type +GetKeyboardState: Callable[[_keyboard_state_type], BOOL] +GetKeyNameText: Callable[[c_long, LPWSTR, c_int], c_int] +MapVirtualKey: Callable[[c_uint, c_uint], c_uint] +ToUnicode: Callable[[c_uint, c_uint, _keyboard_state_type, LPWSTR, c_int, c_uint], c_int] +SendInput: Callable[[c_uint, _POINTER_INPUT, c_int], c_uint] +MAPVK_VK_TO_CHAR: Literal[2] +MAPVK_VK_TO_VSC: Literal[0] +MAPVK_VSC_TO_VK: Literal[1] +MAPVK_VK_TO_VSC_EX: Literal[4] +MAPVK_VSC_TO_VK_EX: Literal[3] +VkKeyScan: Callable[[WCHAR], c_short] +LLKHF_INJECTED: Literal[16] + +WM_KEYDOWN: Literal[256] +WM_KEYUP: Literal[257] +WM_SYSKEYDOWN: Literal[260] +WM_SYSKEYUP: Literal[261] +keyboard_event_types: dict[int, str] +official_virtual_keys: dict[ + int, + tuple[Literal["control-break processing"], Literal[False]] + | tuple[Literal["backspace"], Literal[False]] + | tuple[Literal["tab"], Literal[False]] + | tuple[Literal["clear"], Literal[False]] + | tuple[Literal["enter"], Literal[False]] + | tuple[Literal["shift"], Literal[False]] + | tuple[Literal["ctrl"], Literal[False]] + | tuple[Literal["alt"], Literal[False]] + | tuple[Literal["pause"], Literal[False]] + | tuple[Literal["caps lock"], Literal[False]] + | tuple[Literal["ime kana mode"], Literal[False]] + | tuple[Literal["ime hanguel mode"], Literal[False]] + | tuple[Literal["ime hangul mode"], Literal[False]] + | tuple[Literal["ime junja mode"], Literal[False]] + | tuple[Literal["ime final mode"], Literal[False]] + | tuple[Literal["ime hanja mode"], Literal[False]] + | tuple[Literal["ime kanji mode"], Literal[False]] + | tuple[Literal["esc"], Literal[False]] + | tuple[Literal["ime convert"], Literal[False]] + | tuple[Literal["ime nonconvert"], Literal[False]] + | tuple[Literal["ime accept"], Literal[False]] + | tuple[Literal["ime mode change request"], Literal[False]] + | tuple[Literal["spacebar"], Literal[False]] + | tuple[Literal["page up"], Literal[False]] + | tuple[Literal["page down"], Literal[False]] + | tuple[Literal["end"], Literal[False]] + | tuple[Literal["home"], Literal[False]] + | tuple[Literal["left"], Literal[False]] + | tuple[Literal["up"], Literal[False]] + | tuple[Literal["right"], Literal[False]] + | tuple[Literal["down"], Literal[False]] + | tuple[Literal["select"], Literal[False]] + | tuple[Literal["print"], Literal[False]] + | tuple[Literal["execute"], Literal[False]] + | tuple[Literal["print screen"], Literal[False]] + | tuple[Literal["insert"], Literal[False]] + | tuple[Literal["delete"], Literal[False]] + | tuple[Literal["help"], Literal[False]] + | tuple[Literal["0"], Literal[False]] + | tuple[Literal["1"], Literal[False]] + | tuple[Literal["2"], Literal[False]] + | tuple[Literal["3"], Literal[False]] + | tuple[Literal["4"], Literal[False]] + | tuple[Literal["5"], Literal[False]] + | tuple[Literal["6"], Literal[False]] + | tuple[Literal["7"], Literal[False]] + | tuple[Literal["8"], Literal[False]] + | tuple[Literal["9"], Literal[False]] + | tuple[Literal["a"], Literal[False]] + | tuple[Literal["b"], Literal[False]] + | tuple[Literal["c"], Literal[False]] + | tuple[Literal["d"], Literal[False]] + | tuple[Literal["e"], Literal[False]] + | tuple[Literal["f"], Literal[False]] + | tuple[Literal["g"], Literal[False]] + | tuple[Literal["h"], Literal[False]] + | tuple[Literal["i"], Literal[False]] + | tuple[Literal["j"], Literal[False]] + | tuple[Literal["k"], Literal[False]] + | tuple[Literal["l"], Literal[False]] + | tuple[Literal["m"], Literal[False]] + | tuple[Literal["n"], Literal[False]] + | tuple[Literal["o"], Literal[False]] + | tuple[Literal["p"], Literal[False]], +] +tables_lock: Lock +to_name: defaultdict[tuple[int, int, int, str | int | Tuple[str, ...]] | tuple[int, int, int, int, int], list[str]] +from_name: defaultdict[str, list[tuple[int, Tuple[str | int | Tuple[str, ...], ...]]]] +scan_code_to_vk: dict[int, int] +distinct_modifiers: list[ + tuple[()] + | tuple[Literal["shift"]] + | tuple[Literal["alt gr"]] + | tuple[Literal["num lock"]] + | tuple[Literal["shift"], Literal["num lock"]] + | tuple[Literal["caps lock"]] + | tuple[Literal["shift"], Literal["caps lock"]] + | tuple[Literal["alt gr"], Literal["num lock"]] +] +name_buffer: Array[c_wchar] +unicode_buffer: Array[c_wchar] +keyboard_state: _keyboard_state_type + +def get_event_names( + scan_code: int, vk: int, is_extended: Literal[0, 1], modifiers: Sequence[str] +) -> Generator[str, None, None]: ... + +init: Callable[[], None] +keypad_keys: list[ + tuple[Literal[126], Literal[194], Literal[0]] + | tuple[Literal[28], Literal[13], Literal[1]] + | tuple[Literal[53], Literal[111], Literal[1]] + | tuple[Literal[55], Literal[106], Literal[0]] + | tuple[Literal[69], Literal[144], Literal[1]] + | tuple[Literal[71], Literal[103], Literal[0]] + | tuple[Literal[71], Literal[36], Literal[0]] + | tuple[Literal[72], Literal[104], Literal[0]] + | tuple[Literal[72], Literal[38], Literal[0]] + | tuple[Literal[73], Literal[105], Literal[0]] + | tuple[Literal[73], Literal[33], Literal[0]] + | tuple[Literal[74], Literal[109], Literal[0]] + | tuple[Literal[75], Literal[100], Literal[0]] + | tuple[Literal[75], Literal[37], Literal[0]] + | tuple[Literal[76], Literal[101], Literal[0]] + | tuple[Literal[76], Literal[12], Literal[0]] + | tuple[Literal[77], Literal[102], Literal[0]] + | tuple[Literal[77], Literal[39], Literal[0]] + | tuple[Literal[78], Literal[107], Literal[0]] + | tuple[Literal[79], Literal[35], Literal[0]] + | tuple[Literal[79], Literal[97], Literal[0]] + | tuple[Literal[80], Literal[40], Literal[0]] + | tuple[Literal[80], Literal[98], Literal[0]] + | tuple[Literal[81], Literal[34], Literal[0]] + | tuple[Literal[81], Literal[99], Literal[0]] + | tuple[Literal[82], Literal[45], Literal[0]] + | tuple[Literal[82], Literal[96], Literal[0]] + | tuple[Literal[83], Literal[110], Literal[0]] + | tuple[Literal[83], Literal[46], Literal[0]] +] +shift_is_pressed: bool +altgr_is_pressed: bool +ignore_next_right_alt: bool +shift_vks: set[int] + +def prepare_intercept(callback: Callable[[KeyboardEvent], bool]) -> None: ... +def listen(callback: Callable[[KeyboardEvent], bool]) -> None: ... +def map_name(name: str) -> Generator[tuple[int, str | int | Tuple[str, ...]], None, None]: ... +def press(code: int) -> None: ... +def release(code: int) -> None: ... +def type_unicode(character: str) -> None: ... diff --git a/stubs/keyboard/keyboard/_winmouse.pyi b/stubs/keyboard/keyboard/_winmouse.pyi new file mode 100644 index 000000000000..73c5ce66c691 --- /dev/null +++ b/stubs/keyboard/keyboard/_winmouse.pyi @@ -0,0 +1,129 @@ +from _typeshed import Incomplete +from collections.abc import Callable +from ctypes import ( + Structure, + WinDLL, + c_char as c_char, + c_int, + c_int32, + c_long, + c_short as c_short, + c_uint as c_uint, + c_uint8 as c_uint8, + c_uint32 as c_uint32, +) +from ctypes.wintypes import BOOL, DWORD, HHOOK, LPARAM, LPMSG as LPMSG, LPWSTR as LPWSTR, WCHAR as WCHAR, WPARAM +from queue import Queue +from typing_extensions import Literal, TypeAlias + +from ._mouse_event import ( + DOUBLE as DOUBLE, + DOWN as DOWN, + HORIZONTAL as HORIZONTAL, + LEFT as LEFT, + MIDDLE as MIDDLE, + RIGHT as RIGHT, + UP as UP, + VERTICAL as VERTICAL, + WHEEL as WHEEL, + X2 as X2, + ButtonEvent as ButtonEvent, + MoveEvent as MoveEvent, + WheelEvent as WheelEvent, + X as X, + _MouseButton, +) + +user32: WinDLL + +class MSLLHOOKSTRUCT(Structure): + x: c_long + y: c_long + data: c_int32 + reserved: c_int32 + flags: DWORD + time: c_int + +_POINTER_MSLLHOOKSTRUCT: TypeAlias = Incomplete # POINTER(MSLLHOOKSTRUCT) +_LRESULT: TypeAlias = Incomplete +LowLevelMouseProc: TypeAlias = Callable[[Callable[[c_int, WPARAM, LPARAM], c_int]], _POINTER_MSLLHOOKSTRUCT] +SetWindowsHookEx: Callable[[c_int, LowLevelMouseProc, c_int, c_int], HHOOK] +CallNextHookEx: Callable[[c_int, c_int, WPARAM, LPARAM], c_int] +UnhookWindowsHookEx: Callable[[HHOOK], BOOL] +GetMessage: Callable[[LPMSG, c_int, c_int, c_int], BOOL] +TranslateMessage: Callable[[LPMSG], BOOL] +DispatchMessage: Callable[[LPMSG], _LRESULT] +WM_MOUSEMOVE: Literal[512] +WM_LBUTTONDOWN: Literal[513] +WM_LBUTTONUP: Literal[514] +WM_LBUTTONDBLCLK: Literal[515] +WM_RBUTTONDOWN: Literal[516] +WM_RBUTTONUP: Literal[517] +WM_RBUTTONDBLCLK: Literal[518] +WM_MBUTTONDOWN: Literal[519] +WM_MBUTTONUP: Literal[520] +WM_MBUTTONDBLCLK: Literal[521] +WM_MOUSEWHEEL: Literal[522] +WM_XBUTTONDOWN: Literal[523] +WM_XBUTTONUP: Literal[524] +WM_XBUTTONDBLCLK: Literal[525] +WM_NCXBUTTONDOWN: Literal[171] +WM_NCXBUTTONUP: Literal[172] +WM_NCXBUTTONDBLCLK: Literal[173] +WM_MOUSEHWHEEL: Literal[526] +buttons_by_wm_code: dict[ + int, + tuple[Literal["down"], Literal["left"]] + | tuple[Literal["up"], Literal["left"]] + | tuple[Literal["double"], Literal["left"]] + | tuple[Literal["down"], Literal["right"]] + | tuple[Literal["up"], Literal["right"]] + | tuple[Literal["double"], Literal["right"]] + | tuple[Literal["down"], Literal["middle"]] + | tuple[Literal["up"], Literal["middle"]] + | tuple[Literal["double"], Literal["middle"]] + | tuple[Literal["down"], Literal["x"]] + | tuple[Literal["up"], Literal["x"]] + | tuple[Literal["double"], Literal["x"]], +] +MOUSEEVENTF_ABSOLUTE: Literal[32768] +MOUSEEVENTF_MOVE: Literal[1] +MOUSEEVENTF_WHEEL: Literal[2048] +MOUSEEVENTF_HWHEEL: Literal[4096] +MOUSEEVENTF_LEFTDOWN: Literal[2] +MOUSEEVENTF_LEFTUP: Literal[4] +MOUSEEVENTF_RIGHTDOWN: Literal[8] +MOUSEEVENTF_RIGHTUP: Literal[16] +MOUSEEVENTF_MIDDLEDOWN: Literal[32] +MOUSEEVENTF_MIDDLEUP: Literal[64] +MOUSEEVENTF_XDOWN: Literal[128] +MOUSEEVENTF_XUP: Literal[256] +simulated_mouse_codes: dict[ + tuple[Literal["wheel"], Literal["horizontal"]] + | tuple[Literal["wheel"], Literal["vertical"]] + | tuple[Literal["down"], Literal["left"]] + | tuple[Literal["up"], Literal["left"]] + | tuple[Literal["down"], Literal["right"]] + | tuple[Literal["up"], Literal["right"]] + | tuple[Literal["down"], Literal["middle"]] + | tuple[Literal["up"], Literal["middle"]] + | tuple[Literal["down"], Literal["x"]] + | tuple[Literal["up"], Literal["x"]], + int, +] +NULL: c_long +WHEEL_DELTA: Literal[120] +init: Callable[[], None] + +def listen(queue: Queue[MoveEvent | WheelEvent | ButtonEvent]): ... +def press(button: _MouseButton = ...) -> None: ... +def release(button: _MouseButton = ...) -> None: ... +def wheel(delta: int = ...) -> None: ... +def move_to(x: int | c_long, y: int | c_long) -> None: ... +def move_relative(x: int | c_long, y: int | c_long) -> None: ... + +class POINT(Structure): + x: c_long + y: c_long + +def get_position() -> tuple[c_long, c_long]: ... diff --git a/stubs/keyboard/keyboard/mouse.pyi b/stubs/keyboard/keyboard/mouse.pyi new file mode 100644 index 000000000000..6761ff9294df --- /dev/null +++ b/stubs/keyboard/keyboard/mouse.pyi @@ -0,0 +1,78 @@ +import sys +from collections.abc import Callable, Sequence +from ctypes import c_long +from typing import Tuple +from typing_extensions import Literal, ParamSpec, TypeAlias + +from ._generic import GenericListener as _GenericListener +from ._mouse_event import ( + DOUBLE as DOUBLE, + DOWN as DOWN, + LEFT as LEFT, + MIDDLE as MIDDLE, + RIGHT as RIGHT, + UP as UP, + X2 as X2, + ButtonEvent as ButtonEvent, + MoveEvent as MoveEvent, + WheelEvent as WheelEvent, + X as X, + _MouseButton, + _MouseEvent, +) + +_P = ParamSpec("_P") +_Callback: TypeAlias = Callable[[ButtonEvent | WheelEvent | MoveEvent], bool | None] + +class _MouseListener(_GenericListener): + def init(self) -> None: ... + def pre_process_event( # type: ignore[override] # Mouse specific events and return + self, event: ButtonEvent | MoveEvent | WheelEvent + ) -> Literal[True]: ... + def listen(self) -> None: ... + +def is_pressed(button: _MouseButton = ...): ... +def press(button: _MouseButton = ...) -> None: ... +def release(button: _MouseButton = ...) -> None: ... +def click(button: _MouseButton = ...) -> None: ... +def double_click(button: _MouseButton = ...) -> None: ... +def right_click() -> None: ... +def wheel(delta: int = ...) -> None: ... +def move(x: int | c_long, y: int | c_long, absolute: bool = ..., duration: float = ...) -> None: ... +def drag(start_x: int, start_y: int, end_x: int, end_y: int, absolute: bool = ..., duration: float = ...) -> None: ... + +# TODO: how to make args: _P.args ? +_P_args: TypeAlias = tuple[object, ...] + +def on_button( + callback: Callable[_P, None], + args: _P_args = ..., + buttons: list[_MouseButton] | Tuple[_MouseButton, ...] | _MouseButton = ..., + types: list[_MouseEvent] | Tuple[_MouseEvent, ...] | _MouseEvent = ..., +) -> _Callback: ... +def on_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... +def on_double_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... +def on_right_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... +def on_middle_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... +def wait(button: _MouseButton = ..., target_types: tuple[_MouseEvent] = ...) -> None: ... + +if sys.platform == "win32": + def get_position() -> tuple[c_long, c_long]: ... + +else: + def get_position() -> tuple[int, int]: ... + +def hook(callback: _Callback) -> _Callback: ... +def unhook(callback: _Callback) -> None: ... +def unhook_all() -> None: ... +def record(button: _MouseButton = ..., target_types: tuple[_MouseEvent] = ...) -> ButtonEvent | WheelEvent | MoveEvent: ... +def play( + events: Sequence[ButtonEvent | WheelEvent | MoveEvent], + speed_factor: float = ..., + include_clicks: bool = ..., + include_moves: bool = ..., + include_wheel: bool = ..., +) -> None: ... + +replay = play +hold = press diff --git a/stubs/pynput/pynput/keyboard/_base.pyi b/stubs/pynput/pynput/keyboard/_base.pyi index 6c10ba3ceb33..6f89e40d9064 100644 --- a/stubs/pynput/pynput/keyboard/_base.pyi +++ b/stubs/pynput/pynput/keyboard/_base.pyi @@ -119,4 +119,4 @@ class Listener(AbstractListener): suppress: bool = ..., **kwargs: Any, ) -> None: ... - def canonical(self, key: Key | KeyCode) -> Key | KeyCode: ... + def canonical(self, key: Key | KeyCode) -> Key | KeyCode: ... \ No newline at end of file From 8f9a3ff2b9c2a9438e7ec21c9ee4f5ab113058c4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 2 Sep 2022 03:05:16 +0000 Subject: [PATCH 02/17] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/pynput/pynput/keyboard/_base.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/pynput/pynput/keyboard/_base.pyi b/stubs/pynput/pynput/keyboard/_base.pyi index 6f89e40d9064..6c10ba3ceb33 100644 --- a/stubs/pynput/pynput/keyboard/_base.pyi +++ b/stubs/pynput/pynput/keyboard/_base.pyi @@ -119,4 +119,4 @@ class Listener(AbstractListener): suppress: bool = ..., **kwargs: Any, ) -> None: ... - def canonical(self, key: Key | KeyCode) -> Key | KeyCode: ... \ No newline at end of file + def canonical(self, key: Key | KeyCode) -> Key | KeyCode: ... From 93ac04ed6e1d4fd5db80210cd9982cbd7c3fe489 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 1 Sep 2022 23:42:37 -0400 Subject: [PATCH 03/17] Fixed CI errors --- stubs/keyboard/@tests/stubtests_allowlist.txt | 2 ++ stubs/keyboard/keyboard/__init__.pyi | 4 ++-- stubs/keyboard/keyboard/_darwinkeyboard.pyi | 4 ++-- stubs/keyboard/keyboard/_darwinmouse.pyi | 4 ++-- stubs/keyboard/keyboard/_keyboard_event.pyi | 2 +- stubs/keyboard/keyboard/_nixkeyboard.pyi | 4 ++-- stubs/keyboard/keyboard/_nixmouse.pyi | 6 ++--- stubs/keyboard/keyboard/_winkeyboard.pyi | 22 +++++++++++-------- stubs/keyboard/keyboard/_winmouse.pyi | 7 ++++-- stubs/keyboard/keyboard/mouse.pyi | 2 +- stubs/pynput/pynput/keyboard/_base.pyi | 2 +- 11 files changed, 34 insertions(+), 25 deletions(-) diff --git a/stubs/keyboard/@tests/stubtests_allowlist.txt b/stubs/keyboard/@tests/stubtests_allowlist.txt index 1a6f7d1c0234..33bdba088d28 100644 --- a/stubs/keyboard/@tests/stubtests_allowlist.txt +++ b/stubs/keyboard/@tests/stubtests_allowlist.txt @@ -1,6 +1,8 @@ # MacOs: ModuleNotFoundError: No module named 'Quartz' keyboard._darwinkeyboard keyboard._darwinmouse +# Exposing a standard type that conflicts with Y024 +keyboard._nixkeyboard.namedtuple # Exposing CFunctionType as a Callable keyboard._winkeyboard.LowLevelKeyboardProc keyboard._winmouse.LowLevelMouseProc diff --git a/stubs/keyboard/keyboard/__init__.pyi b/stubs/keyboard/keyboard/__init__.pyi index 588567aabbaa..b52be85709bf 100644 --- a/stubs/keyboard/keyboard/__init__.pyi +++ b/stubs/keyboard/keyboard/__init__.pyi @@ -2,7 +2,7 @@ from collections import Counter, defaultdict, deque from collections.abc import Callable, Generator, Sequence from queue import Queue from threading import Event as _UninterruptibleEvent -from typing import Optional, Tuple, Union +from typing import Optional, Tuple # noqa: Y022 # Arbitrary length Tuple from typing_extensions import Literal, ParamSpec, TypeAlias from ._canonical_names import all_modifiers as all_modifiers, sided_modifiers as sided_modifiers @@ -11,7 +11,7 @@ from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEve _Key: TypeAlias = int | str _ScanCodeList: TypeAlias = list[int] | Tuple[int, ...] -_ParseableHotkey: TypeAlias = _Key | list[Union[int, _ScanCodeList]] | Tuple[Union[int, _ScanCodeList], ...] +_ParseableHotkey: TypeAlias = _Key | list[int | _ScanCodeList] | Tuple[int | _ScanCodeList, ...] _Callback: TypeAlias = Callable[[KeyboardEvent], Optional[bool]] | Callable[[], Optional[bool]] _P = ParamSpec("_P") diff --git a/stubs/keyboard/keyboard/_darwinkeyboard.pyi b/stubs/keyboard/keyboard/_darwinkeyboard.pyi index 79f8b4eccbd7..02a655b643bb 100644 --- a/stubs/keyboard/keyboard/_darwinkeyboard.pyi +++ b/stubs/keyboard/keyboard/_darwinkeyboard.pyi @@ -11,7 +11,7 @@ _Unused: TypeAlias = object # https://github.com/ronaldoussoren/pyobjc/milestone/3 _CGEventTap: TypeAlias = Incomplete # Quartz.CGEventTap -_kCGEvent: TypeAlias = Incomplete # Quartz.kCGEvent +_KCGEvent: TypeAlias = Incomplete # Quartz.kCGEvent _T = TypeVar("_T") unichr = chr @@ -39,7 +39,7 @@ class KeyEventListener: tap: _CGEventTap def __init__(self, callback: Callable[[KeyboardEvent], None], blocking: bool = ...) -> None: ... def run(self) -> None: ... - def handler(self, proxy: _Unused, e_type: _kCGEvent, event: _T, refcon: _Unused) -> _T: ... + def handler(self, proxy: _Unused, e_type: _KCGEvent, event: _T, refcon: _Unused) -> _T: ... key_controller: KeyController diff --git a/stubs/keyboard/keyboard/_darwinmouse.pyi b/stubs/keyboard/keyboard/_darwinmouse.pyi index 4cf320410ae7..33abfe48e084 100644 --- a/stubs/keyboard/keyboard/_darwinmouse.pyi +++ b/stubs/keyboard/keyboard/_darwinmouse.pyi @@ -23,7 +23,7 @@ _Unused: TypeAlias = object # https://github.com/ronaldoussoren/pyobjc/milestone/3 _CGEventTap: TypeAlias = Incomplete # Quartz.CGEventTap -_kCGEventKey: TypeAlias = Incomplete # Quartz.kCGEventKey +_KCGEventKey: TypeAlias = Incomplete # Quartz.kCGEventKey _T = TypeVar("_T") class MouseEventListener: @@ -33,7 +33,7 @@ class MouseEventListener: def __init__(self, callback: Callable[[KeyboardEvent], None], blocking: bool = ...) -> None: ... tap: _CGEventTap def run(self) -> None: ... - def handler(self, proxy: _Unused, e_type: _kCGEventKey, event: _T, refcon: _Unused) -> _T: ... + def handler(self, proxy: _Unused, e_type: _KCGEventKey, event: _T, refcon: _Unused) -> _T: ... def init() -> None: ... def listen(queue: Queue[KeyboardEvent]) -> None: ... diff --git a/stubs/keyboard/keyboard/_keyboard_event.pyi b/stubs/keyboard/keyboard/_keyboard_event.pyi index efe8573cf300..717c57f1b783 100644 --- a/stubs/keyboard/keyboard/_keyboard_event.pyi +++ b/stubs/keyboard/keyboard/_keyboard_event.pyi @@ -1,4 +1,4 @@ -from typing import Tuple +from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from typing_extensions import Literal from ._canonical_names import canonical_names as canonical_names, normalize_name as normalize_name diff --git a/stubs/keyboard/keyboard/_nixkeyboard.pyi b/stubs/keyboard/keyboard/_nixkeyboard.pyi index 8f872b802dd3..7f60a309c171 100644 --- a/stubs/keyboard/keyboard/_nixkeyboard.pyi +++ b/stubs/keyboard/keyboard/_nixkeyboard.pyi @@ -1,6 +1,6 @@ -from collections import defaultdict, namedtuple as namedtuple +from collections import defaultdict from collections.abc import Callable, Generator -from typing import Tuple +from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from ._canonical_names import all_modifiers as all_modifiers, normalize_name as normalize_name from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent diff --git a/stubs/keyboard/keyboard/_nixmouse.pyi b/stubs/keyboard/keyboard/_nixmouse.pyi index cdf932c9bba9..b970c9ceceb7 100644 --- a/stubs/keyboard/keyboard/_nixmouse.pyi +++ b/stubs/keyboard/keyboard/_nixmouse.pyi @@ -2,7 +2,7 @@ from _typeshed import Incomplete from ctypes import CDLL from queue import Queue from subprocess import check_output as check_output -from typing_extensions import Literal, TypeAlias +from typing_extensions import Literal from ._mouse_event import ( DOWN as DOWN, @@ -30,8 +30,8 @@ from ._nixcommon import ( ) x11: CDLL | None -display: TypeAlias = Incomplete # x11.XOpenDisplay(None) -window: TypeAlias = Incomplete # x11.XDefaultRootWindow(display) +display: Incomplete # x11.XOpenDisplay(None) +window: Incomplete # x11.XDefaultRootWindow(display) def build_display() -> None: ... def get_position() -> tuple[int, int]: ... diff --git a/stubs/keyboard/keyboard/_winkeyboard.pyi b/stubs/keyboard/keyboard/_winkeyboard.pyi index a7368f9f9920..5666dd03e12f 100644 --- a/stubs/keyboard/keyboard/_winkeyboard.pyi +++ b/stubs/keyboard/keyboard/_winkeyboard.pyi @@ -1,3 +1,4 @@ +import sys from _typeshed import Incomplete from collections import defaultdict from collections.abc import Callable, Generator, Sequence @@ -5,7 +6,6 @@ from ctypes import ( Array, Structure, Union, - WinDLL, c_char as c_char, c_int, c_int32 as c_int32, @@ -32,16 +32,20 @@ from ctypes.wintypes import ( WPARAM, ) from threading import Lock -from typing import Tuple +from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from typing_extensions import Literal, TypeAlias from ._canonical_names import normalize_name as normalize_name from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent +if sys.platform == "win32": + from ctypes import WinDLL + + kernel32: WinDLL + user32: WinDLL + ULONG_PTR: TypeAlias = LPDWORD -kernel32: WinDLL GetModuleHandleW: Callable[[LPCWSTR | None], HMODULE] -user32: WinDLL VK_PACKET: Literal[231] INPUT_MOUSE: Literal[0] INPUT_KEYBOARD: Literal[1] @@ -96,12 +100,12 @@ UnhookWindowsHookEx: Callable[[HHOOK], BOOL] GetMessage: Callable[[LPMSG, c_int, c_int, c_int], BOOL] TranslateMessage: Callable[[LPMSG], BOOL] DispatchMessage: Callable[[LPMSG], _LRESULT] -_keyboard_state_type: TypeAlias = Array[c_uint8] -keyboard_state_type: _keyboard_state_type -GetKeyboardState: Callable[[_keyboard_state_type], BOOL] +_KeyboardStateType: TypeAlias = Array[c_uint8] +keyboard_state_type: _KeyboardStateType +GetKeyboardState: Callable[[_KeyboardStateType], BOOL] GetKeyNameText: Callable[[c_long, LPWSTR, c_int], c_int] MapVirtualKey: Callable[[c_uint, c_uint], c_uint] -ToUnicode: Callable[[c_uint, c_uint, _keyboard_state_type, LPWSTR, c_int, c_uint], c_int] +ToUnicode: Callable[[c_uint, c_uint, _KeyboardStateType, LPWSTR, c_int, c_uint], c_int] SendInput: Callable[[c_uint, _POINTER_INPUT, c_int], c_uint] MAPVK_VK_TO_CHAR: Literal[2] MAPVK_VK_TO_VSC: Literal[0] @@ -199,7 +203,7 @@ distinct_modifiers: list[ ] name_buffer: Array[c_wchar] unicode_buffer: Array[c_wchar] -keyboard_state: _keyboard_state_type +keyboard_state: _KeyboardStateType def get_event_names( scan_code: int, vk: int, is_extended: Literal[0, 1], modifiers: Sequence[str] diff --git a/stubs/keyboard/keyboard/_winmouse.pyi b/stubs/keyboard/keyboard/_winmouse.pyi index 73c5ce66c691..2bb19971a216 100644 --- a/stubs/keyboard/keyboard/_winmouse.pyi +++ b/stubs/keyboard/keyboard/_winmouse.pyi @@ -1,8 +1,8 @@ +import sys from _typeshed import Incomplete from collections.abc import Callable from ctypes import ( Structure, - WinDLL, c_char as c_char, c_int, c_int32, @@ -34,7 +34,10 @@ from ._mouse_event import ( _MouseButton, ) -user32: WinDLL +if sys.platform == "win32": + from ctypes import WinDLL + + user32: WinDLL class MSLLHOOKSTRUCT(Structure): x: c_long diff --git a/stubs/keyboard/keyboard/mouse.pyi b/stubs/keyboard/keyboard/mouse.pyi index 6761ff9294df..a7f28896f1ce 100644 --- a/stubs/keyboard/keyboard/mouse.pyi +++ b/stubs/keyboard/keyboard/mouse.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Callable, Sequence from ctypes import c_long -from typing import Tuple +from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from typing_extensions import Literal, ParamSpec, TypeAlias from ._generic import GenericListener as _GenericListener diff --git a/stubs/pynput/pynput/keyboard/_base.pyi b/stubs/pynput/pynput/keyboard/_base.pyi index 6f89e40d9064..6c10ba3ceb33 100644 --- a/stubs/pynput/pynput/keyboard/_base.pyi +++ b/stubs/pynput/pynput/keyboard/_base.pyi @@ -119,4 +119,4 @@ class Listener(AbstractListener): suppress: bool = ..., **kwargs: Any, ) -> None: ... - def canonical(self, key: Key | KeyCode) -> Key | KeyCode: ... \ No newline at end of file + def canonical(self, key: Key | KeyCode) -> Key | KeyCode: ... From 78626e35c8c3b92dadf2b8512db981017f3a5584 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 00:01:40 -0400 Subject: [PATCH 04/17] tuple --- stubs/keyboard/keyboard/__init__.pyi | 16 ++++++++-------- stubs/keyboard/keyboard/_keyboard_event.pyi | 5 ++--- stubs/keyboard/keyboard/_nixkeyboard.pyi | 9 ++++----- stubs/keyboard/keyboard/_winkeyboard.pyi | 7 +++---- stubs/keyboard/keyboard/mouse.pyi | 5 ++--- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/stubs/keyboard/keyboard/__init__.pyi b/stubs/keyboard/keyboard/__init__.pyi index b52be85709bf..7472d9f1d69e 100644 --- a/stubs/keyboard/keyboard/__init__.pyi +++ b/stubs/keyboard/keyboard/__init__.pyi @@ -2,7 +2,7 @@ from collections import Counter, defaultdict, deque from collections.abc import Callable, Generator, Sequence from queue import Queue from threading import Event as _UninterruptibleEvent -from typing import Optional, Tuple # noqa: Y022 # Arbitrary length Tuple +from typing import Optional from typing_extensions import Literal, ParamSpec, TypeAlias from ._canonical_names import all_modifiers as all_modifiers, sided_modifiers as sided_modifiers @@ -10,8 +10,8 @@ from ._generic import GenericListener as _GenericListener from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent _Key: TypeAlias = int | str -_ScanCodeList: TypeAlias = list[int] | Tuple[int, ...] -_ParseableHotkey: TypeAlias = _Key | list[int | _ScanCodeList] | Tuple[int | _ScanCodeList, ...] +_ScanCodeList: TypeAlias = list[int] | tuple[int, ...] +_ParseableHotkey: TypeAlias = _Key | list[int | _ScanCodeList] | tuple[int | _ScanCodeList, ...] _Callback: TypeAlias = Callable[[KeyboardEvent], Optional[bool]] | Callable[[], Optional[bool]] _P = ParamSpec("_P") @@ -64,8 +64,8 @@ class _KeyboardListener(_GenericListener): blocking_hooks: list[_Callback] blocking_keys: defaultdict[int, list[_Callback]] nonblocking_keys: defaultdict[int, list[_Callback]] - blocking_hotkeys: defaultdict[Tuple[int, ...], list[_Callback]] - nonblocking_hotkeys: defaultdict[Tuple[int, ...], list[_Callback]] + blocking_hotkeys: defaultdict[tuple[int, ...], list[_Callback]] + nonblocking_hotkeys: defaultdict[tuple[int, ...], list[_Callback]] filtered_modifiers: Counter[int] is_replaying: bool modifier_states: dict[_Key, str] @@ -74,8 +74,8 @@ class _KeyboardListener(_GenericListener): def direct_callback(self, event): ... def listen(self) -> None: ... -def key_to_scan_codes(key: _Key, error_if_missing: bool = ...) -> Tuple[int, ...]: ... -def parse_hotkey(hotkey: _ParseableHotkey) -> Tuple[Tuple[Tuple[int, ...], ...], ...]: ... +def key_to_scan_codes(key: _Key, error_if_missing: bool = ...) -> tuple[int, ...]: ... +def parse_hotkey(hotkey: _ParseableHotkey) -> tuple[tuple[tuple[int, ...], ...], ...]: ... def send(hotkey: _ParseableHotkey, do_press: bool = ..., do_release: bool = ...) -> None: ... press_and_release = send @@ -110,7 +110,7 @@ def remap_key(src: _Key, dst: _ParseableHotkey) -> Callable[[], None]: ... unremap_key = unhook_key -def parse_hotkey_combinations(hotkey: _ParseableHotkey) -> Tuple[Tuple[Tuple[int, ...], ...], ...]: ... +def parse_hotkey_combinations(hotkey: _ParseableHotkey) -> tuple[tuple[tuple[int, ...], ...], ...]: ... # TODO: how to make args: _P.args ? diff --git a/stubs/keyboard/keyboard/_keyboard_event.pyi b/stubs/keyboard/keyboard/_keyboard_event.pyi index 717c57f1b783..30a2882f2701 100644 --- a/stubs/keyboard/keyboard/_keyboard_event.pyi +++ b/stubs/keyboard/keyboard/_keyboard_event.pyi @@ -1,4 +1,3 @@ -from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from typing_extensions import Literal from ._canonical_names import canonical_names as canonical_names, normalize_name as normalize_name @@ -13,7 +12,7 @@ class KeyboardEvent: name: str | None time: float | None device: str | None - modifiers: Tuple[str, ...] | None + modifiers: tuple[str, ...] | None is_keypad: bool | None def __init__( @@ -23,7 +22,7 @@ class KeyboardEvent: name: str | None = ..., time: float | None = ..., device: str | None = ..., - modifiers: Tuple[str, ...] | None = ..., + modifiers: tuple[str, ...] | None = ..., is_keypad: bool | None = ..., ) -> None: ... def to_json(self, ensure_ascii: bool = ...) -> str: ... diff --git a/stubs/keyboard/keyboard/_nixkeyboard.pyi b/stubs/keyboard/keyboard/_nixkeyboard.pyi index 7f60a309c171..c9b3260b9b13 100644 --- a/stubs/keyboard/keyboard/_nixkeyboard.pyi +++ b/stubs/keyboard/keyboard/_nixkeyboard.pyi @@ -1,6 +1,5 @@ from collections import defaultdict from collections.abc import Callable, Generator -from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from ._canonical_names import all_modifiers as all_modifiers, normalize_name as normalize_name from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent @@ -15,11 +14,11 @@ from ._nixcommon import ( def cleanup_key(name: str) -> tuple[str, bool]: ... def cleanup_modifier(modifier: str) -> str: ... -to_name: defaultdict[tuple[int, Tuple[str, ...]], list[str] | str] -from_name: defaultdict[str, list[tuple[int, Tuple[str, ...]]]] +to_name: defaultdict[tuple[int, tuple[str, ...]], list[str] | str] +from_name: defaultdict[str, list[tuple[int, tuple[str, ...]]]] keypad_scan_codes: set[str] -def register_key(key_and_modifiers: tuple[int, Tuple[str, ...]], name: str) -> None: ... +def register_key(key_and_modifiers: tuple[int, tuple[str, ...]], name: str) -> None: ... def build_tables() -> None: ... device: AggregatedEventDevice | EventDevice | None @@ -31,7 +30,7 @@ pressed_modifiers: set[str] def listen(callback: Callable[[KeyboardEvent], None]) -> None: ... def write_event(scan_code: int, is_down: bool | int) -> None: ... -def map_name(name: str) -> Generator[tuple[int, Tuple[str, ...]], None, None]: ... +def map_name(name: str) -> Generator[tuple[int, tuple[str, ...]], None, None]: ... def press(scan_code: int) -> None: ... def release(scan_code: int) -> None: ... def type_unicode(character: str | bytes | bytearray) -> None: ... diff --git a/stubs/keyboard/keyboard/_winkeyboard.pyi b/stubs/keyboard/keyboard/_winkeyboard.pyi index 5666dd03e12f..2331f6107736 100644 --- a/stubs/keyboard/keyboard/_winkeyboard.pyi +++ b/stubs/keyboard/keyboard/_winkeyboard.pyi @@ -32,7 +32,6 @@ from ctypes.wintypes import ( WPARAM, ) from threading import Lock -from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from typing_extensions import Literal, TypeAlias from ._canonical_names import normalize_name as normalize_name @@ -188,8 +187,8 @@ official_virtual_keys: dict[ | tuple[Literal["p"], Literal[False]], ] tables_lock: Lock -to_name: defaultdict[tuple[int, int, int, str | int | Tuple[str, ...]] | tuple[int, int, int, int, int], list[str]] -from_name: defaultdict[str, list[tuple[int, Tuple[str | int | Tuple[str, ...], ...]]]] +to_name: defaultdict[tuple[int, int, int, str | int | tuple[str, ...]] | tuple[int, int, int, int, int], list[str]] +from_name: defaultdict[str, list[tuple[int, tuple[str | int | tuple[str, ...], ...]]]] scan_code_to_vk: dict[int, int] distinct_modifiers: list[ tuple[()] @@ -248,7 +247,7 @@ shift_vks: set[int] def prepare_intercept(callback: Callable[[KeyboardEvent], bool]) -> None: ... def listen(callback: Callable[[KeyboardEvent], bool]) -> None: ... -def map_name(name: str) -> Generator[tuple[int, str | int | Tuple[str, ...]], None, None]: ... +def map_name(name: str) -> Generator[tuple[int, str | int | tuple[str, ...]], None, None]: ... def press(code: int) -> None: ... def release(code: int) -> None: ... def type_unicode(character: str) -> None: ... diff --git a/stubs/keyboard/keyboard/mouse.pyi b/stubs/keyboard/keyboard/mouse.pyi index a7f28896f1ce..97b6c6ed56c7 100644 --- a/stubs/keyboard/keyboard/mouse.pyi +++ b/stubs/keyboard/keyboard/mouse.pyi @@ -1,7 +1,6 @@ import sys from collections.abc import Callable, Sequence from ctypes import c_long -from typing import Tuple # noqa: Y022 # Arbitrary length Tuple from typing_extensions import Literal, ParamSpec, TypeAlias from ._generic import GenericListener as _GenericListener @@ -47,8 +46,8 @@ _P_args: TypeAlias = tuple[object, ...] def on_button( callback: Callable[_P, None], args: _P_args = ..., - buttons: list[_MouseButton] | Tuple[_MouseButton, ...] | _MouseButton = ..., - types: list[_MouseEvent] | Tuple[_MouseEvent, ...] | _MouseEvent = ..., + buttons: list[_MouseButton] | tuple[_MouseButton, ...] | _MouseButton = ..., + types: list[_MouseEvent] | tuple[_MouseEvent, ...] | _MouseEvent = ..., ) -> _Callback: ... def on_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... def on_double_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... From 403d8b99ff6edacbc45894daf841ba9d8a3602f1 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 00:10:27 -0400 Subject: [PATCH 05/17] stubtest_allowlist --- .../{stubtests_allowlist.txt => stubtest_allowlist.txt} | 4 ++++ 1 file changed, 4 insertions(+) rename stubs/keyboard/@tests/{stubtests_allowlist.txt => stubtest_allowlist.txt} (81%) diff --git a/stubs/keyboard/@tests/stubtests_allowlist.txt b/stubs/keyboard/@tests/stubtest_allowlist.txt similarity index 81% rename from stubs/keyboard/@tests/stubtests_allowlist.txt rename to stubs/keyboard/@tests/stubtest_allowlist.txt index 33bdba088d28..892fa2c7d3c7 100644 --- a/stubs/keyboard/@tests/stubtests_allowlist.txt +++ b/stubs/keyboard/@tests/stubtest_allowlist.txt @@ -1,3 +1,7 @@ +# Tests and __main__ +keyboard.__main__ +keyboard._keyboard_tests +keyboard._mouse_tests # MacOs: ModuleNotFoundError: No module named 'Quartz' keyboard._darwinkeyboard keyboard._darwinmouse From e4d65c11c4e316f2efda8d08058c4e37adae2581 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 00:12:52 -0400 Subject: [PATCH 06/17] Removed unused allowlist entry --- stubs/keyboard/@tests/stubtest_allowlist.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stubs/keyboard/@tests/stubtest_allowlist.txt b/stubs/keyboard/@tests/stubtest_allowlist.txt index 892fa2c7d3c7..aeebdb394e0e 100644 --- a/stubs/keyboard/@tests/stubtest_allowlist.txt +++ b/stubs/keyboard/@tests/stubtest_allowlist.txt @@ -5,10 +5,5 @@ keyboard._mouse_tests # MacOs: ModuleNotFoundError: No module named 'Quartz' keyboard._darwinkeyboard keyboard._darwinmouse -# Exposing a standard type that conflicts with Y024 -keyboard._nixkeyboard.namedtuple -# Exposing CFunctionType as a Callable -keyboard._winkeyboard.LowLevelKeyboardProc -keyboard._winmouse.LowLevelMouseProc # Defaults don't align with possible values keyboard.mouse.wait From 4aebccfe7d461de309242e80680ae46a05f75b87 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 00:15:06 -0400 Subject: [PATCH 07/17] module 'ctypes' has no attribute 'WinDLL' --- stubs/keyboard/@tests/stubtest_allowlist.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stubs/keyboard/@tests/stubtest_allowlist.txt b/stubs/keyboard/@tests/stubtest_allowlist.txt index aeebdb394e0e..8eee401cf62b 100644 --- a/stubs/keyboard/@tests/stubtest_allowlist.txt +++ b/stubs/keyboard/@tests/stubtest_allowlist.txt @@ -5,5 +5,10 @@ keyboard._mouse_tests # MacOs: ModuleNotFoundError: No module named 'Quartz' keyboard._darwinkeyboard keyboard._darwinmouse +# Exposing a standard type that conflicts with Y024 +keyboard._nixkeyboard.namedtuple +# Windows: AttributeError: module 'ctypes' has no attribute 'WinDLL' +keyboard._winkeyboard +keyboard._winmouse # Defaults don't align with possible values keyboard.mouse.wait From a9772950b679297ec350d858a56c10d49e3d2cf5 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 00:17:28 -0400 Subject: [PATCH 08/17] keyboard.mouse.on_button --- stubs/keyboard/@tests/stubtest_allowlist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/stubs/keyboard/@tests/stubtest_allowlist.txt b/stubs/keyboard/@tests/stubtest_allowlist.txt index 8eee401cf62b..31ff0fcaa2c8 100644 --- a/stubs/keyboard/@tests/stubtest_allowlist.txt +++ b/stubs/keyboard/@tests/stubtest_allowlist.txt @@ -11,4 +11,5 @@ keyboard._nixkeyboard.namedtuple keyboard._winkeyboard keyboard._winmouse # Defaults don't align with possible values +keyboard.mouse.on_button keyboard.mouse.wait From 85207136ad7081097f1cb18758bcec2f230fa18d Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 00:18:38 -0400 Subject: [PATCH 09/17] More unused entries --- stubs/keyboard/@tests/stubtest_allowlist.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/stubs/keyboard/@tests/stubtest_allowlist.txt b/stubs/keyboard/@tests/stubtest_allowlist.txt index 31ff0fcaa2c8..02f25e9c73e8 100644 --- a/stubs/keyboard/@tests/stubtest_allowlist.txt +++ b/stubs/keyboard/@tests/stubtest_allowlist.txt @@ -5,8 +5,6 @@ keyboard._mouse_tests # MacOs: ModuleNotFoundError: No module named 'Quartz' keyboard._darwinkeyboard keyboard._darwinmouse -# Exposing a standard type that conflicts with Y024 -keyboard._nixkeyboard.namedtuple # Windows: AttributeError: module 'ctypes' has no attribute 'WinDLL' keyboard._winkeyboard keyboard._winmouse From f4b79fd8f5ed2be94009e61bd73dc405b4fdd5d7 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 01:25:39 -0400 Subject: [PATCH 10/17] Updated from usage and checkign which types work for keys --- stubs/keyboard/keyboard/__init__.pyi | 35 ++++++++++++---------------- stubs/keyboard/keyboard/mouse.pyi | 22 ++++++++--------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/stubs/keyboard/keyboard/__init__.pyi b/stubs/keyboard/keyboard/__init__.pyi index 7472d9f1d69e..dd9104b59308 100644 --- a/stubs/keyboard/keyboard/__init__.pyi +++ b/stubs/keyboard/keyboard/__init__.pyi @@ -3,7 +3,7 @@ from collections.abc import Callable, Generator, Sequence from queue import Queue from threading import Event as _UninterruptibleEvent from typing import Optional -from typing_extensions import Literal, ParamSpec, TypeAlias +from typing_extensions import Literal, TypeAlias from ._canonical_names import all_modifiers as all_modifiers, sided_modifiers as sided_modifiers from ._generic import GenericListener as _GenericListener @@ -13,14 +13,16 @@ _Key: TypeAlias = int | str _ScanCodeList: TypeAlias = list[int] | tuple[int, ...] _ParseableHotkey: TypeAlias = _Key | list[int | _ScanCodeList] | tuple[int | _ScanCodeList, ...] _Callback: TypeAlias = Callable[[KeyboardEvent], Optional[bool]] | Callable[[], Optional[bool]] -_P = ParamSpec("_P") +# Can't use ParamSpecArgs on `args`, only on `*args` +# _P = ParamSpec("_P") +_P: TypeAlias = tuple[object, ...] version: str class _Event(_UninterruptibleEvent): def wait(self) -> None: ... # type: ignore[override] # Actual implementation -def is_modifier(key: _Key) -> bool: ... +def is_modifier(key: _Key | None) -> bool: ... class _KeyboardListener(_GenericListener): transition_table: dict[ @@ -74,7 +76,7 @@ class _KeyboardListener(_GenericListener): def direct_callback(self, event): ... def listen(self) -> None: ... -def key_to_scan_codes(key: _Key, error_if_missing: bool = ...) -> tuple[int, ...]: ... +def key_to_scan_codes(key: _ParseableHotkey, error_if_missing: bool = ...) -> tuple[int, ...]: ... def parse_hotkey(hotkey: _ParseableHotkey) -> tuple[tuple[tuple[int, ...], ...], ...]: ... def send(hotkey: _ParseableHotkey, do_press: bool = ..., do_release: bool = ...) -> None: ... @@ -83,41 +85,34 @@ press_and_release = send def press(hotkey: _ParseableHotkey) -> None: ... def release(hotkey: _ParseableHotkey) -> None: ... -# is_pressed cannot check multi-step hotkeys +# is_pressed cannot check multi-step hotkeys, so not using _ParseableHotkey def is_pressed(hotkey: _Key | _ScanCodeList) -> bool: ... - -# TODO: how to make args: _P.args ? -_P_args: TypeAlias = tuple[object, ...] - -def call_later(fn: Callable[_P, None], args: tuple[object, ...] = ..., delay: float = ...) -> None: ... +def call_later(fn: Callable[..., None], args: _P = ..., delay: float = ...) -> None: ... def hook(callback: _Callback, suppress: bool = ..., on_remove: Callable[[], None] = ...) -> Callable[[], None]: ... def on_press(callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... def on_release(callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... -def hook_key(key: _Key, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... -def on_press_key(key: _Key, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... -def on_release_key(key: _Key, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def hook_key(key: _ParseableHotkey, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def on_press_key(key: _ParseableHotkey, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... +def on_release_key(key: _ParseableHotkey, callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... def unhook(remove: _Callback) -> None: ... unhook_key = unhook def unhook_all() -> None: ... -def block_key(key: _Key) -> Callable[[], None]: ... +def block_key(key: _ParseableHotkey) -> Callable[[], None]: ... unblock_key = unhook_key -def remap_key(src: _Key, dst: _ParseableHotkey) -> Callable[[], None]: ... +def remap_key(src: _ParseableHotkey, dst: _ParseableHotkey) -> Callable[[], None]: ... unremap_key = unhook_key def parse_hotkey_combinations(hotkey: _ParseableHotkey) -> tuple[tuple[tuple[int, ...], ...], ...]: ... - -# TODO: how to make args: _P.args ? - def add_hotkey( hotkey: _ParseableHotkey, - callback: Callable[_P, bool | None], - args: _P_args = ..., + callback: Callable[..., bool | None], + args: _P = ..., suppress: bool = ..., timeout: float = ..., trigger_on_release: bool = ..., diff --git a/stubs/keyboard/keyboard/mouse.pyi b/stubs/keyboard/keyboard/mouse.pyi index 97b6c6ed56c7..7dc3f930acb9 100644 --- a/stubs/keyboard/keyboard/mouse.pyi +++ b/stubs/keyboard/keyboard/mouse.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Callable, Sequence from ctypes import c_long -from typing_extensions import Literal, ParamSpec, TypeAlias +from typing_extensions import Literal, TypeAlias from ._generic import GenericListener as _GenericListener from ._mouse_event import ( @@ -20,7 +20,9 @@ from ._mouse_event import ( _MouseEvent, ) -_P = ParamSpec("_P") +# Can't use ParamSpecArgs on `args`, only on `*args` +# _P = ParamSpec("_P") +_P: TypeAlias = tuple[object, ...] _Callback: TypeAlias = Callable[[ButtonEvent | WheelEvent | MoveEvent], bool | None] class _MouseListener(_GenericListener): @@ -39,20 +41,16 @@ def right_click() -> None: ... def wheel(delta: int = ...) -> None: ... def move(x: int | c_long, y: int | c_long, absolute: bool = ..., duration: float = ...) -> None: ... def drag(start_x: int, start_y: int, end_x: int, end_y: int, absolute: bool = ..., duration: float = ...) -> None: ... - -# TODO: how to make args: _P.args ? -_P_args: TypeAlias = tuple[object, ...] - def on_button( - callback: Callable[_P, None], - args: _P_args = ..., + callback: Callable[..., None], + args: _P = ..., buttons: list[_MouseButton] | tuple[_MouseButton, ...] | _MouseButton = ..., types: list[_MouseEvent] | tuple[_MouseEvent, ...] | _MouseEvent = ..., ) -> _Callback: ... -def on_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... -def on_double_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... -def on_right_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... -def on_middle_click(callback: Callable[_P, None], args: _P_args = ...) -> _Callback: ... +def on_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... +def on_double_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... +def on_right_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... +def on_middle_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... def wait(button: _MouseButton = ..., target_types: tuple[_MouseEvent] = ...) -> None: ... if sys.platform == "win32": From 92b3c3718ea47339aa9dba2ad5f6635b041c2cdb Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 01:28:10 -0400 Subject: [PATCH 11/17] scan_code should *in theory* never be None. This is also according to docs --- stubs/keyboard/keyboard/_keyboard_event.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/keyboard/keyboard/_keyboard_event.pyi b/stubs/keyboard/keyboard/_keyboard_event.pyi index 30a2882f2701..aecb95a5dce2 100644 --- a/stubs/keyboard/keyboard/_keyboard_event.pyi +++ b/stubs/keyboard/keyboard/_keyboard_event.pyi @@ -8,7 +8,7 @@ KEY_UP: Literal["up"] class KeyboardEvent: event_type: Literal["down", "up"] | None - scan_code: int | None + scan_code: int name: str | None time: float | None device: str | None @@ -18,7 +18,7 @@ class KeyboardEvent: def __init__( self, event_type: Literal["down", "up"] | None, - scan_code: int | None, + scan_code: int, name: str | None = ..., time: float | None = ..., device: str | None = ..., From 48bb876627c54a24de201b4a68e61ce52eb4d433 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 01:33:20 -0400 Subject: [PATCH 12/17] allowlist scan_code --- stubs/keyboard/@tests/stubtest_allowlist.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stubs/keyboard/@tests/stubtest_allowlist.txt b/stubs/keyboard/@tests/stubtest_allowlist.txt index 02f25e9c73e8..5770d30e723e 100644 --- a/stubs/keyboard/@tests/stubtest_allowlist.txt +++ b/stubs/keyboard/@tests/stubtest_allowlist.txt @@ -8,6 +8,10 @@ keyboard._darwinmouse # Windows: AttributeError: module 'ctypes' has no attribute 'WinDLL' keyboard._winkeyboard keyboard._winmouse +# scan_code *should* never be None in real use. This is also according to docs. +keyboard.KeyboardEvent.scan_code +keyboard._keyboard_event.KeyboardEvent.scan_code +keyboard._nixkeyboard.KeyboardEvent.scan_code # Defaults don't align with possible values keyboard.mouse.on_button keyboard.mouse.wait From b997dca1a44a45b539274fd9554c8c8d51b85df3 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 17:35:48 -0400 Subject: [PATCH 13/17] Removed unnecessary private definitions --- stubs/keyboard/keyboard/_darwinkeyboard.pyi | 52 ---- stubs/keyboard/keyboard/_darwinmouse.pyi | 44 ---- stubs/keyboard/keyboard/_generic.pyi | 4 +- stubs/keyboard/keyboard/_mouse_event.pyi | 8 +- stubs/keyboard/keyboard/_nixcommon.pyi | 45 ---- stubs/keyboard/keyboard/_nixkeyboard.pyi | 36 --- stubs/keyboard/keyboard/_nixmouse.pyi | 68 ------ stubs/keyboard/keyboard/_winkeyboard.pyi | 253 -------------------- stubs/keyboard/keyboard/_winmouse.pyi | 132 ---------- stubs/keyboard/keyboard/mouse.pyi | 13 +- 10 files changed, 14 insertions(+), 641 deletions(-) delete mode 100644 stubs/keyboard/keyboard/_darwinkeyboard.pyi delete mode 100644 stubs/keyboard/keyboard/_darwinmouse.pyi delete mode 100644 stubs/keyboard/keyboard/_nixcommon.pyi delete mode 100644 stubs/keyboard/keyboard/_nixkeyboard.pyi delete mode 100644 stubs/keyboard/keyboard/_nixmouse.pyi delete mode 100644 stubs/keyboard/keyboard/_winkeyboard.pyi delete mode 100644 stubs/keyboard/keyboard/_winmouse.pyi diff --git a/stubs/keyboard/keyboard/_darwinkeyboard.pyi b/stubs/keyboard/keyboard/_darwinkeyboard.pyi deleted file mode 100644 index 02a655b643bb..000000000000 --- a/stubs/keyboard/keyboard/_darwinkeyboard.pyi +++ /dev/null @@ -1,52 +0,0 @@ -from _typeshed import Incomplete -from collections.abc import Callable, Generator, Sequence -from ctypes import CDLL -from typing import TypeVar -from typing_extensions import TypeAlias - -from ._canonical_names import normalize_name as normalize_name -from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent - -_Unused: TypeAlias = object - -# https://github.com/ronaldoussoren/pyobjc/milestone/3 -_CGEventTap: TypeAlias = Incomplete # Quartz.CGEventTap -_KCGEvent: TypeAlias = Incomplete # Quartz.kCGEvent -_T = TypeVar("_T") - -unichr = chr -Carbon: CDLL - -class KeyMap: - non_layout_keys: dict[int, str] - layout_specific_keys: dict[int, tuple[str, str]] - def character_to_vk(self, character: str) -> tuple[int, list[str]]: ... - def vk_to_character(self, vk: int, modifiers: Sequence[str] = ...): ... - -class KeyController: - key_map: KeyMap - current_modifiers: dict[str, bool] - media_keys: dict[str, int] - def press(self, key_code: int) -> None: ... - def release(self, key_code: int) -> None: ... - def map_char(self, character: str) -> tuple[int, list[str]]: ... - def map_scan_code(self, scan_code: int) -> int | str | None: ... - -class KeyEventListener: - blocking: bool - callback: Callable[[KeyboardEvent], None] - listening: bool - tap: _CGEventTap - def __init__(self, callback: Callable[[KeyboardEvent], None], blocking: bool = ...) -> None: ... - def run(self) -> None: ... - def handler(self, proxy: _Unused, e_type: _KCGEvent, event: _T, refcon: _Unused) -> _T: ... - -key_controller: KeyController - -def init() -> None: ... -def press(scan_code: int) -> None: ... -def release(scan_code: int) -> None: ... -def map_name(name: str) -> Generator[tuple[int, list[str]], None, None]: ... -def name_from_scancode(scan_code: int) -> int | str | None: ... -def listen(callback: Callable[[KeyboardEvent], None]) -> None: ... -def type_unicode(character: str) -> None: ... diff --git a/stubs/keyboard/keyboard/_darwinmouse.pyi b/stubs/keyboard/keyboard/_darwinmouse.pyi deleted file mode 100644 index 33abfe48e084..000000000000 --- a/stubs/keyboard/keyboard/_darwinmouse.pyi +++ /dev/null @@ -1,44 +0,0 @@ -from _typeshed import Incomplete -from collections.abc import Callable -from queue import Queue -from typing import TypeVar -from typing_extensions import TypeAlias - -from ._keyboard_event import KeyboardEvent -from ._mouse_event import ( - DOWN as DOWN, - LEFT as LEFT, - MIDDLE as MIDDLE, - RIGHT as RIGHT, - UP as UP, - X2 as X2, - ButtonEvent as ButtonEvent, - MoveEvent as MoveEvent, - WheelEvent as WheelEvent, - X as X, - _MouseButton, -) - -_Unused: TypeAlias = object - -# https://github.com/ronaldoussoren/pyobjc/milestone/3 -_CGEventTap: TypeAlias = Incomplete # Quartz.CGEventTap -_KCGEventKey: TypeAlias = Incomplete # Quartz.kCGEventKey -_T = TypeVar("_T") - -class MouseEventListener: - blocking: bool - callback: Callable[[KeyboardEvent], None] - listening: bool - def __init__(self, callback: Callable[[KeyboardEvent], None], blocking: bool = ...) -> None: ... - tap: _CGEventTap - def run(self) -> None: ... - def handler(self, proxy: _Unused, e_type: _KCGEventKey, event: _T, refcon: _Unused) -> _T: ... - -def init() -> None: ... -def listen(queue: Queue[KeyboardEvent]) -> None: ... -def press(button: _MouseButton = ...) -> None: ... -def release(button: _MouseButton = ...) -> None: ... -def wheel(delta: int = ...) -> None: ... -def move_to(x: int, y: int) -> None: ... -def get_position() -> tuple[int, int]: ... diff --git a/stubs/keyboard/keyboard/_generic.pyi b/stubs/keyboard/keyboard/_generic.pyi index dd6a6d2fbf19..49c88a43f351 100644 --- a/stubs/keyboard/keyboard/_generic.pyi +++ b/stubs/keyboard/keyboard/_generic.pyi @@ -4,9 +4,9 @@ from threading import Lock, Thread from typing_extensions import Literal, TypeAlias from ._keyboard_event import KeyboardEvent -from ._mouse_event import ButtonEvent, MoveEvent, WheelEvent +from ._mouse_event import _MouseEvent -_Event: TypeAlias = KeyboardEvent | ButtonEvent | WheelEvent | MoveEvent +_Event: TypeAlias = KeyboardEvent | _MouseEvent class GenericListener: lock: Lock diff --git a/stubs/keyboard/keyboard/_mouse_event.pyi b/stubs/keyboard/keyboard/_mouse_event.pyi index 6089b32b40ba..49dbc97dadf7 100644 --- a/stubs/keyboard/keyboard/_mouse_event.pyi +++ b/stubs/keyboard/keyboard/_mouse_event.pyi @@ -2,6 +2,8 @@ import sys from typing import NamedTuple from typing_extensions import Literal, TypeAlias +_MouseEvent: TypeAlias = ButtonEvent | WheelEvent | MoveEvent + LEFT: Literal["left"] RIGHT: Literal["right"] MIDDLE: Literal["middle"] @@ -22,12 +24,12 @@ else: _MouseButton: TypeAlias = Literal["left", "right", "middle"] if sys.platform == "win32": - _MouseEvent: TypeAlias = Literal["up", "down", "double", "wheel"] + _MouseEventType: TypeAlias = Literal["up", "down", "double", "wheel"] else: - _MouseEvent: TypeAlias = Literal["up", "down"] + _MouseEventType: TypeAlias = Literal["up", "down"] class ButtonEvent(NamedTuple): - event_type: _MouseEvent + event_type: _MouseEventType button: _MouseButton time: float diff --git a/stubs/keyboard/keyboard/_nixcommon.pyi b/stubs/keyboard/keyboard/_nixcommon.pyi deleted file mode 100644 index 5a77e8ceecec..000000000000 --- a/stubs/keyboard/keyboard/_nixcommon.pyi +++ /dev/null @@ -1,45 +0,0 @@ -from _typeshed import Incomplete -from collections.abc import Generator, Sequence -from io import BufferedReader, BufferedWriter -from queue import Queue -from typing import NamedTuple -from typing_extensions import Literal - -event_bin_format: Literal["llHHI"] -EV_SYN: Literal[0] -EV_KEY: Literal[1] -EV_REL: Literal[2] -EV_ABS: Literal[3] -EV_MSC: Literal[4] - -def make_uinput() -> BufferedWriter: ... - -class EventDevice: - path: str - def __init__(self, path: str) -> None: ... - @property - def input_file(self) -> BufferedReader: ... - @property - def output_file(self) -> BufferedWriter: ... - def read_event(self) -> tuple[float, Incomplete, Incomplete, Incomplete, str]: ... - def write_event(self, type, code, value) -> None: ... - -class AggregatedEventDevice: - event_queue: Queue[tuple[float, Incomplete, Incomplete, Incomplete, str]] - devices: Sequence[EventDevice] - output: EventDevice - def __init__(self, devices: Sequence[EventDevice], output: EventDevice | None = ...) -> None: ... - def read_event(self) -> EventDevice: ... - def write_event(self, type, code, value) -> None: ... - -class DeviceDescription(NamedTuple): - event_file: str - is_mouse: bool - is_keyboard: bool - -device_pattern: str - -def list_devices_from_proc(type_name: str) -> Generator[EventDevice, None, None]: ... -def list_devices_from_by_id(name_suffix: str, by_id: bool = ...) -> Generator[EventDevice, None, None]: ... -def aggregate_devices(type_name: str) -> AggregatedEventDevice | EventDevice: ... -def ensure_root() -> None: ... diff --git a/stubs/keyboard/keyboard/_nixkeyboard.pyi b/stubs/keyboard/keyboard/_nixkeyboard.pyi deleted file mode 100644 index c9b3260b9b13..000000000000 --- a/stubs/keyboard/keyboard/_nixkeyboard.pyi +++ /dev/null @@ -1,36 +0,0 @@ -from collections import defaultdict -from collections.abc import Callable, Generator - -from ._canonical_names import all_modifiers as all_modifiers, normalize_name as normalize_name -from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent -from ._nixcommon import ( - EV_KEY as EV_KEY, - AggregatedEventDevice, - EventDevice, - aggregate_devices as aggregate_devices, - ensure_root as ensure_root, -) - -def cleanup_key(name: str) -> tuple[str, bool]: ... -def cleanup_modifier(modifier: str) -> str: ... - -to_name: defaultdict[tuple[int, tuple[str, ...]], list[str] | str] -from_name: defaultdict[str, list[tuple[int, tuple[str, ...]]]] -keypad_scan_codes: set[str] - -def register_key(key_and_modifiers: tuple[int, tuple[str, ...]], name: str) -> None: ... -def build_tables() -> None: ... - -device: AggregatedEventDevice | EventDevice | None - -def build_device() -> None: ... -def init() -> None: ... - -pressed_modifiers: set[str] - -def listen(callback: Callable[[KeyboardEvent], None]) -> None: ... -def write_event(scan_code: int, is_down: bool | int) -> None: ... -def map_name(name: str) -> Generator[tuple[int, tuple[str, ...]], None, None]: ... -def press(scan_code: int) -> None: ... -def release(scan_code: int) -> None: ... -def type_unicode(character: str | bytes | bytearray) -> None: ... diff --git a/stubs/keyboard/keyboard/_nixmouse.pyi b/stubs/keyboard/keyboard/_nixmouse.pyi deleted file mode 100644 index b970c9ceceb7..000000000000 --- a/stubs/keyboard/keyboard/_nixmouse.pyi +++ /dev/null @@ -1,68 +0,0 @@ -from _typeshed import Incomplete -from ctypes import CDLL -from queue import Queue -from subprocess import check_output as check_output -from typing_extensions import Literal - -from ._mouse_event import ( - DOWN as DOWN, - LEFT as LEFT, - MIDDLE as MIDDLE, - RIGHT as RIGHT, - UP as UP, - X2 as X2, - ButtonEvent as ButtonEvent, - MoveEvent as MoveEvent, - WheelEvent as WheelEvent, - X as X, - _MouseButton, -) -from ._nixcommon import ( - EV_ABS as EV_ABS, - EV_KEY as EV_KEY, - EV_MSC as EV_MSC, - EV_REL as EV_REL, - EV_SYN as EV_SYN, - AggregatedEventDevice, - EventDevice, - aggregate_devices as aggregate_devices, - ensure_root as ensure_root, -) - -x11: CDLL | None -display: Incomplete # x11.XOpenDisplay(None) -window: Incomplete # x11.XDefaultRootWindow(display) - -def build_display() -> None: ... -def get_position() -> tuple[int, int]: ... -def move_to(x, y) -> None: ... - -REL_X: Literal[0] -REL_Y: Literal[1] -REL_Z: Literal[2] -REL_HWHEEL: Literal[6] -REL_WHEEL: Literal[8] - -ABS_X: Literal[0] -ABS_Y: Literal[1] - -BTN_MOUSE: Literal[272] -BTN_LEFT: Literal[272] -BTN_RIGHT: Literal[273] -BTN_MIDDLE: Literal[274] -BTN_SIDE: Literal[275] -BTN_EXTRA: Literal[276] - -button_by_code: dict[int, str] -code_by_button: dict[str, int] -device: AggregatedEventDevice | EventDevice | None - -def build_device() -> None: ... - -init = build_device - -def listen(queue: Queue[ButtonEvent | WheelEvent | MoveEvent]) -> None: ... -def press(button: _MouseButton = ...) -> None: ... -def release(button: _MouseButton = ...) -> None: ... -def move_relative(x: int, y: int) -> None: ... -def wheel(delta: int = ...) -> None: ... diff --git a/stubs/keyboard/keyboard/_winkeyboard.pyi b/stubs/keyboard/keyboard/_winkeyboard.pyi deleted file mode 100644 index 2331f6107736..000000000000 --- a/stubs/keyboard/keyboard/_winkeyboard.pyi +++ /dev/null @@ -1,253 +0,0 @@ -import sys -from _typeshed import Incomplete -from collections import defaultdict -from collections.abc import Callable, Generator, Sequence -from ctypes import ( - Array, - Structure, - Union, - c_char as c_char, - c_int, - c_int32 as c_int32, - c_long, - c_short, - c_uint, - c_uint8, - c_uint32 as c_uint32, - c_wchar, -) -from ctypes.wintypes import ( - BOOL, - DWORD, - HHOOK, - HMODULE, - LONG, - LPARAM, - LPCWSTR, - LPDWORD, - LPMSG as LPMSG, - LPWSTR, - WCHAR, - WORD, - WPARAM, -) -from threading import Lock -from typing_extensions import Literal, TypeAlias - -from ._canonical_names import normalize_name as normalize_name -from ._keyboard_event import KEY_DOWN as KEY_DOWN, KEY_UP as KEY_UP, KeyboardEvent as KeyboardEvent - -if sys.platform == "win32": - from ctypes import WinDLL - - kernel32: WinDLL - user32: WinDLL - -ULONG_PTR: TypeAlias = LPDWORD -GetModuleHandleW: Callable[[LPCWSTR | None], HMODULE] -VK_PACKET: Literal[231] -INPUT_MOUSE: Literal[0] -INPUT_KEYBOARD: Literal[1] -INPUT_HARDWARE: Literal[2] -KEYEVENTF_KEYUP: Literal[2] -KEYEVENTF_UNICODE: Literal[4] - -class KBDLLHOOKSTRUCT(Structure): - vk_code: DWORD - scan_code: DWORD - flags: DWORD - time: c_int - dwExtraInfo: ULONG_PTR - -class MOUSEINPUT(Structure): - dx: LONG - dy: LONG - mouseData: DWORD - dwFlags: DWORD - time: DWORD - dwExtraInfo: ULONG_PTR - -class KEYBDINPUT(Structure): - wVk: WORD - wScan: WORD - dwFlags: DWORD - time: DWORD - dwExtraInfo: ULONG_PTR - -class HARDWAREINPUT(Structure): - uMsg: DWORD - wParamL: WORD - wParamH: WORD - -class _INPUTunion(Union): - mi: MOUSEINPUT - ki: KEYBDINPUT - hi: HARDWAREINPUT - -class INPUT(Structure): - type: DWORD - union: _INPUTunion - -_POINTER_KBDLLHOOKSTRUCT: TypeAlias = Incomplete # POINTER(KBDLLHOOKSTRUCT) -_LRESULT: TypeAlias = Incomplete -_POINTER_INPUT: TypeAlias = Incomplete # POINTER(INPUT) -_LowLevelKeyboardProc: TypeAlias = Callable[[Callable[[c_int, WPARAM, LPARAM], c_int]], _POINTER_KBDLLHOOKSTRUCT] -LowLevelKeyboardProc: _LowLevelKeyboardProc -SetWindowsHookEx: Callable[[c_int, _LowLevelKeyboardProc, c_int, c_int], HHOOK] -CallNextHookEx: Callable[[c_int, c_int, WPARAM, LPARAM], c_int] -UnhookWindowsHookEx: Callable[[HHOOK], BOOL] -GetMessage: Callable[[LPMSG, c_int, c_int, c_int], BOOL] -TranslateMessage: Callable[[LPMSG], BOOL] -DispatchMessage: Callable[[LPMSG], _LRESULT] -_KeyboardStateType: TypeAlias = Array[c_uint8] -keyboard_state_type: _KeyboardStateType -GetKeyboardState: Callable[[_KeyboardStateType], BOOL] -GetKeyNameText: Callable[[c_long, LPWSTR, c_int], c_int] -MapVirtualKey: Callable[[c_uint, c_uint], c_uint] -ToUnicode: Callable[[c_uint, c_uint, _KeyboardStateType, LPWSTR, c_int, c_uint], c_int] -SendInput: Callable[[c_uint, _POINTER_INPUT, c_int], c_uint] -MAPVK_VK_TO_CHAR: Literal[2] -MAPVK_VK_TO_VSC: Literal[0] -MAPVK_VSC_TO_VK: Literal[1] -MAPVK_VK_TO_VSC_EX: Literal[4] -MAPVK_VSC_TO_VK_EX: Literal[3] -VkKeyScan: Callable[[WCHAR], c_short] -LLKHF_INJECTED: Literal[16] - -WM_KEYDOWN: Literal[256] -WM_KEYUP: Literal[257] -WM_SYSKEYDOWN: Literal[260] -WM_SYSKEYUP: Literal[261] -keyboard_event_types: dict[int, str] -official_virtual_keys: dict[ - int, - tuple[Literal["control-break processing"], Literal[False]] - | tuple[Literal["backspace"], Literal[False]] - | tuple[Literal["tab"], Literal[False]] - | tuple[Literal["clear"], Literal[False]] - | tuple[Literal["enter"], Literal[False]] - | tuple[Literal["shift"], Literal[False]] - | tuple[Literal["ctrl"], Literal[False]] - | tuple[Literal["alt"], Literal[False]] - | tuple[Literal["pause"], Literal[False]] - | tuple[Literal["caps lock"], Literal[False]] - | tuple[Literal["ime kana mode"], Literal[False]] - | tuple[Literal["ime hanguel mode"], Literal[False]] - | tuple[Literal["ime hangul mode"], Literal[False]] - | tuple[Literal["ime junja mode"], Literal[False]] - | tuple[Literal["ime final mode"], Literal[False]] - | tuple[Literal["ime hanja mode"], Literal[False]] - | tuple[Literal["ime kanji mode"], Literal[False]] - | tuple[Literal["esc"], Literal[False]] - | tuple[Literal["ime convert"], Literal[False]] - | tuple[Literal["ime nonconvert"], Literal[False]] - | tuple[Literal["ime accept"], Literal[False]] - | tuple[Literal["ime mode change request"], Literal[False]] - | tuple[Literal["spacebar"], Literal[False]] - | tuple[Literal["page up"], Literal[False]] - | tuple[Literal["page down"], Literal[False]] - | tuple[Literal["end"], Literal[False]] - | tuple[Literal["home"], Literal[False]] - | tuple[Literal["left"], Literal[False]] - | tuple[Literal["up"], Literal[False]] - | tuple[Literal["right"], Literal[False]] - | tuple[Literal["down"], Literal[False]] - | tuple[Literal["select"], Literal[False]] - | tuple[Literal["print"], Literal[False]] - | tuple[Literal["execute"], Literal[False]] - | tuple[Literal["print screen"], Literal[False]] - | tuple[Literal["insert"], Literal[False]] - | tuple[Literal["delete"], Literal[False]] - | tuple[Literal["help"], Literal[False]] - | tuple[Literal["0"], Literal[False]] - | tuple[Literal["1"], Literal[False]] - | tuple[Literal["2"], Literal[False]] - | tuple[Literal["3"], Literal[False]] - | tuple[Literal["4"], Literal[False]] - | tuple[Literal["5"], Literal[False]] - | tuple[Literal["6"], Literal[False]] - | tuple[Literal["7"], Literal[False]] - | tuple[Literal["8"], Literal[False]] - | tuple[Literal["9"], Literal[False]] - | tuple[Literal["a"], Literal[False]] - | tuple[Literal["b"], Literal[False]] - | tuple[Literal["c"], Literal[False]] - | tuple[Literal["d"], Literal[False]] - | tuple[Literal["e"], Literal[False]] - | tuple[Literal["f"], Literal[False]] - | tuple[Literal["g"], Literal[False]] - | tuple[Literal["h"], Literal[False]] - | tuple[Literal["i"], Literal[False]] - | tuple[Literal["j"], Literal[False]] - | tuple[Literal["k"], Literal[False]] - | tuple[Literal["l"], Literal[False]] - | tuple[Literal["m"], Literal[False]] - | tuple[Literal["n"], Literal[False]] - | tuple[Literal["o"], Literal[False]] - | tuple[Literal["p"], Literal[False]], -] -tables_lock: Lock -to_name: defaultdict[tuple[int, int, int, str | int | tuple[str, ...]] | tuple[int, int, int, int, int], list[str]] -from_name: defaultdict[str, list[tuple[int, tuple[str | int | tuple[str, ...], ...]]]] -scan_code_to_vk: dict[int, int] -distinct_modifiers: list[ - tuple[()] - | tuple[Literal["shift"]] - | tuple[Literal["alt gr"]] - | tuple[Literal["num lock"]] - | tuple[Literal["shift"], Literal["num lock"]] - | tuple[Literal["caps lock"]] - | tuple[Literal["shift"], Literal["caps lock"]] - | tuple[Literal["alt gr"], Literal["num lock"]] -] -name_buffer: Array[c_wchar] -unicode_buffer: Array[c_wchar] -keyboard_state: _KeyboardStateType - -def get_event_names( - scan_code: int, vk: int, is_extended: Literal[0, 1], modifiers: Sequence[str] -) -> Generator[str, None, None]: ... - -init: Callable[[], None] -keypad_keys: list[ - tuple[Literal[126], Literal[194], Literal[0]] - | tuple[Literal[28], Literal[13], Literal[1]] - | tuple[Literal[53], Literal[111], Literal[1]] - | tuple[Literal[55], Literal[106], Literal[0]] - | tuple[Literal[69], Literal[144], Literal[1]] - | tuple[Literal[71], Literal[103], Literal[0]] - | tuple[Literal[71], Literal[36], Literal[0]] - | tuple[Literal[72], Literal[104], Literal[0]] - | tuple[Literal[72], Literal[38], Literal[0]] - | tuple[Literal[73], Literal[105], Literal[0]] - | tuple[Literal[73], Literal[33], Literal[0]] - | tuple[Literal[74], Literal[109], Literal[0]] - | tuple[Literal[75], Literal[100], Literal[0]] - | tuple[Literal[75], Literal[37], Literal[0]] - | tuple[Literal[76], Literal[101], Literal[0]] - | tuple[Literal[76], Literal[12], Literal[0]] - | tuple[Literal[77], Literal[102], Literal[0]] - | tuple[Literal[77], Literal[39], Literal[0]] - | tuple[Literal[78], Literal[107], Literal[0]] - | tuple[Literal[79], Literal[35], Literal[0]] - | tuple[Literal[79], Literal[97], Literal[0]] - | tuple[Literal[80], Literal[40], Literal[0]] - | tuple[Literal[80], Literal[98], Literal[0]] - | tuple[Literal[81], Literal[34], Literal[0]] - | tuple[Literal[81], Literal[99], Literal[0]] - | tuple[Literal[82], Literal[45], Literal[0]] - | tuple[Literal[82], Literal[96], Literal[0]] - | tuple[Literal[83], Literal[110], Literal[0]] - | tuple[Literal[83], Literal[46], Literal[0]] -] -shift_is_pressed: bool -altgr_is_pressed: bool -ignore_next_right_alt: bool -shift_vks: set[int] - -def prepare_intercept(callback: Callable[[KeyboardEvent], bool]) -> None: ... -def listen(callback: Callable[[KeyboardEvent], bool]) -> None: ... -def map_name(name: str) -> Generator[tuple[int, str | int | tuple[str, ...]], None, None]: ... -def press(code: int) -> None: ... -def release(code: int) -> None: ... -def type_unicode(character: str) -> None: ... diff --git a/stubs/keyboard/keyboard/_winmouse.pyi b/stubs/keyboard/keyboard/_winmouse.pyi deleted file mode 100644 index 2bb19971a216..000000000000 --- a/stubs/keyboard/keyboard/_winmouse.pyi +++ /dev/null @@ -1,132 +0,0 @@ -import sys -from _typeshed import Incomplete -from collections.abc import Callable -from ctypes import ( - Structure, - c_char as c_char, - c_int, - c_int32, - c_long, - c_short as c_short, - c_uint as c_uint, - c_uint8 as c_uint8, - c_uint32 as c_uint32, -) -from ctypes.wintypes import BOOL, DWORD, HHOOK, LPARAM, LPMSG as LPMSG, LPWSTR as LPWSTR, WCHAR as WCHAR, WPARAM -from queue import Queue -from typing_extensions import Literal, TypeAlias - -from ._mouse_event import ( - DOUBLE as DOUBLE, - DOWN as DOWN, - HORIZONTAL as HORIZONTAL, - LEFT as LEFT, - MIDDLE as MIDDLE, - RIGHT as RIGHT, - UP as UP, - VERTICAL as VERTICAL, - WHEEL as WHEEL, - X2 as X2, - ButtonEvent as ButtonEvent, - MoveEvent as MoveEvent, - WheelEvent as WheelEvent, - X as X, - _MouseButton, -) - -if sys.platform == "win32": - from ctypes import WinDLL - - user32: WinDLL - -class MSLLHOOKSTRUCT(Structure): - x: c_long - y: c_long - data: c_int32 - reserved: c_int32 - flags: DWORD - time: c_int - -_POINTER_MSLLHOOKSTRUCT: TypeAlias = Incomplete # POINTER(MSLLHOOKSTRUCT) -_LRESULT: TypeAlias = Incomplete -LowLevelMouseProc: TypeAlias = Callable[[Callable[[c_int, WPARAM, LPARAM], c_int]], _POINTER_MSLLHOOKSTRUCT] -SetWindowsHookEx: Callable[[c_int, LowLevelMouseProc, c_int, c_int], HHOOK] -CallNextHookEx: Callable[[c_int, c_int, WPARAM, LPARAM], c_int] -UnhookWindowsHookEx: Callable[[HHOOK], BOOL] -GetMessage: Callable[[LPMSG, c_int, c_int, c_int], BOOL] -TranslateMessage: Callable[[LPMSG], BOOL] -DispatchMessage: Callable[[LPMSG], _LRESULT] -WM_MOUSEMOVE: Literal[512] -WM_LBUTTONDOWN: Literal[513] -WM_LBUTTONUP: Literal[514] -WM_LBUTTONDBLCLK: Literal[515] -WM_RBUTTONDOWN: Literal[516] -WM_RBUTTONUP: Literal[517] -WM_RBUTTONDBLCLK: Literal[518] -WM_MBUTTONDOWN: Literal[519] -WM_MBUTTONUP: Literal[520] -WM_MBUTTONDBLCLK: Literal[521] -WM_MOUSEWHEEL: Literal[522] -WM_XBUTTONDOWN: Literal[523] -WM_XBUTTONUP: Literal[524] -WM_XBUTTONDBLCLK: Literal[525] -WM_NCXBUTTONDOWN: Literal[171] -WM_NCXBUTTONUP: Literal[172] -WM_NCXBUTTONDBLCLK: Literal[173] -WM_MOUSEHWHEEL: Literal[526] -buttons_by_wm_code: dict[ - int, - tuple[Literal["down"], Literal["left"]] - | tuple[Literal["up"], Literal["left"]] - | tuple[Literal["double"], Literal["left"]] - | tuple[Literal["down"], Literal["right"]] - | tuple[Literal["up"], Literal["right"]] - | tuple[Literal["double"], Literal["right"]] - | tuple[Literal["down"], Literal["middle"]] - | tuple[Literal["up"], Literal["middle"]] - | tuple[Literal["double"], Literal["middle"]] - | tuple[Literal["down"], Literal["x"]] - | tuple[Literal["up"], Literal["x"]] - | tuple[Literal["double"], Literal["x"]], -] -MOUSEEVENTF_ABSOLUTE: Literal[32768] -MOUSEEVENTF_MOVE: Literal[1] -MOUSEEVENTF_WHEEL: Literal[2048] -MOUSEEVENTF_HWHEEL: Literal[4096] -MOUSEEVENTF_LEFTDOWN: Literal[2] -MOUSEEVENTF_LEFTUP: Literal[4] -MOUSEEVENTF_RIGHTDOWN: Literal[8] -MOUSEEVENTF_RIGHTUP: Literal[16] -MOUSEEVENTF_MIDDLEDOWN: Literal[32] -MOUSEEVENTF_MIDDLEUP: Literal[64] -MOUSEEVENTF_XDOWN: Literal[128] -MOUSEEVENTF_XUP: Literal[256] -simulated_mouse_codes: dict[ - tuple[Literal["wheel"], Literal["horizontal"]] - | tuple[Literal["wheel"], Literal["vertical"]] - | tuple[Literal["down"], Literal["left"]] - | tuple[Literal["up"], Literal["left"]] - | tuple[Literal["down"], Literal["right"]] - | tuple[Literal["up"], Literal["right"]] - | tuple[Literal["down"], Literal["middle"]] - | tuple[Literal["up"], Literal["middle"]] - | tuple[Literal["down"], Literal["x"]] - | tuple[Literal["up"], Literal["x"]], - int, -] -NULL: c_long -WHEEL_DELTA: Literal[120] -init: Callable[[], None] - -def listen(queue: Queue[MoveEvent | WheelEvent | ButtonEvent]): ... -def press(button: _MouseButton = ...) -> None: ... -def release(button: _MouseButton = ...) -> None: ... -def wheel(delta: int = ...) -> None: ... -def move_to(x: int | c_long, y: int | c_long) -> None: ... -def move_relative(x: int | c_long, y: int | c_long) -> None: ... - -class POINT(Structure): - x: c_long - y: c_long - -def get_position() -> tuple[c_long, c_long]: ... diff --git a/stubs/keyboard/keyboard/mouse.pyi b/stubs/keyboard/keyboard/mouse.pyi index 7dc3f930acb9..890c9ee0f82c 100644 --- a/stubs/keyboard/keyboard/mouse.pyi +++ b/stubs/keyboard/keyboard/mouse.pyi @@ -18,17 +18,18 @@ from ._mouse_event import ( X as X, _MouseButton, _MouseEvent, + _MouseEventType, ) # Can't use ParamSpecArgs on `args`, only on `*args` # _P = ParamSpec("_P") _P: TypeAlias = tuple[object, ...] -_Callback: TypeAlias = Callable[[ButtonEvent | WheelEvent | MoveEvent], bool | None] +_Callback: TypeAlias = Callable[[_MouseEvent], bool | None] class _MouseListener(_GenericListener): def init(self) -> None: ... def pre_process_event( # type: ignore[override] # Mouse specific events and return - self, event: ButtonEvent | MoveEvent | WheelEvent + self, event: _MouseEvent ) -> Literal[True]: ... def listen(self) -> None: ... @@ -45,13 +46,13 @@ def on_button( callback: Callable[..., None], args: _P = ..., buttons: list[_MouseButton] | tuple[_MouseButton, ...] | _MouseButton = ..., - types: list[_MouseEvent] | tuple[_MouseEvent, ...] | _MouseEvent = ..., + types: list[_MouseEventType] | tuple[_MouseEventType, ...] | _MouseEventType = ..., ) -> _Callback: ... def on_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... def on_double_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... def on_right_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... def on_middle_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... -def wait(button: _MouseButton = ..., target_types: tuple[_MouseEvent] = ...) -> None: ... +def wait(button: _MouseButton = ..., target_types: tuple[_MouseEventType] = ...) -> None: ... if sys.platform == "win32": def get_position() -> tuple[c_long, c_long]: ... @@ -62,9 +63,9 @@ else: def hook(callback: _Callback) -> _Callback: ... def unhook(callback: _Callback) -> None: ... def unhook_all() -> None: ... -def record(button: _MouseButton = ..., target_types: tuple[_MouseEvent] = ...) -> ButtonEvent | WheelEvent | MoveEvent: ... +def record(button: _MouseButton = ..., target_types: tuple[_MouseEventType] = ...) -> _MouseEvent: ... def play( - events: Sequence[ButtonEvent | WheelEvent | MoveEvent], + events: Sequence[_MouseEvent], speed_factor: float = ..., include_clicks: bool = ..., include_moves: bool = ..., From 76010437bc205771c61a9a75288fbba60388b5e7 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 17:41:50 -0400 Subject: [PATCH 14/17] Some Sequence to Iterable --- stubs/keyboard/keyboard/__init__.pyi | 12 ++++++------ stubs/keyboard/keyboard/mouse.pyi | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/stubs/keyboard/keyboard/__init__.pyi b/stubs/keyboard/keyboard/__init__.pyi index dd9104b59308..988cd856f17c 100644 --- a/stubs/keyboard/keyboard/__init__.pyi +++ b/stubs/keyboard/keyboard/__init__.pyi @@ -1,5 +1,5 @@ from collections import Counter, defaultdict, deque -from collections.abc import Callable, Generator, Sequence +from collections.abc import Callable, Generator, Iterable, Sequence from queue import Queue from threading import Event as _UninterruptibleEvent from typing import Optional @@ -138,21 +138,21 @@ def remap_hotkey( unremap_hotkey = remove_hotkey def stash_state() -> list[int]: ... -def restore_state(scan_codes: Sequence[int]) -> None: ... -def restore_modifiers(scan_codes: Sequence[int]) -> None: ... +def restore_state(scan_codes: Iterable[int]) -> None: ... +def restore_modifiers(scan_codes: Iterable[int]) -> None: ... def write(text: str, delay: float = ..., restore_state_after: bool = ..., exact: bool | None = ...) -> None: ... def wait(hotkey: _ParseableHotkey | None = ..., suppress: bool = ..., trigger_on_release: bool = ...) -> None: ... -def get_hotkey_name(names: Sequence[str] | None = ...) -> str: ... +def get_hotkey_name(names: Iterable[str] | None = ...) -> str: ... def read_event(suppress: bool = ...) -> KeyboardEvent: ... def read_key(suppress: bool = ...) -> _Key: ... def read_hotkey(suppress: bool = ...) -> str: ... -def get_typed_strings(events: Sequence[KeyboardEvent], allow_backspace: bool = ...) -> Generator[str, None, None]: ... +def get_typed_strings(events: Iterable[KeyboardEvent], allow_backspace: bool = ...) -> Generator[str, None, None]: ... def start_recording( recorded_events_queue: Queue[KeyboardEvent] | None = ..., ) -> tuple[Queue[KeyboardEvent], Callable[[], None]]: ... def stop_recording() -> list[deque[KeyboardEvent]]: ... def record(until: str = ..., suppress: bool = ..., trigger_on_release: bool = ...) -> list[deque[KeyboardEvent]]: ... -def play(events: Sequence[KeyboardEvent], speed_factor: float = ...) -> None: ... +def play(events: Iterable[KeyboardEvent], speed_factor: float = ...) -> None: ... replay = play diff --git a/stubs/keyboard/keyboard/mouse.pyi b/stubs/keyboard/keyboard/mouse.pyi index 890c9ee0f82c..c5a5c794e799 100644 --- a/stubs/keyboard/keyboard/mouse.pyi +++ b/stubs/keyboard/keyboard/mouse.pyi @@ -1,5 +1,5 @@ import sys -from collections.abc import Callable, Sequence +from collections.abc import Callable, Iterable from ctypes import c_long from typing_extensions import Literal, TypeAlias @@ -65,7 +65,7 @@ def unhook(callback: _Callback) -> None: ... def unhook_all() -> None: ... def record(button: _MouseButton = ..., target_types: tuple[_MouseEventType] = ...) -> _MouseEvent: ... def play( - events: Sequence[_MouseEvent], + events: Iterable[_MouseEvent], speed_factor: float = ..., include_clicks: bool = ..., include_moves: bool = ..., From 4f544558c9b086ec9427c237d5a216111b93d083 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 17:44:36 -0400 Subject: [PATCH 15/17] flake8 fix --- stubs/keyboard/keyboard/_mouse_event.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stubs/keyboard/keyboard/_mouse_event.pyi b/stubs/keyboard/keyboard/_mouse_event.pyi index 49dbc97dadf7..479fe4c9dbd8 100644 --- a/stubs/keyboard/keyboard/_mouse_event.pyi +++ b/stubs/keyboard/keyboard/_mouse_event.pyi @@ -2,7 +2,7 @@ import sys from typing import NamedTuple from typing_extensions import Literal, TypeAlias -_MouseEvent: TypeAlias = ButtonEvent | WheelEvent | MoveEvent +_MouseEvent: TypeAlias = ButtonEvent | WheelEvent | MoveEvent # noqa: Y047 # Used outside LEFT: Literal["left"] RIGHT: Literal["right"] From 1f11b30071e27b4ef557b5fbf8625b2c11db6f87 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 2 Sep 2022 18:05:14 -0400 Subject: [PATCH 16/17] Updated stubtest_allowlist --- stubs/keyboard/@tests/stubtest_allowlist.txt | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/stubs/keyboard/@tests/stubtest_allowlist.txt b/stubs/keyboard/@tests/stubtest_allowlist.txt index 5770d30e723e..8ecec31a6b87 100644 --- a/stubs/keyboard/@tests/stubtest_allowlist.txt +++ b/stubs/keyboard/@tests/stubtest_allowlist.txt @@ -1,17 +1,17 @@ -# Tests and __main__ -keyboard.__main__ -keyboard._keyboard_tests -keyboard._mouse_tests -# MacOs: ModuleNotFoundError: No module named 'Quartz' -keyboard._darwinkeyboard -keyboard._darwinmouse -# Windows: AttributeError: module 'ctypes' has no attribute 'WinDLL' -keyboard._winkeyboard -keyboard._winmouse # scan_code *should* never be None in real use. This is also according to docs. keyboard.KeyboardEvent.scan_code keyboard._keyboard_event.KeyboardEvent.scan_code -keyboard._nixkeyboard.KeyboardEvent.scan_code # Defaults don't align with possible values keyboard.mouse.on_button keyboard.mouse.wait +# Private modules and tests +keyboard.__main__ +keyboard._darwinkeyboard +keyboard._darwinmouse +keyboard._keyboard_tests +keyboard._mouse_tests +keyboard._nixcommon +keyboard._nixkeyboard +keyboard._nixmouse +keyboard._winkeyboard +keyboard._winmouse From 9796cb1bc2f60871b804ce0322ab58369ab21c62 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sun, 4 Sep 2022 19:51:24 -0400 Subject: [PATCH 17/17] Resolve PR comments --- stubs/keyboard/keyboard/__init__.pyi | 70 +++----------------- stubs/keyboard/keyboard/_canonical_names.pyi | 1 - stubs/keyboard/keyboard/_generic.pyi | 3 +- stubs/keyboard/keyboard/_keyboard_event.pyi | 1 - stubs/keyboard/keyboard/mouse.pyi | 22 +++--- 5 files changed, 22 insertions(+), 75 deletions(-) diff --git a/stubs/keyboard/keyboard/__init__.pyi b/stubs/keyboard/keyboard/__init__.pyi index 988cd856f17c..3235e0ac5453 100644 --- a/stubs/keyboard/keyboard/__init__.pyi +++ b/stubs/keyboard/keyboard/__init__.pyi @@ -1,9 +1,8 @@ -from collections import Counter, defaultdict, deque from collections.abc import Callable, Generator, Iterable, Sequence from queue import Queue from threading import Event as _UninterruptibleEvent from typing import Optional -from typing_extensions import Literal, TypeAlias +from typing_extensions import TypeAlias from ._canonical_names import all_modifiers as all_modifiers, sided_modifiers as sided_modifiers from ._generic import GenericListener as _GenericListener @@ -13,9 +12,9 @@ _Key: TypeAlias = int | str _ScanCodeList: TypeAlias = list[int] | tuple[int, ...] _ParseableHotkey: TypeAlias = _Key | list[int | _ScanCodeList] | tuple[int | _ScanCodeList, ...] _Callback: TypeAlias = Callable[[KeyboardEvent], Optional[bool]] | Callable[[], Optional[bool]] -# Can't use ParamSpecArgs on `args`, only on `*args` -# _P = ParamSpec("_P") -_P: TypeAlias = tuple[object, ...] +# mypy doesn't support PEP 646's TypeVarTuple yet: https://github.com/python/mypy/issues/12280 +# _Ts = TypeVarTuple("_Ts") +_Ts: TypeAlias = tuple[object, ...] version: str @@ -23,59 +22,6 @@ class _Event(_UninterruptibleEvent): def wait(self) -> None: ... # type: ignore[override] # Actual implementation def is_modifier(key: _Key | None) -> bool: ... - -class _KeyboardListener(_GenericListener): - transition_table: dict[ - tuple[Literal["free"], Literal["up"], Literal["modifier"]] - | tuple[Literal["free"], Literal["down"], Literal["modifier"]] - | tuple[Literal["pending"], Literal["up"], Literal["modifier"]] - | tuple[Literal["pending"], Literal["down"], Literal["modifier"]] - | tuple[Literal["suppressed"], Literal["up"], Literal["modifier"]] - | tuple[Literal["suppressed"], Literal["down"], Literal["modifier"]] - | tuple[Literal["allowed"], Literal["up"], Literal["modifier"]] - | tuple[Literal["allowed"], Literal["down"], Literal["modifier"]] - | tuple[Literal["free"], Literal["up"], Literal["hotkey"]] - | tuple[Literal["free"], Literal["down"], Literal["hotkey"]] - | tuple[Literal["pending"], Literal["up"], Literal["hotkey"]] - | tuple[Literal["pending"], Literal["down"], Literal["hotkey"]] - | tuple[Literal["suppressed"], Literal["up"], Literal["hotkey"]] - | tuple[Literal["suppressed"], Literal["down"], Literal["hotkey"]] - | tuple[Literal["allowed"], Literal["up"], Literal["hotkey"]] - | tuple[Literal["allowed"], Literal["down"], Literal["hotkey"]] - | tuple[Literal["free"], Literal["up"], Literal["other"]] - | tuple[Literal["free"], Literal["down"], Literal["other"]] - | tuple[Literal["pending"], Literal["up"], Literal["other"]] - | tuple[Literal["pending"], Literal["down"], Literal["other"]] - | tuple[Literal["suppressed"], Literal["up"], Literal["other"]] - | tuple[Literal["suppressed"], Literal["down"], Literal["other"]] - | tuple[Literal["allowed"], Literal["up"], Literal["other"]] - | tuple[Literal["allowed"], Literal["down"], Literal["other"]], - tuple[Literal[False], Literal[True], Literal["free"]] - | tuple[Literal[False], Literal[False], Literal["pending"]] - | tuple[Literal[True], Literal[True], Literal["free"]] - | tuple[Literal[False], Literal[True], Literal["allowed"]] - | tuple[Literal[False], Literal[False], Literal["free"]] - | tuple[Literal[False], Literal[False], Literal["suppressed"]] - | tuple[Literal[False], None, Literal["free"]] - | tuple[Literal[False], None, Literal["suppressed"]] - | tuple[Literal[False], None, Literal["allowed"]] - | tuple[Literal[True], Literal[True], Literal["allowed"]] - | tuple[Literal[False], Literal[False], Literal["allowed"]], - ] - active_modifiers: set[int] - blocking_hooks: list[_Callback] - blocking_keys: defaultdict[int, list[_Callback]] - nonblocking_keys: defaultdict[int, list[_Callback]] - blocking_hotkeys: defaultdict[tuple[int, ...], list[_Callback]] - nonblocking_hotkeys: defaultdict[tuple[int, ...], list[_Callback]] - filtered_modifiers: Counter[int] - is_replaying: bool - modifier_states: dict[_Key, str] - def init(self) -> None: ... - def pre_process_event(self, event): ... - def direct_callback(self, event): ... - def listen(self) -> None: ... - def key_to_scan_codes(key: _ParseableHotkey, error_if_missing: bool = ...) -> tuple[int, ...]: ... def parse_hotkey(hotkey: _ParseableHotkey) -> tuple[tuple[tuple[int, ...], ...], ...]: ... def send(hotkey: _ParseableHotkey, do_press: bool = ..., do_release: bool = ...) -> None: ... @@ -88,7 +34,7 @@ def release(hotkey: _ParseableHotkey) -> None: ... # is_pressed cannot check multi-step hotkeys, so not using _ParseableHotkey def is_pressed(hotkey: _Key | _ScanCodeList) -> bool: ... -def call_later(fn: Callable[..., None], args: _P = ..., delay: float = ...) -> None: ... +def call_later(fn: Callable[..., None], args: _Ts = ..., delay: float = ...) -> None: ... def hook(callback: _Callback, suppress: bool = ..., on_remove: Callable[[], None] = ...) -> Callable[[], None]: ... def on_press(callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... def on_release(callback: _Callback, suppress: bool = ...) -> Callable[[], None]: ... @@ -112,7 +58,7 @@ def parse_hotkey_combinations(hotkey: _ParseableHotkey) -> tuple[tuple[tuple[int def add_hotkey( hotkey: _ParseableHotkey, callback: Callable[..., bool | None], - args: _P = ..., + args: _Ts = ..., suppress: bool = ..., timeout: float = ..., trigger_on_release: bool = ..., @@ -150,8 +96,8 @@ def get_typed_strings(events: Iterable[KeyboardEvent], allow_backspace: bool = . def start_recording( recorded_events_queue: Queue[KeyboardEvent] | None = ..., ) -> tuple[Queue[KeyboardEvent], Callable[[], None]]: ... -def stop_recording() -> list[deque[KeyboardEvent]]: ... -def record(until: str = ..., suppress: bool = ..., trigger_on_release: bool = ...) -> list[deque[KeyboardEvent]]: ... +def stop_recording() -> list[KeyboardEvent]: ... +def record(until: str = ..., suppress: bool = ..., trigger_on_release: bool = ...) -> list[KeyboardEvent]: ... def play(events: Iterable[KeyboardEvent], speed_factor: float = ...) -> None: ... replay = play diff --git a/stubs/keyboard/keyboard/_canonical_names.pyi b/stubs/keyboard/keyboard/_canonical_names.pyi index 1bfd90779708..8a0c3a007643 100644 --- a/stubs/keyboard/keyboard/_canonical_names.pyi +++ b/stubs/keyboard/keyboard/_canonical_names.pyi @@ -1,4 +1,3 @@ -basestring = str canonical_names: dict[str, str] sided_modifiers: set[str] all_modifiers: set[str] diff --git a/stubs/keyboard/keyboard/_generic.pyi b/stubs/keyboard/keyboard/_generic.pyi index 49c88a43f351..21f74b9e1830 100644 --- a/stubs/keyboard/keyboard/_generic.pyi +++ b/stubs/keyboard/keyboard/_generic.pyi @@ -1,6 +1,7 @@ from collections.abc import Callable from queue import Queue from threading import Lock, Thread +from typing import ClassVar from typing_extensions import Literal, TypeAlias from ._keyboard_event import KeyboardEvent @@ -9,7 +10,7 @@ from ._mouse_event import _MouseEvent _Event: TypeAlias = KeyboardEvent | _MouseEvent class GenericListener: - lock: Lock + lock: ClassVar[Lock] handlers: list[Callable[[_Event], bool | None]] listening: bool queue: Queue[_Event] diff --git a/stubs/keyboard/keyboard/_keyboard_event.pyi b/stubs/keyboard/keyboard/_keyboard_event.pyi index aecb95a5dce2..9c511fdccf59 100644 --- a/stubs/keyboard/keyboard/_keyboard_event.pyi +++ b/stubs/keyboard/keyboard/_keyboard_event.pyi @@ -2,7 +2,6 @@ from typing_extensions import Literal from ._canonical_names import canonical_names as canonical_names, normalize_name as normalize_name -basestring = str KEY_DOWN: Literal["down"] KEY_UP: Literal["up"] diff --git a/stubs/keyboard/keyboard/mouse.pyi b/stubs/keyboard/keyboard/mouse.pyi index c5a5c794e799..6285b0b0541d 100644 --- a/stubs/keyboard/keyboard/mouse.pyi +++ b/stubs/keyboard/keyboard/mouse.pyi @@ -1,6 +1,7 @@ import sys from collections.abc import Callable, Iterable from ctypes import c_long +from typing import SupportsInt, TypeVar from typing_extensions import Literal, TypeAlias from ._generic import GenericListener as _GenericListener @@ -21,10 +22,11 @@ from ._mouse_event import ( _MouseEventType, ) -# Can't use ParamSpecArgs on `args`, only on `*args` -# _P = ParamSpec("_P") -_P: TypeAlias = tuple[object, ...] +# mypy doesn't support PEP 646's TypeVarTuple yet: https://github.com/python/mypy/issues/12280 +# _Ts = TypeVarTuple("_Ts") +_Ts: TypeAlias = tuple[object, ...] _Callback: TypeAlias = Callable[[_MouseEvent], bool | None] +_C = TypeVar("_C", bound=_Callback) class _MouseListener(_GenericListener): def init(self) -> None: ... @@ -40,18 +42,18 @@ def click(button: _MouseButton = ...) -> None: ... def double_click(button: _MouseButton = ...) -> None: ... def right_click() -> None: ... def wheel(delta: int = ...) -> None: ... -def move(x: int | c_long, y: int | c_long, absolute: bool = ..., duration: float = ...) -> None: ... +def move(x: SupportsInt, y: SupportsInt, absolute: bool = ..., duration: float = ...) -> None: ... def drag(start_x: int, start_y: int, end_x: int, end_y: int, absolute: bool = ..., duration: float = ...) -> None: ... def on_button( callback: Callable[..., None], - args: _P = ..., + args: _Ts = ..., buttons: list[_MouseButton] | tuple[_MouseButton, ...] | _MouseButton = ..., types: list[_MouseEventType] | tuple[_MouseEventType, ...] | _MouseEventType = ..., ) -> _Callback: ... -def on_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... -def on_double_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... -def on_right_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... -def on_middle_click(callback: Callable[..., None], args: _P = ...) -> _Callback: ... +def on_click(callback: Callable[..., None], args: _Ts = ...) -> _Callback: ... +def on_double_click(callback: Callable[..., None], args: _Ts = ...) -> _Callback: ... +def on_right_click(callback: Callable[..., None], args: _Ts = ...) -> _Callback: ... +def on_middle_click(callback: Callable[..., None], args: _Ts = ...) -> _Callback: ... def wait(button: _MouseButton = ..., target_types: tuple[_MouseEventType] = ...) -> None: ... if sys.platform == "win32": @@ -60,7 +62,7 @@ if sys.platform == "win32": else: def get_position() -> tuple[int, int]: ... -def hook(callback: _Callback) -> _Callback: ... +def hook(callback: _C) -> _C: ... def unhook(callback: _Callback) -> None: ... def unhook_all() -> None: ... def record(button: _MouseButton = ..., target_types: tuple[_MouseEventType] = ...) -> _MouseEvent: ...