Reformat type hints to use comment style syntax

Update Pipfile to add typing module and pyright
Update pyproject.toml for pyright and mypy configs
This commit is contained in:
sofubi 2021-08-27 00:33:28 -04:00
parent 9fc431e0a7
commit b202dc77d1
12 changed files with 439 additions and 311 deletions

View File

@ -21,4 +21,6 @@ black = "==21.6b0"
flake8-quotes = "*"
flake8-black = "*"
circuitpython-stubs = "==7.0.0a6.dev195"
pyright = "*"
typing = "*"
mypy = "*"

131
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "e80d827684ac8c56b762a74548440c5b371c5b3ee5fcb5b74e68ae6d9bff0665"
"sha256": "cee0eeba8c8dad66dccffe0935656829132f7ca928569e3aa957f278e6e92da6"
},
"pipfile-spec": 6,
"requires": {},
@ -94,11 +94,11 @@
},
"flake8-comprehensions": {
"hashes": [
"sha256:b07aef3277623db32310aa241a1cec67212b53c1d18e767d7e26d4d83aa05bf7",
"sha256:f24be9032587127f7a5bc6d066bf755b6e66834f694383adb8a673e229c1f559"
"sha256:4888de89248b7f7535159189ff693c77f8354f6d37a02619fa28c9921a913aa0",
"sha256:e9a010b99aa90c05790d45281ad9953df44a4a08a1a8f6cd41f98b4fc6a268a0"
],
"index": "pypi",
"version": "==3.5.0"
"version": "==3.6.1"
},
"flake8-isort": {
"hashes": [
@ -110,10 +110,10 @@
},
"flake8-quotes": {
"hashes": [
"sha256:3f1116e985ef437c130431ac92f9b3155f8f652fda7405ac22ffdfd7a9d1055e"
"sha256:f1dd87830ed77ff2ce47fc0ee0fd87ae20e8f045355354ffbf4dcaa18d528217"
],
"index": "pypi",
"version": "==3.2.0"
"version": "==3.3.0"
},
"greenlet": {
"hashes": [
@ -300,6 +300,13 @@
"index": "pypi",
"version": "==0.3.1"
},
"nodeenv": {
"hashes": [
"sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b",
"sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"
],
"version": "==1.6.0"
},
"parso": {
"hashes": [
"sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398",
@ -332,11 +339,11 @@
},
"prompt-toolkit": {
"hashes": [
"sha256:08360ee3a3148bdb5163621709ee322ec34fc4375099afa4bbf751e9b7b7fa4f",
"sha256:7089d8d2938043508aa9420ec18ce0922885304cddae87fb96eebca942299f88"
"sha256:6076e46efae19b1e0ca1ec003ed37a933dc94b4d20f486235d436e64771dcd5c",
"sha256:eb71d5a6b72ce6db177af4a7d4d7085b99756bf656d98ffcc4fecd36850eea6c"
],
"markers": "python_full_version >= '3.6.1'",
"version": "==3.0.19"
"markers": "python_full_version >= '3.6.2'",
"version": "==3.0.20"
},
"ptyprocess": {
"hashes": [
@ -363,11 +370,11 @@
},
"pygments": {
"hashes": [
"sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f",
"sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e"
"sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380",
"sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"
],
"markers": "python_version >= '3.5'",
"version": "==2.9.0"
"version": "==2.10.0"
},
"pynvim": {
"hashes": [
@ -375,6 +382,14 @@
],
"version": "==0.4.3"
},
"pyright": {
"hashes": [
"sha256:dd8e18c54321340be44a708b6037c0b967486c32b3f492741fffdc205cb82f15",
"sha256:e2668730cddf580e696d4a11946e740e2f5647df1eb45f7c55b7029376eac5a1"
],
"index": "pypi",
"version": "==0.0.9"
},
"pyserial": {
"hashes": [
"sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb",
@ -408,41 +423,49 @@
},
"regex": {
"hashes": [
"sha256:026beb631097a4a3def7299aa5825e05e057de3c6d72b139c37813bfa351274b",
"sha256:14caacd1853e40103f59571f169704367e79fb78fac3d6d09ac84d9197cadd16",
"sha256:16d9eaa8c7e91537516c20da37db975f09ac2e7772a0694b245076c6d68f85da",
"sha256:18fdc51458abc0a974822333bd3a932d4e06ba2a3243e9a1da305668bd62ec6d",
"sha256:28e8af338240b6f39713a34e337c3813047896ace09d51593d6907c66c0708ba",
"sha256:3835de96524a7b6869a6c710b26c90e94558c31006e96ca3cf6af6751b27dca1",
"sha256:3905c86cc4ab6d71635d6419a6f8d972cab7c634539bba6053c47354fd04452c",
"sha256:3c09d88a07483231119f5017904db8f60ad67906efac3f1baa31b9b7f7cca281",
"sha256:4551728b767f35f86b8e5ec19a363df87450c7376d7419c3cac5b9ceb4bce576",
"sha256:459bbe342c5b2dec5c5223e7c363f291558bc27982ef39ffd6569e8c082bdc83",
"sha256:4f421e3cdd3a273bace013751c345f4ebeef08f05e8c10757533ada360b51a39",
"sha256:577737ec3d4c195c4aef01b757905779a9e9aee608fa1cf0aec16b5576c893d3",
"sha256:57fece29f7cc55d882fe282d9de52f2f522bb85290555b49394102f3621751ee",
"sha256:7976d410e42be9ae7458c1816a416218364e06e162b82e42f7060737e711d9ce",
"sha256:85f568892422a0e96235eb8ea6c5a41c8ccbf55576a2260c0160800dbd7c4f20",
"sha256:8764a78c5464ac6bde91a8c87dd718c27c1cabb7ed2b4beaf36d3e8e390567f9",
"sha256:8935937dad2c9b369c3d932b0edbc52a62647c2afb2fafc0c280f14a8bf56a6a",
"sha256:8fe58d9f6e3d1abf690174fd75800fda9bdc23d2a287e77758dc0e8567e38ce6",
"sha256:937b20955806381e08e54bd9d71f83276d1f883264808521b70b33d98e4dec5d",
"sha256:9569da9e78f0947b249370cb8fadf1015a193c359e7e442ac9ecc585d937f08d",
"sha256:a3b73390511edd2db2d34ff09aa0b2c08be974c71b4c0505b4a048d5dc128c2b",
"sha256:a4eddbe2a715b2dd3849afbdeacf1cc283160b24e09baf64fa5675f51940419d",
"sha256:a5c6dbe09aff091adfa8c7cfc1a0e83fdb8021ddb2c183512775a14f1435fe16",
"sha256:b63e3571b24a7959017573b6455e05b675050bbbea69408f35f3cb984ec54363",
"sha256:bb350eb1060591d8e89d6bac4713d41006cd4d479f5e11db334a48ff8999512f",
"sha256:bf6d987edd4a44dd2fa2723fca2790f9442ae4de2c8438e53fcb1befdf5d823a",
"sha256:bfa6a679410b394600eafd16336b2ce8de43e9b13f7fb9247d84ef5ad2b45e91",
"sha256:c856ec9b42e5af4fe2d8e75970fcc3a2c15925cbcc6e7a9bcb44583b10b95e80",
"sha256:cea56288eeda8b7511d507bbe7790d89ae7049daa5f51ae31a35ae3c05408531",
"sha256:ea212df6e5d3f60341aef46401d32fcfded85593af1d82b8b4a7a68cd67fdd6b",
"sha256:f35567470ee6dbfb946f069ed5f5615b40edcbb5f1e6e1d3d2b114468d505fc6",
"sha256:fbc20975eee093efa2071de80df7f972b7b35e560b213aafabcec7c0bd00bd8c",
"sha256:ff4a8ad9638b7ca52313d8732f37ecd5fd3c8e3aff10a8ccb93176fd5b3812f6"
"sha256:0696eb934dee723e3292056a2c046ddb1e4dd3887685783a9f4af638e85dee76",
"sha256:105122fa63da98d8456d5026bc6ac5a1399fd82fa6bad22c6ea641b1572c9142",
"sha256:116c277774f84266044e889501fe79cfd293a8b4336b7a5e89b9f20f1e5a9f21",
"sha256:12eaf0bbe568bd62e6cade7937e0bf01a2a4cef49a82f4fd204401e78409e158",
"sha256:1401cfa4320691cbd91191ec678735c727dee674d0997b0902a5a38ad482faf5",
"sha256:19acdb8831a4e3b03b23369db43178d8fee1f17b99c83af6cd907886f76bd9d4",
"sha256:208851a2f8dd31e468f0b5aa6c94433975bd67a107a4e7da3bdda947c9f85e25",
"sha256:24d68499a27b2d93831fde4a9b84ea5b19e0ab141425fbc9ab1e5b4dad179df7",
"sha256:2778c6cb379d804e429cc8e627392909e60db5152b42c695c37ae5757aae50ae",
"sha256:2a0a5e323cf86760784ce2b91d8ab5ea09d0865d6ef4da0151e03d15d097b24e",
"sha256:2d9cbe0c755ab8b6f583169c0783f7278fc6b195e423b09c5a8da6f858025e96",
"sha256:2de1429e4eeab799c168a4f6e6eecdf30fcaa389bba4039cc8a065d6b7aad647",
"sha256:32753eda8d413ce4f208cfe01dd61171a78068a6f5d5f38ccd751e00585cdf1d",
"sha256:3ee8ad16a35c45a5bab098e39020ecb6fec3b0e700a9d88983d35cbabcee79c8",
"sha256:4f03fc0a25122cdcbf39136510d4ea7627f732206892db522adf510bc03b8c67",
"sha256:4f3e36086d6631ceaf468503f96a3be0d247caef0660c9452fb1b0c055783851",
"sha256:503c1ba0920a46a1844363725215ef44d59fcac2bd2c03ae3c59aa9d08d29bd6",
"sha256:507861cf3d97a86fbe26ea6cc04660ae028b9e4080b8290e28b99547b4e15d89",
"sha256:56ae6e3cf0506ec0c40b466e31f41ee7a7149a2b505ae0ee50edd9043b423d27",
"sha256:6530b7b9505123cdea40a2301225183ca65f389bc6129f0c225b9b41680268d8",
"sha256:6729914dd73483cd1c8aaace3ac082436fc98b0072743ac136eaea0b3811d42f",
"sha256:7406dd2e44c7cfb4680c0a45a03264381802c67890cf506c147288f04c67177d",
"sha256:7684016b73938ca12d160d2907d141f06b7597bd17d854e32bb7588be01afa1d",
"sha256:7db58ad61f3f6ea393aaf124d774ee0c58806320bc85c06dc9480f5c7219c250",
"sha256:83946ca9278b304728b637bc8d8200ab1663a79de85e47724594917aeed0e892",
"sha256:84057cfae5676f456b03970eb78b7e182fddc80c2daafd83465a3d6ca9ff8dbf",
"sha256:862b6164e9a38b5c495be2c2854e75fd8af12c5be4c61dc9b42d255980d7e907",
"sha256:8ddb4f9ce6bb388ecc97b4b3eb37e786f05d7d5815e8822e0d87a3dbd7100649",
"sha256:92eb03f47427fea452ff6956d11f5d5a3f22a048c90a0f34fa223e6badab6c85",
"sha256:a5f3bc727fea58f21d99c22e6d4fca652dc11dbc2a1e7cfc4838cd53b2e3691f",
"sha256:a6180dbf5945b27e9420e1b58c3cacfc79ad5278bdad3ea35109f5680fbe16d1",
"sha256:b158f673ae6a6523f13704f70aa7e4ce875f91e379bece4362c89db18db189d5",
"sha256:cd45b4542134de63e7b9dd653e0a2d7d47ffed9615e3637c27ca5f6b78ea68bb",
"sha256:d2404336fd16788ea757d4218a2580de60adb052d9888031e765320be8884309",
"sha256:db888d4fb33a2fd54b57ac55d5015e51fa849f0d8592bd799b4e47f83bd04e00",
"sha256:dde0ac721c7c5bfa5f9fc285e811274dec3c392f2c1225f7d07ca98a8187ca84",
"sha256:de0d06ccbc06af5bf93bddec10f4f80275c5d74ea6d28b456931f3955f58bc8c",
"sha256:e02dad60e3e8442eefd28095e99b2ac98f2b8667167493ac6a2f3aadb5d84a17",
"sha256:e960fe211496333b2f7e36badf4c22a919d740386681f79139ee346b403d1ca1",
"sha256:e9700c52749cb3e90c98efd72b730c97b7e4962992fca5fbcaf1363be8e3b849",
"sha256:ee318974a1fdacba1701bc9e552e9015788d6345416364af6fa987424ff8df53"
],
"version": "==2021.8.3"
"version": "==2021.8.27"
},
"s3cmd": {
"hashes": [
@ -462,10 +485,10 @@
},
"testfixtures": {
"hashes": [
"sha256:9bddf79b2dddb36420a20c25a65c827a8e7398c6ed4e2c75c2697857cb006be9",
"sha256:d4bd1c4f90eac90a73e1bdc59c31d03943f218d687f3c5a09e48478841a8af5f"
"sha256:0a6422737f6d89b45cdef1e2df5576f52ad0f507956002ce1020daa9f44211d6",
"sha256:486be7b01eb71326029811878a3317b7e7994324621c0ec633c8e24499d8d5b3"
],
"version": "==6.18.0"
"version": "==6.18.1"
},
"toml": {
"hashes": [
@ -483,6 +506,14 @@
"markers": "python_version >= '3.7'",
"version": "==5.0.5"
},
"typing": {
"hashes": [
"sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9",
"sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"
],
"index": "pypi",
"version": "==3.7.4.3"
},
"typing-extensions": {
"hashes": [
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",

View File

@ -11,3 +11,17 @@ class UnicodeMode:
LINUX = IBUS = const(1)
MACOS = OSX = RALT = const(2)
WINC = const(3)
TYPING_PLATFORMS = [
'linux',
'linux2',
'win32',
'cygwin',
'msys',
'darwin',
'freebsd7',
'freebsd8',
'freebsdN',
'openbsd6',
]

View File

@ -1,16 +1,21 @@
from kmk.kmk_keyboard import KMKKeyboard
class InvalidExtensionEnvironment(Exception):
pass
class Extension:
_enabled = True
_enabled = True # type: bool
def enable(self, keyboard):
# type: (KMKKeyboard) -> None
self._enabled = True
self.on_runtime_enable(keyboard)
def disable(self, keyboard):
# type (KMKKeyboard) -> None
self._enabled = False
self.on_runtime_disable(keyboard)
@ -18,34 +23,43 @@ class Extension:
# The below methods should be implemented by subclasses
def on_runtime_enable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def on_runtime_disable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def during_bootup(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def before_matrix_scan(self, keyboard):
# type: (KMKKeyboard) -> None
'''
Return value will be injected as an extra matrix update
'''
raise NotImplementedError
def after_matrix_scan(self, keyboard):
# type: (KMKKeyboard) -> None
'''
Return value will be replace matrix update if supplied
'''
raise NotImplementedError
def before_hid_send(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def after_hid_send(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def on_powersave_enable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def on_powersave_disable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError

View File

@ -1,6 +1,7 @@
'''Adds international keys'''
from kmk.extensions import Extension
from kmk.keys import make_key
from kmk.kmk_keyboard import KMKKeyboard
class International(Extension):
@ -32,28 +33,37 @@ class International(Extension):
make_key(code=152, names=('LANG9',))
def on_runtime_enable(self, sandbox):
# type: (KMKKeyboard) -> None
return
def on_runtime_disable(self, sandbox):
# type: (KMKKeyboard) -> None
return
def during_bootup(self, sandbox):
# type: (KMKKeyboard) -> None
return
def before_matrix_scan(self, sandbox):
# type: (KMKKeyboard) -> None
return
def after_matrix_scan(self, sandbox):
# type: (KMKKeyboard) -> None
return
def before_hid_send(self, sandbox):
# type: (KMKKeyboard) -> None
return
def after_hid_send(self, sandbox):
# type: (KMKKeyboard) -> None
return
def on_powersave_enable(self, sandbox):
# type: (KMKKeyboard) -> None
return
def on_powersave_disable(self, sandbox):
# type: (KMKKeyboard) -> None
return

View File

@ -1,23 +1,29 @@
from typing import Any, Optional
import sys
from kmk.keys import Key, KeyAttrDict
from kmk.kmk_keyboard import KMKKeyboard
from kmk.consts import TYPING_PLATFORMS
from kmk.kmktime import sleep_ms
if sys.platform in TYPING_PLATFORMS:
from typing import Any, Optional
from kmk.keys import Key, KeyAttrDict
from kmk.kmk_keyboard import KMKKeyboard # Avoid cyclical imports
def passthrough(key, keyboard, *args, **kwargs):
return keyboard
def default_pressed(
key: Key,
keyboard: KMKKeyboard,
KC: KeyAttrDict,
coord_int: Optional[int] = None,
coord_raw: Optional[str] = None,
*args: Any,
**kwargs: Any,
) -> KMKKeyboard:
key, # type: Key
keyboard, # type: KMKKeyboard
KC, # type: KeyAttrDict
coord_int=None, # type: Optional[int]
coord_raw=None, # type: Optional[str]
*args, # type: Any
**kwargs, # type: Any
):
# type: (...) -> KMKKeyboard
keyboard.hid_pending = True
if coord_int is not None:
@ -29,14 +35,15 @@ def default_pressed(
def default_released(
key: Key,
keyboard: KMKKeyboard,
KC: KeyAttrDict,
coord_int: Optional[int] = None,
coord_raw: Optional[str] = None,
*args: Any,
**kwargs: Any, # NOQA
key, # type: Key
keyboard, # type: KMKKeyboard
KC, # type: KeyAttrDict
coord_int=None, # type: Optional[int]
coord_raw=None, # type: Optional[str]
*args, # type: Any
**kwargs, # type: Any # NOQA
):
# type: (...) -> KMKKeyboard
keyboard.hid_pending = True
keyboard.keys_pressed.discard(key)

View File

@ -1,6 +1,6 @@
from typing import List, Optional
import sys
from kmk.keys import Key
from kmk.consts import TYPING_PLATFORMS
from kmk.types import (
KeySeqSleepMeta,
LayerKeyMeta,
@ -9,12 +9,20 @@ from kmk.types import (
UnicodeModeKeyMeta,
)
if sys.platform in TYPING_PLATFORMS:
from typing import List, Optional
def key_seq_sleep_validator(ms: float) -> KeySeqSleepMeta:
# Avoid cyclical imports
from kmk.keys import Key
def key_seq_sleep_validator(ms):
# type: (float) -> KeySeqSleepMeta
return KeySeqSleepMeta(ms)
def layer_key_validator(layer: int, kc: Key = None) -> LayerKeyMeta:
def layer_key_validator(layer, kc=None):
# type: (int, Optional[Key]) -> LayerKeyMeta
'''
Validates the syntax (but not semantics) of a layer key call. We won't
have access to the keymap here, so we can't verify much of anything useful
@ -25,16 +33,19 @@ def layer_key_validator(layer: int, kc: Key = None) -> LayerKeyMeta:
return LayerKeyMeta(layer=layer, kc=kc)
def mod_tap_validator(kc: Key, mods: Optional[List[Key]] = None) -> ModTapKeyMeta:
def mod_tap_validator(kc, mods):
# type: (Key, Optional[List[Key]]) -> ModTapKeyMeta
'''
Validates that mod tap keys are correctly used
'''
return ModTapKeyMeta(kc=kc, mods=mods)
def tap_dance_key_validator(*codes: Key) -> TapDanceKeyMeta:
def tap_dance_key_validator(*codes):
# type: (*Key) -> TapDanceKeyMeta
return TapDanceKeyMeta(codes)
def unicode_mode_key_validator(mode: int) -> UnicodeModeKeyMeta:
def unicode_mode_key_validator(mode):
# type: (int) -> UnicodeModeKeyMeta
return UnicodeModeKeyMeta(mode)

View File

@ -1,43 +1,37 @@
from __future__ import annotations
import gc
from micropython import const
from typing import Any, Callable, List, Optional, Protocol, Set, Tuple, Union
import sys
import kmk.handlers.stock as handlers
from kmk.consts import UnicodeMode
from kmk.consts import TYPING_PLATFORMS, UnicodeMode
from kmk.key_validators import (
key_seq_sleep_validator,
tap_dance_key_validator,
unicode_mode_key_validator,
)
from kmk.kmk_keyboard import KMKKeyboard
from kmk.types import AttrDict, UnicodeModeKeyMeta
DEBUG_OUTPUT: bool = False
if sys.platform in TYPING_PLATFORMS:
from typing import Any, Callable, List, Optional, Set, Tuple, Union
FIRST_KMK_INTERNAL_KEY: int = const(1000)
NEXT_AVAILABLE_KEY: int = 1000
# Avoid cyclical imports
from kmk.kmk_keyboard import KMKKeyboard
KEY_SIMPLE: int = const(0)
KEY_MODIFIER: int = const(1)
KEY_CONSUMER: int = const(2)
ALL_ALPHAS: str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ALL_NUMBERS: str = '1234567890'
DEBUG_OUTPUT = False # type: bool
FIRST_KMK_INTERNAL_KEY = const(1000) # type: int
NEXT_AVAILABLE_KEY = 1000 # type: int
KEY_SIMPLE = const(0) # type: int
KEY_MODIFIER = const(1) # type: int
KEY_CONSUMER = const(2) # type: int
ALL_ALPHAS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # type: str
ALL_NUMBERS = '1234567890' # type: str
# since KC.1 isn't valid Python, alias to KC.N1
ALL_NUMBER_ALIASES: Tuple[str, ...] = tuple(f'N{x}' for x in ALL_NUMBERS)
KeyReturn = Union[Key, ModifierKey, ConsumerKey, None]
class LeftPipeCallback(Protocol):
def __call__(
self, candidate: str, code: Union[str, int], names: Tuple[str, ...]
) -> KeyReturn:
...
ALL_NUMBER_ALIASES = tuple(f'N{x}' for x in ALL_NUMBERS) # type: Tuple[str, ...]
class InfiniteLoopDetected(Exception):
@ -47,10 +41,11 @@ class InfiniteLoopDetected(Exception):
# this is a bit of an FP style thing - combining a pipe operator a-la F# with
# a bootleg Maybe monad to clean up these make_key sequences
def left_pipe_until_some(
candidate: str,
functor: LeftPipeCallback,
*args_iter: Tuple[Union[str, int], Tuple[str, ...]],
) -> KeyReturn:
candidate, # type: str
functor, # type: Callable[[str, Union[str, int], Tuple[str, ...]], Optional[Union[Key, ModifierKey, ConsumerKey]]]
*args_iter, # type: Tuple[Union[str, int], Tuple[str, ...]]
):
# type: (...) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
for args in args_iter:
result = functor(candidate, *args)
if result is not None:
@ -58,41 +53,43 @@ def left_pipe_until_some(
def first_truthy(
candidate: str,
*funcs: Callable[[str], Union[Key, ModifierKey, ConsumerKey, None]],
) -> KeyReturn:
candidate, # type: str
*funcs, # type: Callable[[str], Union[Key, ModifierKey, ConsumerKey, None]]
):
# type: (...) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
for func in funcs:
result = func(candidate)
if result is not None:
return result
def maybe_make_mod_key(candidate: str, code: int, names: Tuple[str, ...]) -> KeyReturn:
def maybe_make_mod_key(candidate, code, names):
# type: (str, int, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
if candidate in names:
return make_mod_key(code=code, names=names)
def maybe_make_key(candidate: str, code: int, names: Tuple[str, ...]) -> KeyReturn:
def maybe_make_key(candidate, code, names):
# type: (str, int, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
if candidate in names:
return make_key(code=code, names=names)
def maybe_make_shifted_key(
candidate: str, target_name: str, names: Tuple[str, ...]
) -> KeyReturn:
def maybe_make_shifted_key(candidate, target_name, names):
# type: (str, str, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
if candidate in names:
return make_shifted_key(target_name=target_name, names=names)
def maybe_make_consumer_key(
candidate: str, code: int, names: Tuple[str, ...]
) -> KeyReturn:
def maybe_make_consumer_key(candidate, code, names):
# type: (str, int, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
if candidate in names:
return make_consumer_key(code=code, names=names)
class KeyAttrDict(AttrDict):
def __getattr__(self, key: str, depth: int = 0) -> KeyReturn:
def __getattr__(self, key, depth=0):
# type: (str, int) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
if depth > 1:
raise InfiniteLoopDetected()
@ -410,54 +407,46 @@ class KeyAttrDict(AttrDict):
KC = KeyAttrDict()
class DefaultPressRelease(Protocol):
def __call__(
self,
key: Key,
keyboard: KMKKeyboard,
KC: KeyAttrDict,
coord_int: Optional[int],
coord_raw: Optional[str],
*args: Any,
**kwargs: Any,
) -> KMKKeyboard:
...
Handler = Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]
HandlerList = List[Handler]
class Key:
def __init__(
self,
code: int,
has_modifiers: Optional[Set[int]] = None,
no_press: Optional[bool] = False,
no_release: Optional[bool] = False,
on_press: DefaultPressRelease = handlers.default_pressed,
on_release: DefaultPressRelease = handlers.default_released,
meta: object = object(),
) -> None:
self.code: int = code
self.has_modifiers: Optional[Set[int]] = has_modifiers
code, # type: int
has_modifiers=None, # type: Optional[Set[int]]
no_press=False, # type: bool
no_release=False, # type: bool
on_press=handlers.default_pressed, # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
on_release=handlers.default_released, # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
meta=object(), # type: object
):
# type: (...) -> None
self.code = code # type: int
self.has_modifiers = has_modifiers # type: Optional[Set[int]]
# cast to bool() in case we get a None value
self.no_press: bool = bool(no_press)
self.no_release: bool = bool(no_press)
self.no_press = bool(no_press) # type: bool
self.no_release = bool(no_press) # type: bool
self._pre_press_handlers: HandlerList = []
self._post_press_handlers: HandlerList = []
self._pre_release_handlers: HandlerList = []
self._post_release_handlers: HandlerList = []
self._handle_press: DefaultPressRelease = on_press
self._handle_release: DefaultPressRelease = on_release
self.meta: object = meta
self._pre_press_handlers = (
[]
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
self._post_press_handlers = (
[]
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
self._pre_release_handlers = (
[]
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
self._post_release_handlers = (
[]
) # type: List[Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]]
self._handle_press = (
on_press
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
self._handle_release = (
on_release
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
self.meta = meta # type: object
def __call__(
self, no_press: Optional[bool] = None, no_release: Optional[bool] = None
) -> Key:
def __call__(self, no_press, no_release):
# type: (Optional[bool], Optional[bool]) -> Key
if no_press is None and no_release is None:
return self
@ -469,37 +458,43 @@ class Key:
)
def __repr__(self):
# type: () -> str
return 'Key(code={}, has_modifiers={})'.format(self.code, self.has_modifiers)
def on_press(
self, state: KMKKeyboard, coord_int: int, coord_raw: str
) -> Union[KMKKeyboard, None]:
def on_press(self, state, coord_int, coord_raw):
# type: (KMKKeyboard, int, str) -> Optional[Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]]
for fn in self._pre_press_handlers:
if not fn(self, state, KC, coord_int, coord_raw):
return None
ret = self._handle_press(self, state, KC, coord_int, coord_raw)
# TODO -- SOFUBI -- look into way to type hint *args and **kwargs of a Callable signature
ret = self._handle_press(
self, state, KC, coord_int, coord_raw
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
for fn in self._post_press_handlers:
fn(self, state, KC, coord_int, coord_raw)
return ret
def on_release(
self, state: KMKKeyboard, coord_int: int, coord_raw: str
) -> Union[KMKKeyboard, None]:
def on_release(self, state, coord_int, coord_raw):
# type: (KMKKeyboard, int, str) -> Optional[Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]]
for fn in self._pre_release_handlers:
if not fn(self, state, KC, coord_int, coord_raw):
return None
ret = self._handle_release(self, state, KC, coord_int, coord_raw)
# TODO -- SOFUBI -- look into way to type hint *args and **kwargs of a Callable signature
ret = self._handle_release(
self, state, KC, coord_int, coord_raw
) # type: Callable[[Key, KMKKeyboard, KeyAttrDict, Optional[int], Optional[str], Any, Any], KMKKeyboard]
for fn in self._post_release_handlers:
fn(self, state, KC, coord_int, coord_raw)
return ret
def clone(self) -> Key:
def clone(self):
# type: () -> Key
'''
Return a shallow clone of the current key without any pre/post press/release
handlers attached. Almost exclusively useful for creating non-colliding keys
@ -516,7 +511,8 @@ class Key:
meta=self.meta,
)
def before_press_handler(self, fn: Handler) -> Key:
def before_press_handler(self, fn):
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
'''
Attach a callback to be run prior to the on_press handler for this key.
Receives the following:
@ -540,7 +536,8 @@ class Key:
self._pre_press_handlers.append(fn)
return self
def after_press_handler(self, fn: Handler) -> Key:
def after_press_handler(self, fn):
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
'''
Attach a callback to be run after the on_release handler for this key.
Receives the following:
@ -563,7 +560,8 @@ class Key:
self._post_press_handlers.append(fn)
return self
def before_release_handler(self, fn: Handler) -> Key:
def before_release_handler(self, fn):
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
'''
Attach a callback to be run prior to the on_release handler for this
key. Receives the following:
@ -587,7 +585,8 @@ class Key:
self._pre_release_handlers.append(fn)
return self
def after_release_handler(self, fn: Handler) -> Key:
def after_release_handler(self, fn):
# type: (Callable[[Any, KMKKeyboard, KeyAttrDict, int, str], KMKKeyboard]) -> Key
'''
Attach a callback to be run after the on_release handler for this key.
Receives the following:
@ -615,14 +614,15 @@ class ModifierKey(Key):
# FIXME this is atrocious to read. Please, please, please, strike down upon
# this with great vengeance and furious anger.
FAKE_CODE: int = const(-1)
FAKE_CODE = const(-1) # type: int
def __call__(
self,
modified_code: Optional[Key] = None,
no_press: Optional[bool] = None,
no_release: Optional[bool] = None,
) -> Union[Key, ModifierKey]:
modified_code=None, # type: Optional[Key]
no_press=None, # type: Optional[bool]
no_release=None, # type: Optional[bool]
):
# type: (...) -> Union[Key, ModifierKey]
if modified_code is None and no_press is None and no_release is None:
return self
@ -655,7 +655,8 @@ class ModifierKey(Key):
return new_keycode
def __repr__(self) -> str:
def __repr__(self):
# () -> str
return 'ModifierKey(code={}, has_modifiers={})'.format(
self.code, self.has_modifiers
)
@ -665,7 +666,8 @@ class ConsumerKey(Key):
pass
def register_key_names(key: Key, names: Tuple[str, ...] = tuple()): # NOQA
def register_key_names(key, names=tuple()): # NOQA
# type: (Key, Tuple[str, ...]) -> Key
'''
Names are globally unique. If a later key is created with
the same name as an existing entry in `KC`, it will overwrite
@ -686,12 +688,8 @@ def register_key_names(key: Key, names: Tuple[str, ...] = tuple()): # NOQA
return key
def make_key(
code: Optional[int] = None,
names: Tuple[str, ...] = tuple(),
type: int = KEY_SIMPLE,
**kwargs: Any,
) -> KeyReturn: # NOQA
def make_key(code=None, names=tuple(), type=KEY_SIMPLE, **kwargs): # NOQA
# type: (Optional[int], Tuple[str, ...], int, **Any) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
'''
Create a new key, aliased by `names` in the KC lookup table.
@ -733,16 +731,13 @@ def make_key(
return key
def make_mod_key(
code: Optional[int],
names: Tuple[str, ...],
*args: Any,
**kwargs: Any,
):
def make_mod_key(code, names, *args, **kwargs):
# type: (Optional[int], Tuple[str, ...], *Any, **Any) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
return make_key(code, names, *args, **kwargs, type=KEY_MODIFIER)
def make_shifted_key(target_name, names=tuple()): # NOQA
# type: (str, Tuple[str, ...]) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
# For... probably a few years, a bug existed here where keys were looked
# up by `KC[...]`, but that's incorrect: an AttrDit exposes a dictionary
# with attributes, but key-based dictionary access with brackets does
@ -757,34 +752,28 @@ def make_shifted_key(target_name, names=tuple()): # NOQA
return key
def make_consumer_key(*args: Any, **kwargs: Any):
def make_consumer_key(*args, **kwargs):
# type: (*Any, **Any) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
return make_key(*args, **kwargs, type=KEY_CONSUMER)
class ArgumentedKey(Protocol):
def __call__(self, *user_args: Any, **user_kwargs: Any) -> Key:
...
class Validator(Protocol):
def __call__(self, *validator_args: Any, **validator_kwargs: Any) -> object:
...
# Argumented keys are implicitly internal, so auto-gen of code
# is almost certainly the best plan here
def make_argumented_key(
validator: Validator = lambda *validator_args, **validator_kwargs: object(),
names: Tuple = tuple(), # NOQA
*constructor_args: Any,
**constructor_kwargs: Any,
) -> Optional[ArgumentedKey]:
validator=lambda *validator_args, **validator_kwargs: object(), # type: object
names=tuple(), # type: Tuple[str, ...] # NOQA
*constructor_args, # type; Any
**constructor_kwargs, # type: Any
):
global NEXT_AVAILABLE_KEY
def _argumented_key(*user_args: Any, **user_kwargs: Any):
def _argumented_key(*user_args, **user_kwargs):
# type: (*Any, **Any) -> Union[Key, ModifierKey, ConsumerKey]
global NEXT_AVAILABLE_KEY
meta = validator(*user_args, **user_kwargs)
meta = validator(
*user_args, **user_kwargs
) # type: Callable[[Any, Any], object]
if meta:
key = Key(

View File

@ -1,77 +1,80 @@
from __future__ import annotations
import sys
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
from kmk.consts import KMK_RELEASE, UnicodeMode
from kmk.consts import KMK_RELEASE, TYPING_PLATFORMS, UnicodeMode
from kmk.hid import BLEHID, USBHID, AbstractHID, HIDModes
from kmk.keys import KC, Key, KeyAttrDict
from kmk.kmktime import ticks_ms
from kmk.matrix import MatrixScanner, intify_coordinate
from kmk.types import TapDanceKeyMeta
if sys.platform in TYPING_PLATFORMS:
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
class Sandbox:
matrix_update: Optional[bytearray] = None
secondary_matrix_update: Optional[bytearray] = None
active_layers: Optional[List[int]] = None
matrix_update = None # type: Optional[bytearray]
secondary_matrix_update = None # type: Optional[bytearray]
active_layers = None # type: Optional[List[int]]
class KMKKeyboard:
#####
# User-configurable
debug_enabled: bool = False
debug_enabled = False # type: bool
keymap: List[KeyAttrDict] = []
coord_mapping: Optional[List[int]] = None
keymap = [] # type: List[KeyAttrDict]
coord_mapping = None # type: Optional[List[int]]
row_pins: Optional[Tuple[Any, ...]] = None
col_pins: Optional[Tuple[Any, ...]] = None
diode_orientation: Optional[int] = None
matrix: Optional[MatrixScanner] = None
matrix_scanner: Type[MatrixScanner] = MatrixScanner
uart_buffer: List[Any] = []
row_pins = None # type: Optional[Tuple[Any, ...]]
col_pins = None # type: Optional[Tuple[Any, ...]]
diode_orientation = None # type: Optional[int]
matrix = None # type: Optional[MatrixScanner]
matrix_scanner = MatrixScanner # type: Type[MatrixScanner]
uart_buffer = [] # type: List[Any]
unicode_mode: int = UnicodeMode.NOOP
tap_time: int = 300
unicode_mode = UnicodeMode.NOOP # type: int
tap_time = 300 # type: int
modules: List[Type[Any]] = []
extensions: List[Type[Any]] = []
sandbox: Sandbox = Sandbox()
modules = [] # type: List[Type[Any]]
extensions = [] # type: List[Type[Any]]
sandbox = Sandbox() # type: Sandbox
#####
# Internal State
keys_pressed: Set[Key] = set()
_coordkeys_pressed: Dict[Any, Any] = {}
hid_type: int = HIDModes.USB
secondary_hid_type: Optional[int] = None
_hid_helper: Optional[Union[Type[AbstractHID], Type[BLEHID], Type[USBHID]]] = None
hid_pending: bool = False
state_layer_key: Optional[Key] = None
matrix_update: Optional[Union[bytearray, None]] = None
secondary_matrix_update: Optional[Union[bytearray, None]] = None
_matrix_modify: Optional[Any] = None
state_changed: bool = False
_old_timeouts_len: Optional[int] = None
_new_timeouts_len: Optional[int] = None
_trigger_powersave_enable: bool = False
_trigger_powersave_disable: bool = False
i2c_deinit_count: int = 0
keys_pressed = set() # type: Set[Key]
_coordkeys_pressed = {} # type: Dict[Any, Any]
hid_type = HIDModes.USB # type: int
secondary_hid_type = None # type: Optional[int]
_hid_helper = (
None
) # type: Optional[Union[Type[AbstractHID], Type[BLEHID], Type[USBHID]]]
hid_pending = False # type: bool
state_layer_key = None # type: Optional[Key]
matrix_update = None # type: Optional[Union[bytearray, None]]
secondary_matrix_update = None # type: Optional[Union[bytearray, None]]
_matrix_modify = None # type: Optional[Any]
state_changed = False # type: bool
_old_timeouts_len = None # type: Optional[int]
_new_timeouts_len = None # type: Optional[int]
_trigger_powersave_enable = False # type: bool
_trigger_powersave_disable = False # type: bool
i2c_deinit_count = 0 # type: int
# this should almost always be PREpended to, replaces
# former use of reversed_active_layers which had pointless
# overhead (the underlying list was never used anyway)
active_layers: List[int] = [0]
active_layers = [0] # type: List[int]
_timeouts: Dict[float, Callable[[], Key]] = {}
_tapping: bool = False
_tap_dance_counts: Dict[Union[Key, TapDanceKeyMeta], Union[int, None]] = {}
_tap_side_effects: Dict[Union[Key, TapDanceKeyMeta], Union[Key, None]] = {}
_timeouts = {} # type: Dict[float, Callable[[], Key]]
_tapping = False # type: bool
_tap_dance_counts = {} # type: Dict[Union[Key, TapDanceKeyMeta], Union[int, None]]
_tap_side_effects = {} # type: Dict[Union[Key, TapDanceKeyMeta], Union[int, None]]
# on some M4 setups (such as klardotsh/klarank_feather_m4, CircuitPython
# 6.0rc1) this runs out of RAM every cycle and takes down the board. no
# real known fix yet other than turning off debug, but M4s have always been
# tight on RAM so....
def __repr__(self) -> str:
def __repr__(self): # type: () -> str
return (
'KMKKeyboard('
'debug_enabled={} '
@ -107,22 +110,26 @@ class KMKKeyboard:
self._tap_side_effects,
)
def _print_debug_cycle(self, init: bool = False) -> None:
def _print_debug_cycle(self, init=False):
# type: (bool) -> None
if self.debug_enabled:
if init:
print('KMKInit(release={})'.format(KMK_RELEASE))
print(self)
def _send_hid(self) -> None:
def _send_hid(self):
# type: () -> None
self._hid_helper.create_report(self.keys_pressed).send()
self.hid_pending = False
def _handle_matrix_report(self, update: bytearray = None) -> None:
def _handle_matrix_report(self, update=None):
# type: (Optional[bytearray]) -> None
if update is not None:
self._on_matrix_changed(update[0], update[1], update[2])
self.state_changed = True
def _find_key_in_map(self, int_coord: int, row: int, col: int) -> Union[Key, None]:
def _find_key_in_map(self, int_coord, row, col):
# type: (int, int, int) -> Optional[Key]
self.state_layer_key = None
try:
idx = self.coord_mapping.index(int_coord)
@ -147,7 +154,8 @@ class KMKKeyboard:
return self.state_layer_key
def _on_matrix_changed(self, row: int, col: int, is_pressed: int) -> KMKKeyboard:
def _on_matrix_changed(self, row, col, is_pressed):
# type: (int, int, int) -> KMKKeyboard
if self.debug_enabled:
print('MatrixChange(col={} row={} pressed={})'.format(col, row, is_pressed))
@ -162,11 +170,12 @@ class KMKKeyboard:
def process_key(
self,
key: Union[Key, TapDanceKeyMeta],
is_pressed: int,
coord_int: Optional[int] = None,
coord_raw: Tuple[int, int] = None,
) -> KMKKeyboard:
key, # type: Union[Key, TapDanceKeyMeta]
is_pressed, # type: int
coord_int=None, # type: Optional[int]
coord_raw=None, # type: Optional[Tuple[int, int]]
):
# (...) -> KMKKeyboard
if self._tapping and not isinstance(key.meta, TapDanceKeyMeta):
self._process_tap_dance(key, is_pressed)
else:
@ -177,24 +186,26 @@ class KMKKeyboard:
return self
def remove_key(self, keycode: Key) -> KMKKeyboard:
def remove_key(self, keycode):
# type: (Key) -> KMKKeyboard
self.keys_pressed.discard(keycode)
return self.process_key(keycode, False)
def add_key(self, keycode: Key) -> KMKKeyboard:
def add_key(self, keycode):
# type: (Key) -> KMKKeyboard
self.keys_pressed.add(keycode)
return self.process_key(keycode, True)
def tap_key(self, keycode: Key) -> KMKKeyboard:
def tap_key(self, keycode):
# type: (Key) -> KMKKeyboard
self.add_key(keycode)
# On the next cycle, we'll remove the key.
self.set_timeout(False, lambda: self.remove_key(keycode))
return self
def _process_tap_dance(
self, changed_key: Union[Key, TapDanceKeyMeta], is_pressed: int
) -> KMKKeyboard:
def _process_tap_dance(self, changed_key, is_pressed):
# type: (Union[Key, TapDanceKeyMeta], int) -> KMKKeyboard
if is_pressed:
if not isinstance(changed_key.meta, TapDanceKeyMeta):
# If we get here, changed_key is not a TapDanceKey and thus
@ -231,7 +242,8 @@ class KMKKeyboard:
return self
def _end_tap_dance(self, td_key: Union[Key, TapDanceKeyMeta]) -> KMKKeyboard:
def _end_tap_dance(self, td_key):
# type: (Union[Key, TapDanceKeyMeta]) -> KMKKeyboard
v = self._tap_dance_counts[td_key] - 1
if v >= 0:
@ -252,12 +264,14 @@ class KMKKeyboard:
return self
def _cleanup_tap_dance(self, td_key: Union[Key, TapDanceKeyMeta]) -> KMKKeyboard:
def _cleanup_tap_dance(self, td_key):
# type: (Union[Key, TapDanceKeyMeta]) -> KMKKeyboard
self._tap_dance_counts[td_key] = 0
self._tapping = any(count > 0 for count in self._tap_dance_counts.values())
return self
def set_timeout(self, after_ticks: float, callback: Callable[[], Key]) -> float:
def set_timeout(self, after_ticks, callback):
# type: (float, Callable[[], Key]) -> float
if after_ticks is False:
# We allow passing False as an implicit "run this on the next process timeouts cycle"
timeout_key = ticks_ms()
@ -270,11 +284,13 @@ class KMKKeyboard:
self._timeouts[timeout_key] = callback
return timeout_key
def _cancel_timeout(self, timeout_key: float) -> None:
def _cancel_timeout(self, timeout_key):
# type: (float) -> None
if timeout_key in self._timeouts:
del self._timeouts[timeout_key]
def _process_timeouts(self) -> KMKKeyboard:
def _process_timeouts(self):
# type: () -> KMKKeyboard
if not self._timeouts:
return self
@ -291,7 +307,8 @@ class KMKKeyboard:
return self
def _init_sanity_check(self) -> KMKKeyboard:
def _init_sanity_check(self):
# type: () -> KMKKeyboard
'''
Ensure the provided configuration is *probably* bootable
'''
@ -305,7 +322,8 @@ class KMKKeyboard:
return self
def _init_coord_mapping(self) -> None:
def _init_coord_mapping(self):
# () -> None
'''
Attempt to sanely guess a coord_mapping if one is not provided. No-op
if `kmk.extensions.split.Split` is used, it provides equivalent
@ -327,7 +345,8 @@ class KMKKeyboard:
for cidx in range(cols_to_calc):
self.coord_mapping.append(intify_coordinate(ridx, cidx))
def _init_hid(self) -> None:
def _init_hid(self):
# type: () -> None
if self.hid_type == HIDModes.NOOP:
self._hid_helper = AbstractHID
elif self.hid_type == HIDModes.USB:
@ -338,7 +357,8 @@ class KMKKeyboard:
self._hid_helper = AbstractHID
self._hid_helper = self._hid_helper()
def _init_matrix(self) -> KMKKeyboard:
def _init_matrix(self):
# type: () -> KMKKeyboard
self.matrix = MatrixScanner(
cols=self.col_pins,
rows=self.row_pins,
@ -348,7 +368,8 @@ class KMKKeyboard:
return self
def before_matrix_scan(self) -> None:
def before_matrix_scan(self):
# type: () -> None
for module in self.modules:
try:
module.before_matrix_scan(self)
@ -363,7 +384,8 @@ class KMKKeyboard:
if self.debug_enabled:
print('Failed to run pre matrix function in extension: ', err, ext)
def after_matrix_scan(self) -> None:
def after_matrix_scan(self):
# type: () -> None
for module in self.modules:
try:
module.after_matrix_scan(self)
@ -378,7 +400,8 @@ class KMKKeyboard:
if self.debug_enabled:
print('Failed to run post matrix function in extension: ', err, ext)
def before_hid_send(self) -> None:
def before_hid_send(self):
# type: () -> None
for module in self.modules:
try:
module.before_hid_send(self)
@ -393,7 +416,8 @@ class KMKKeyboard:
if self.debug_enabled:
print('Failed to run pre hid function in extension: ', err, ext)
def after_hid_send(self) -> None:
def after_hid_send(self):
# type: () -> None
for module in self.modules:
try:
module.after_hid_send(self)
@ -408,7 +432,8 @@ class KMKKeyboard:
if self.debug_enabled:
print('Failed to run post hid function in extension: ', err, ext)
def powersave_enable(self) -> None:
def powersave_enable(self):
# type: () -> None
for module in self.modules:
try:
module.on_powersave_enable(self)
@ -423,7 +448,8 @@ class KMKKeyboard:
if self.debug_enabled:
print('Failed to run post hid function in extension: ', err, ext)
def powersave_disable(self) -> None:
def powersave_disable(self):
# type: () -> None
for module in self.modules:
try:
module.on_powersave_disable(self)
@ -439,10 +465,11 @@ class KMKKeyboard:
def go(
self,
hid_type: int = HIDModes.USB,
secondary_hid_type: Optional[int] = None,
**kwargs: Dict[Any, Any],
) -> None:
hid_type=HIDModes.USB, # type: int
secondary_hid_type=None, # type: Optional[int]
**kwargs, # type: Dict[Any, Any]
):
# (...) -> None
self.hid_type = hid_type
self.secondary_hid_type = secondary_hid_type

View File

@ -1,23 +1,28 @@
import time
def sleep_ms(ms: float) -> None:
def sleep_ms(ms):
# type: (float) -> None
return time.sleep(ms / 1000)
def ticks_ms() -> float:
def ticks_ms():
# type: () -> float
'''Has .25s granularity, but is cheap'''
return time.monotonic() * 1000
def ticks_diff(new: float, old: float) -> float:
def ticks_diff(new, old):
# type: (float, float) -> float
return new - old
def accurate_ticks() -> int:
def accurate_ticks():
# type: () -> int
'''Is more expensive, but good for time critical things'''
return time.monotonic_ns()
def accurate_ticks_diff(new: float, old: float, ms: float) -> bool:
def accurate_ticks_diff(new, old, ms):
# type: (float, float, float) -> bool
return bool(new - old < ms * 1000000)

View File

@ -1,6 +1,12 @@
from typing import List, Optional, Tuple
import sys
from kmk.keys import Key
from kmk.consts import TYPING_PLATFORMS
if sys.platform in TYPING_PLATFORMS:
from typing import List, Optional, Tuple, Union
# Avoid cyclical imports
from kmk.keys import ConsumerKey, Key, ModifierKey
class AttrDict(dict):
@ -12,39 +18,44 @@ class AttrDict(dict):
This is read-only on purpose.
'''
def __getattr__(self, key: str) -> str:
def __getattr__(self, key):
# type: (str) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
return self[key]
class LayerKeyMeta:
def __init__(self, layer: int, kc: Optional[Key] = None) -> None:
self.layer: int = layer
self.kc: Optional[Key] = kc
def __init__(self, layer, kc=None):
# type: (int, Optional[Key]) -> None
self.layer = layer # type: int
self.kc = kc # type: Optional[Key]
class ModTapKeyMeta:
def __init__(
self, kc: Optional[Key] = None, mods: Optional[List[Key]] = None
) -> None:
self.mods: Optional[List[Key]] = mods
self.kc: Optional[Key] = kc
def __init__(self, kc=None, mods=None):
# type: (Optional[Key], Optional[List[Key]]) -> None
self.mods = mods # type: Optional[List[Key]]
self.kc = kc # type: Optional[Key]
class KeySequenceMeta:
def __init__(self, seq: List[Key]):
self.seq: List[Key] = seq
def __init__(self, seq):
# type: (List[Key]) -> None
self.seq = seq # type: List[Key]
class KeySeqSleepMeta:
def __init__(self, ms: float):
self.ms: float = ms
def __init__(self, ms):
# type: (float) -> None
self.ms = ms # type: float
class UnicodeModeKeyMeta:
def __init__(self, mode: int):
self.mode: int = mode
def __init__(self, mode):
# type: (int) -> None
self.mode = mode # type: int
class TapDanceKeyMeta:
def __init__(self, codes: Tuple[Key, ...]):
self.codes: Tuple[Key, ...] = codes
def __init__(self, codes):
# type: (Tuple[Key, ...]) -> None
self.codes = codes # type: Tuple[Key, ...]

View File

@ -24,18 +24,25 @@ exclude = '''
'''
[tool.pyright]
strict = ["kmk"]
typeCheckingMode = "strict"
include = ["kmk"]
exclude = [
"hardware",
".venv",
"user_keymaps",
"boards"
"boards",
".git"
]
venvPath = ".venv"
# stops constant reporting of missing board module etc.
reportMissingModuleSource = false
# reports missing typestubs allowing for a code action to
# create new library typestubs
reportMissingTypeStubs = true
pythonVersion = "3.6"
[tool.mypy]
exclude = "boards/|user_keymaps/"
ignore_missing_imports = true
python_version = "3.6"