- commit
- 3261d16114cc24b5d12975c008a3a87cf7f98b7c
- parent
- fc000f4a6a23c0aa964652959f2296015a985d76
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2026-02-26 21:25
add type annotations
Diffstat
| M | xiio.py | 50 | ++++++++++++++++++++++++++++++++------------------ |
1 files changed, 32 insertions, 18 deletions
diff --git a/xiio.py b/xiio.py
@@ -2,20 +2,34 @@ import math 2 2 import os 3 3 import selectors 4 4 import time -1 5 import typing -1 6 from collections.abc import Coroutine -1 7 from collections.abc import Generator 5 8 from selectors import EVENT_READ as READ 6 9 from selectors import EVENT_WRITE as WRITE 7 10 -1 11 T = typing.TypeVar('T') -1 12 Files = dict[int, int] -1 13 Gen = Generator['Condition', None, T] -1 14 Coro = Coroutine['Condition', None, T] -1 15 8 16 9 17 class Condition:10 -1 def __init__(self, *, files={}, futures=set(), time=math.inf):-1 18 def __init__( -1 19 self, -1 20 *, -1 21 files: Files = {}, -1 22 futures: set['Future[typing.Any]'] = set(), -1 23 time: float = math.inf, -1 24 ): 11 25 self.files = files or {} 12 26 self.futures = futures or set() 13 27 self.time = time 14 2815 -1 def __await__(self):-1 29 def __await__(self) -> Gen[None]: 16 30 yield self 17 3118 -1 def select(self):-1 32 def select(self) -> None: 19 33 timeout = self.time - time.monotonic() 20 34 if any(future.done for future in self.futures): 21 35 timeout = 0 @@ -25,51 +39,51 @@ class Condition: 25 39 sel.select(None if timeout == math.inf else timeout) 26 40 27 4128 -1 async def sleep(seconds):-1 42 async def sleep(seconds: float) -> None: 29 43 await Condition(time=time.monotonic() + seconds) 30 44 31 4532 -1 async def read(file, size):-1 46 async def read(file, size: int) -> bytes: 33 47 fileno = file if isinstance(file, int) else file.fileno() 34 48 await Condition(files={fileno: READ}) 35 49 return os.read(fileno, size) 36 50 37 5138 -1 async def write(file, data):-1 52 async def write(file, data: bytes) -> int: 39 53 fileno = file if isinstance(file, int) else file.fileno() 40 54 await Condition(files={fileno: WRITE}) 41 55 return os.write(fileno, data) 42 56 43 5744 -1 async def writeall(file, data):-1 58 async def writeall(file, data: bytes) -> None: 45 59 while data: 46 60 size = await write(file, data) 47 61 data = data[size:] 48 62 49 6350 -1 class Future:51 -1 def __init__(self):52 -1 self.result = None53 -1 self.exc = None54 -1 self.done = False-1 64 class Future(typing.Generic[T]): -1 65 def __init__(self) -> None: -1 66 self.result: T | None = None -1 67 self.exc: BaseException | None = None -1 68 self.done: bool = False 55 6956 -1 def set_result(self, value):-1 70 def set_result(self, value: T) -> None: 57 71 self.result = value 58 72 self.done = True 59 7360 -1 def set_exception(self, exc):-1 74 def set_exception(self, exc: BaseException) -> None: 61 75 self.exc = exc 62 76 self.done = True 63 7764 -1 def __await__(self):-1 78 def __await__(self) -> Gen[T]: 65 79 yield Condition(futures={self}) 66 80 if self.exc: 67 81 raise self.exc 68 82 else:69 -1 return self.result-1 83 return typing.cast(T, self.result) 70 84 71 8572 -1 def run(coro):-1 86 def run(coro: Coro[T]) -> T: 73 87 gen = coro.__await__() 74 88 try: 75 89 condition = next(gen) @@ -81,4 +95,4 @@ def run(coro): 81 95 else: 82 96 condition = next(gen) 83 97 except StopIteration as e:84 -1 return e.value-1 98 return typing.cast(T, e.value)