From 589d4b3b13395e4af983abb6c07395ae8a38f1bd Mon Sep 17 00:00:00 2001 From: Yusur Princeps Date: Thu, 24 Jul 2025 11:44:24 +0200 Subject: [PATCH] type annotations, NotFoundError --- CHANGELOG.md | 3 ++- src/suou/collections.py | 22 +++++++++++++--------- src/suou/exceptions.py | 7 ++++++- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c53a42..da8638d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ + `sqlalchemy`: add `unbound_fk()`, `bound_fk()` + Add `timed_cache()`, `TimedDict()` -+ Move obsolete stuff to `obsolete` package ++ Move obsolete stuff to `obsolete` package (includes configparse 0.3 as of now) ++ Add more exceptions: `NotFoundError()` ## 0.4.0 diff --git a/src/suou/collections.py b/src/suou/collections.py index a11dd87..37097d2 100644 --- a/src/suou/collections.py +++ b/src/suou/collections.py @@ -18,12 +18,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. from __future__ import annotations import time -from typing import TypeVar +from typing import Iterator, TypeVar _KT = TypeVar('_KT') +_VT = TypeVar('_VT') -class TimedDict(dict): +class TimedDict(dict[_KT, _VT]): + """ + Dictionary where keys expire after the defined time to live, expressed in seconds. + """ _expires: dict[_KT, int] _ttl: int @@ -32,7 +36,7 @@ class TimedDict(dict): self._ttl = ttl self._expires = dict() - def check_ex(self, key): + def check_ex(self, key: _KT): if super().__contains__(key): ex = self._expires[key] now = int(time.time()) @@ -42,28 +46,28 @@ class TimedDict(dict): elif key in self._expires: del self._expires[key] - def __getitem__(self, key: _KT, /): + def __getitem__(self, key: _KT, /) -> _VT: self.check_ex(key) return super().__getitem__(key) - def get(self, key, default=None, /): + def get(self, key: _KT, default: _VT | None = None, /) -> _VT | None: self.check_ex(key) return super().get(key) - def __setitem__(self, key: _KT, value, /) -> None: + def __setitem__(self, key: _KT, value: _VT, /) -> None: self._expires = int(time.time() + self._ttl) super().__setitem__(key, value) - def setdefault(self, key, default, /): + def setdefault(self, key: _KT, default: _VT, /) -> _VT: self.check_ex(key) self._expires = int(time.time() + self._ttl) return super().setdefault(key, default) - def __delitem__(self, key, /): + def __delitem__(self, key: _KT, /) -> None: del self._expires[key] super().__delitem__(key) - def __iter__(self): + def __iter__(self) -> Iterator[_KT]: for k in super(): self.check_ex(k) return super().__iter__() diff --git a/src/suou/exceptions.py b/src/suou/exceptions.py index 170125f..c1fe496 100644 --- a/src/suou/exceptions.py +++ b/src/suou/exceptions.py @@ -41,6 +41,11 @@ class InconsistencyError(RuntimeError): This program is in a state which it's not supposed to be in. """ +class NotFoundError(LookupError): + """ + The requested item was not found. + """ + __all__ = ( - 'MissingConfigError', 'MissingConfigWarning', 'LexError', 'InconsistencyError' + 'MissingConfigError', 'MissingConfigWarning', 'LexError', 'InconsistencyError', 'NotFoundError' ) \ No newline at end of file