Skip to content

Commit 59dc614

Browse files
committed
More type hints
1 parent e717161 commit 59dc614

File tree

5 files changed

+87
-72
lines changed

5 files changed

+87
-72
lines changed

docs/changelog.rst

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Changelog
1212

1313
- Drop deprecated ``InputDevice.fn`` (use ``InputDevice.path`` instead).
1414

15+
- More type hints.
16+
1517

1618
1.8.0 (Jan 25, 2025)
1719
====================

src/evdev/device.py

+40-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import collections
21
import contextlib
32
import os
3+
from typing import NamedTuple, Tuple, Union
44

55
from . import _input, ecodes, util
66

@@ -10,18 +10,10 @@
1010
from .eventio import EvdevError, EventIO
1111

1212

13-
# --------------------------------------------------------------------------
14-
_AbsInfo = collections.namedtuple("AbsInfo", ["value", "min", "max", "fuzz", "flat", "resolution"])
15-
16-
_KbdInfo = collections.namedtuple("KbdInfo", ["delay", "repeat"])
17-
18-
_DeviceInfo = collections.namedtuple("DeviceInfo", ["bustype", "vendor", "product", "version"])
19-
20-
21-
class AbsInfo(_AbsInfo):
13+
class AbsInfo(NamedTuple):
2214
"""Absolute axis information.
2315
24-
A ``namedtuple`` used for storing absolute axis information -
16+
A ``namedtuple`` with absolute axis information -
2517
corresponds to the ``input_absinfo`` struct:
2618
2719
Attributes
@@ -57,11 +49,18 @@ class AbsInfo(_AbsInfo):
5749
5850
"""
5951

52+
value: int
53+
min: int
54+
max: int
55+
fuzz: int
56+
flat: int
57+
resolution: int
58+
6059
def __str__(self):
61-
return "val {}, min {}, max {}, fuzz {}, flat {}, res {}".format(*self)
60+
return "value {}, min {}, max {}, fuzz {}, flat {}, res {}".format(*self) # pylint: disable=not-an-iterable
6261

6362

64-
class KbdInfo(_KbdInfo):
63+
class KbdInfo(NamedTuple):
6564
"""Keyboard repeat rate.
6665
6766
Attributes
@@ -74,11 +73,14 @@ class KbdInfo(_KbdInfo):
7473
Keyboard repeat rate in characters per second.
7574
"""
7675

76+
delay: int
77+
repeat: int
78+
7779
def __str__(self):
78-
return "delay {}, repeat {}".format(*self)
80+
return "delay {}, repeat {}".format(self.delay, self.repeat)
7981

8082

81-
class DeviceInfo(_DeviceInfo):
83+
class DeviceInfo(NamedTuple):
8284
"""
8385
Attributes
8486
----------
@@ -88,9 +90,14 @@ class DeviceInfo(_DeviceInfo):
8890
version
8991
"""
9092

93+
bustype: int
94+
vendor: int
95+
product: int
96+
version: int
97+
9198
def __str__(self):
9299
msg = "bus: {:04x}, vendor {:04x}, product {:04x}, version {:04x}"
93-
return msg.format(*self)
100+
return msg.format(*self) # pylint: disable=not-an-iterable
94101

95102

96103
class InputDevice(EventIO):
@@ -100,7 +107,7 @@ class InputDevice(EventIO):
100107

101108
__slots__ = ("path", "fd", "info", "name", "phys", "uniq", "_rawcapabilities", "version", "ff_effects_count")
102109

103-
def __init__(self, dev):
110+
def __init__(self, dev: Union[str, bytes, os.PathLike]):
104111
"""
105112
Arguments
106113
---------
@@ -111,15 +118,14 @@ def __init__(self, dev):
111118
#: Path to input device.
112119
self.path = dev if not hasattr(dev, "__fspath__") else dev.__fspath__()
113120

114-
# Certain operations are possible only when the device is opened in
115-
# read-write mode.
121+
# Certain operations are possible only when the device is opened in read-write mode.
116122
try:
117123
fd = os.open(dev, os.O_RDWR | os.O_NONBLOCK)
118124
except OSError:
119125
fd = os.open(dev, os.O_RDONLY | os.O_NONBLOCK)
120126

121127
#: A non-blocking file descriptor to the device file.
122-
self.fd = fd
128+
self.fd: int = fd
123129

124130
# Returns (bustype, vendor, product, version, name, phys, capabilities).
125131
info_res = _input.ioctl_devinfo(self.fd)
@@ -128,16 +134,16 @@ def __init__(self, dev):
128134
self.info = DeviceInfo(*info_res[:4])
129135

130136
#: The name of the event device.
131-
self.name = info_res[4]
137+
self.name: str = info_res[4]
132138

133139
#: The physical topology of the device.
134-
self.phys = info_res[5]
140+
self.phys: str = info_res[5]
135141

136142
#: The unique identifier of the device.
137-
self.uniq = info_res[6]
143+
self.uniq: str = info_res[6]
138144

139145
#: The evdev protocol version.
140-
self.version = _input.ioctl_EVIOCGVERSION(self.fd)
146+
self.version: int = _input.ioctl_EVIOCGVERSION(self.fd)
141147

142148
#: The raw dictionary of device capabilities - see `:func:capabilities()`.
143149
self._rawcapabilities = _input.ioctl_capabilities(self.fd)
@@ -152,7 +158,7 @@ def __del__(self):
152158
except (OSError, ImportError, AttributeError):
153159
pass
154160

155-
def _capabilities(self, absinfo=True):
161+
def _capabilities(self, absinfo: bool = True):
156162
res = {}
157163

158164
for etype, _ecodes in self._rawcapabilities.items():
@@ -170,7 +176,7 @@ def _capabilities(self, absinfo=True):
170176

171177
return res
172178

173-
def capabilities(self, verbose=False, absinfo=True):
179+
def capabilities(self, verbose: bool = False, absinfo: bool = True):
174180
"""
175181
Return the event types that this device supports as a mapping of
176182
supported event types to lists of handled event codes.
@@ -215,7 +221,7 @@ def capabilities(self, verbose=False, absinfo=True):
215221
else:
216222
return self._capabilities(absinfo)
217223

