Added stubs for keyboard (#8666)

This commit is contained in:
Samuel T
2022-09-05 17:34:11 -04:00
committed by GitHub
parent b6d28acb23
commit 939fc86e79
9 changed files with 315 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
# 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
# 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

View File

@@ -0,0 +1,4 @@
version = "0.13.*"
[tool.stubtest]
ignore_missing_stub = false

View File

@@ -0,0 +1,115 @@
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 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[int | _ScanCodeList] | tuple[int | _ScanCodeList, ...]
_Callback: TypeAlias = Callable[[KeyboardEvent], Optional[bool]] | Callable[[], Optional[bool]]
# 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
class _Event(_UninterruptibleEvent):
def wait(self) -> None: ... # type: ignore[override] # Actual implementation
def is_modifier(key: _Key | None) -> bool: ...
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: ...
press_and_release = send
def press(hotkey: _ParseableHotkey) -> None: ...
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: _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]: ...
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: _ParseableHotkey) -> Callable[[], None]: ...
unblock_key = unhook_key
def remap_key(src: _ParseableHotkey, dst: _ParseableHotkey) -> Callable[[], None]: ...
unremap_key = unhook_key
def parse_hotkey_combinations(hotkey: _ParseableHotkey) -> tuple[tuple[tuple[int, ...], ...], ...]: ...
def add_hotkey(
hotkey: _ParseableHotkey,
callback: Callable[..., bool | None],
args: _Ts = ...,
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: 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: 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: 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[KeyboardEvent]: ...
def record(until: str = ..., suppress: bool = ..., trigger_on_release: bool = ...) -> list[KeyboardEvent]: ...
def play(events: Iterable[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

View File

@@ -0,0 +1,5 @@
canonical_names: dict[str, str]
sided_modifiers: set[str]
all_modifiers: set[str]
def normalize_name(name: str) -> str: ...

View File

@@ -0,0 +1,24 @@
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
from ._mouse_event import _MouseEvent
_Event: TypeAlias = KeyboardEvent | _MouseEvent
class GenericListener:
lock: ClassVar[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: ...

View File

@@ -0,0 +1,28 @@
from typing_extensions import Literal
from ._canonical_names import canonical_names as canonical_names, normalize_name as normalize_name
KEY_DOWN: Literal["down"]
KEY_UP: Literal["up"]
class KeyboardEvent:
event_type: Literal["down", "up"] | None
scan_code: int
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,
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: ...

View File

@@ -0,0 +1,43 @@
import sys
from typing import NamedTuple
from typing_extensions import Literal, TypeAlias
_MouseEvent: TypeAlias = ButtonEvent | WheelEvent | MoveEvent # noqa: Y047 # Used outside
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":
_MouseEventType: TypeAlias = Literal["up", "down", "double", "wheel"]
else:
_MouseEventType: TypeAlias = Literal["up", "down"]
class ButtonEvent(NamedTuple):
event_type: _MouseEventType
button: _MouseButton
time: float
class WheelEvent(NamedTuple):
delta: int
time: float
class MoveEvent(NamedTuple):
x: int
y: int
time: float

View File

@@ -0,0 +1,78 @@
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
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,
_MouseEventType,
)
# 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: ...
def pre_process_event( # type: ignore[override] # Mouse specific events and return
self, event: _MouseEvent
) -> 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: 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: _Ts = ...,
buttons: list[_MouseButton] | tuple[_MouseButton, ...] | _MouseButton = ...,
types: list[_MouseEventType] | tuple[_MouseEventType, ...] | _MouseEventType = ...,
) -> _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":
def get_position() -> tuple[c_long, c_long]: ...
else:
def get_position() -> tuple[int, int]: ...
def hook(callback: _C) -> _C: ...
def unhook(callback: _Callback) -> None: ...
def unhook_all() -> None: ...
def record(button: _MouseButton = ..., target_types: tuple[_MouseEventType] = ...) -> _MouseEvent: ...
def play(
events: Iterable[_MouseEvent],
speed_factor: float = ...,
include_clicks: bool = ...,
include_moves: bool = ...,
include_wheel: bool = ...,
) -> None: ...
replay = play
hold = press