218-
def input_props(self, verbose=False):
224+
def input_props(self, verbose: bool = False):
219225
"""
220226
Get device properties and quirks.
221227
@@ -236,7 +242,7 @@ def input_props(self, verbose=False):
236242

237243
return props
238244

239-
def leds(self, verbose=False):
245+
def leds(self, verbose: bool = False):
240246
"""
241247
Return currently set LED keys.
242248
@@ -257,7 +263,7 @@ def leds(self, verbose=False):
257263

258264
return leds
259265

260-
def set_led(self, led_num, value):
266+
def set_led(self, led_num: int, value: int):
261267
"""
262268
Set the state of the selected LED.
263269
@@ -327,7 +333,7 @@ def grab_context(self):
327333
yield
328334
self.ungrab()
329335

330-
def upload_effect(self, effect):
336+
def upload_effect(self, effect: "ff.Effect"):
331337
"""
332338
Upload a force feedback effect to a force feedback device.
333339
"""
@@ -354,10 +360,10 @@ def repeat(self):
354360
return KbdInfo(*_input.ioctl_EVIOCGREP(self.fd))
355361

356362
@repeat.setter
357-
def repeat(self, value):
363+
def repeat(self, value: Tuple[int, int]):
358364
return _input.ioctl_EVIOCSREP(self.fd, *value)
359365

360-
def active_keys(self, verbose=False):
366+
def active_keys(self, verbose: bool = False):
361367
"""
362368
Return currently active keys.
363369
@@ -380,7 +386,7 @@ def active_keys(self, verbose=False):
380386

381387
return active_keys
382388

383-
def absinfo(self, axis_num):
389+
def absinfo(self, axis_num: int):
384390
"""
385391
Return current :class:`AbsInfo` for input device axis
386392
@@ -396,7 +402,7 @@ def absinfo(self, axis_num):
396402
"""
397403
return AbsInfo(*_input.ioctl_EVIOCGABS(self.fd, axis_num))
398404

399-
def set_absinfo(self, axis_num, value=None, min=None, max=None, fuzz=None, flat=None, resolution=None):
405+
def set_absinfo(self, axis_num: int, value=None, min=None, max=None, fuzz=None, flat=None, resolution=None):
400406
"""
401407
Update :class:`AbsInfo` values. Only specified values will be overwritten.
402408

src/evdev/eventio.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import functools
33
import os
44
import select
5+
from typing import Iterator
56

67
from . import _input, _uinput, ecodes
78
from .events import InputEvent
@@ -35,7 +36,7 @@ def fileno(self):
3536
"""
3637
return self.fd
3738

38-
def read_loop(self):
39+
def read_loop(self) -> Iterator[InputEvent]:
3940
"""
4041
Enter an endless :func:`select.select()` loop that yields input events.
4142
"""
@@ -45,7 +46,7 @@ def read_loop(self):
4546
for event in self.read():
4647
yield event
4748

48-
def read_one(self):
49+
def read_one(self) -> InputEvent:
4950
"""
5051
Read and return a single input event as an instance of
5152
:class:`InputEvent <evdev.events.InputEvent>`.
@@ -59,7 +60,7 @@ def read_one(self):
5960
if event:
6061
return InputEvent(*event)
6162

62-
def read(self):
63+
def read(self) -> Iterator[InputEvent]:
6364
"""
6465
Read multiple input events from device. Return a generator object that
6566
yields :class:`InputEvent <evdev.events.InputEvent>` instances. Raises
@@ -114,7 +115,7 @@ def write_event(self, event):
114115
self.write(event.type, event.code, event.value)
115116

116117
@need_write
117-
def write(self, etype, code, value):
118+
def write(self, etype: int, code: int, value: int):
118119
"""
119120
Inject an input event into the input subsystem. Events are
120121
queued until a synchronization event is received.

0 commit comments

Comments
 (0)