Skip to content

Commit 80b609f

Browse files
committed
better type hints
1 parent b18c90f commit 80b609f

File tree

14 files changed

+242
-233
lines changed

14 files changed

+242
-233
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111
- `firebird.base.buffer.MemoryBuffer.get_raw` method.
1212
- `get_raw` method to `BufferFactory`, `BytesBufferFactory` and `CTypesBufferFactory`.
1313
- `__repr__` method for `PyCode` and `PyCallable` that will limit output to 50 characters.
14+
- Optional `encoding` parameter for `ZMQAddress` constructor.
1415

1516
### Changed
1617

docs/changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Version 2.0.0 (unreleased)
1616
- Change: Sentinel objects completely reworked. Individual sentinels are now classes
1717
derived from `.Sentinel`.
1818
- Added: `__repr__` method for `.PyCode` and `.PyCallable` that will limit output to 50 characters.
19+
- Added: Optional `encoding` parameter for `ZMQAddress` constructor.
1920

2021
* `~firebird.base.buffer` module:
2122

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,15 @@ unfixable = [
105105
# Don't change single quotes to double
106106
"Q000"
107107
]
108+
exclude = ["*_pb2.py", "*.pyi", "tests/*", "docs/*", "work/*"]
108109

109110
[tool.ruff.lint.isort]
110111
known-first-party = ["firebird.base"]
111112

112113
[tool.ruff.lint.flake8-tidy-imports]
113114
ban-relative-imports = "all"
114115

115-
[tool.ruff.lint.per-file-ignores]
116+
[tool.ruff.lint.extend-per-file-ignores]
116117
# Tests can use magic values, assertions, and relative imports
117118
"tests/**/*" = ["PLR2004", "S101", "TID252"]
118119

src/firebird/base/buffer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def __init__(self, init: int | bytes, size: int | None=None, *,
246246
def _ensure_space(self, size: int) -> None:
247247
if len(self.raw) < self.pos + size:
248248
self.resize(self.pos + size)
249-
def _check_space(self, size: int):
249+
def _check_space(self, size: int) -> None:
250250
if len(self.raw) < self.pos + size:
251251
raise BufferError("Insufficient buffer size")
252252
def clear(self) -> None:
@@ -508,7 +508,7 @@ def read_sized_string(self, *, encoding: str='ascii', errors: str='strict') -> s
508508
UnicodeDecodeError: If the read bytes cannot be decoded using `encoding`.
509509
"""
510510
return self.read(self.read_short()).decode(encoding, errors)
511-
def read_bytes(self) -> bytes:
511+
def read_bytes(self) -> bytes | bytearray:
512512
"""Read content of binary cluster (2 bytes data length followed by data).
513513
514514

src/firebird/base/collections.py

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@
6060

6161
from __future__ import annotations
6262

63-
import copy as std_copy
64-
from collections.abc import Callable, Generator, Iterable, Mapping, Sequence
63+
from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Sequence
6564
from operator import attrgetter
66-
from typing import Any, cast
65+
from typing import Any, TypeAlias, TypeVar, cast
6766

6867
from .types import UNDEFINED, Distinct, Error, Sentinel
6968

69+
_T = TypeVar("_T")
7070

71-
def make_lambda(expr: str, params: str='item', context: dict[str, Any] | None=None):
71+
def make_lambda(expr: str, params: str='item', context: dict[str, Any] | None=None) -> Callable[..., Any]:
7272
"""Makes lambda function from expression.
7373
7474
Arguments:
@@ -87,13 +87,13 @@ def make_lambda(expr: str, params: str='item', context: dict[str, Any] | None=No
8787
#: Collection Item
8888
Item = Any
8989
#: Collection Item type specification
90-
TypeSpec = type | tuple[type]
90+
TypeSpec: TypeAlias = type | tuple[type, ...]
9191
#: Collection Item sort expression
92-
ItemExpr = str | Callable[[Item], Item]
92+
ItemExpr: TypeAlias = str | Callable[[Item], Any]
9393
#: Filter expression
94-
FilterExpr = str | Callable[[Item], bool]
94+
FilterExpr: TypeAlias = str | Callable[[Item], bool]
9595
#: Check expression
96-
CheckExpr = str | Callable[[Item, Any], bool]
96+
CheckExpr: TypeAlias = str | Callable[[Item, Any], bool]
9797

9898
class BaseObjectCollection:
9999
"""Base class for collection of objects.
@@ -128,7 +128,7 @@ def filterfalse(self, expr: FilterExpr) -> Generator[Item, None, None]:
128128
"""
129129
fce = expr if callable(expr) else make_lambda(expr)
130130
return (item for item in self if not fce(item))
131-
def find(self, expr: FilterExpr, default: Any=None) -> Item:
131+
def find(self, expr: FilterExpr, default: _T=None) -> Item | _T:
132132
"""Returns first item for which `expr` is evaluated as True, or default.
133133
134134
Arguments:
@@ -291,7 +291,7 @@ def __valchk(self, value: Item) -> None:
291291
def __updchk(self) -> None:
292292
if self.__frozen:
293293
raise TypeError("Cannot modify frozen DataList")
294-
def __setitem__(self, index, value) -> None:
294+
def __setitem__(self, index: int | slice, value: Item | Iterable[Item]) -> None:
295295
"""Set item[index] = value. Performs type check and frozen check."""
296296
self.__updchk()
297297
if isinstance(index, slice):
@@ -300,11 +300,11 @@ def __setitem__(self, index, value) -> None:
300300
else:
301301
self.__valchk(value)
302302
super().__setitem__(index, value)
303-
def __delitem__(self, index) -> None:
303+
def __delitem__(self, index: int | slice) -> None:
304304
"""Delete item[index]. Performs frozen check."""
305305
self.__updchk()
306306
super().__delitem__(index)
307-
def __contains__(self, o):
307+
def __contains__(self, o) -> bool:
308308
"""Return key in self. Optimized for frozen lists with a key_expr.
309309
310310
If the list is frozen and has a key_expr, uses an internal map for
@@ -345,7 +345,7 @@ def append(self, item: Item) -> None:
345345
self.__updchk()
346346
self.__valchk(item)
347347
super().append(item)
348-
def extend(self, iterable: Iterable) -> None:
348+
def extend(self, iterable: Iterable[Item]) -> None:
349349
"""Extend the list by appending all the items in the given iterable.
350350
351351
Raises:
@@ -354,7 +354,8 @@ def extend(self, iterable: Iterable) -> None:
354354
"""
355355
for item in iterable:
356356
self.append(item)
357-
def sort(self, attrs: list | None=None, expr: ItemExpr | None=None, *, reverse: bool=False) -> None:
357+
def sort(self, attrs: list[str] | tuple[str, ...] | None=None,
358+
expr: ItemExpr | None=None, *, reverse: bool=False) -> None:
358359
"""Sort items in-place, optionaly using attribute values as key or key expression.
359360
360361
Arguments:
@@ -453,7 +454,7 @@ def extract(self, expr: FilterExpr, *, copy: bool=False) -> DataList:
453454
else:
454455
i += 1
455456
return l
456-
def get(self, key: Any, default: Any=None) -> Item:
457+
def get(self, key: Any, default: _T=None) -> Item | _T:
457458
"""Returns item with given key using default key expression. Returns `default`
458459
value if item is not found.
459460
@@ -489,7 +490,7 @@ def frozen(self) -> bool:
489490
"""
490491
return self.__frozen
491492
@property
492-
def key_expr(self) -> Item:
493+
def key_expr(self) -> Item | None:
493494
"""Key expression.
494495
"""
495496
return self.__key_expr
@@ -533,25 +534,25 @@ class Registry(BaseObjectCollection, Mapping[Any, Distinct]):
533534
data: Either a `.Distinct` instance, or sequence or mapping of `.Distinct`
534535
instances.
535536
"""
536-
def __init__(self, data: Mapping | Sequence | Registry=None):
537-
self._reg: dict = {}
537+
def __init__(self, data: Mapping[Any, Distinct] | Sequence[Distinct] | Registry=None):
538+
self._reg: dict[Any, Distinct] = {}
538539
if data:
539540
self.update(data)
540541
def __len__(self):
541542
return len(self._reg)
542-
def __getitem__(self, key):
543+
def __getitem__(self, key: Any) -> Distinct:
543544
"""Return self[key]. Accepts a key value or a `.Distinct` instance."""
544545
return self._reg[key.get_key() if isinstance(key, Distinct) else key]
545-
def __setitem__(self, key, value):
546+
def __setitem__(self, key: Any, value: Distinct) -> None:
546547
assert isinstance(value, Distinct) # noqa: S101
547548
self._reg[key.get_key() if isinstance(key, Distinct) else key] = value
548-
def __delitem__(self, key):
549+
def __delitem__(self, key: Any) -> None:
549550
del self._reg[key.get_key() if isinstance(key, Distinct) else key]
550-
def __iter__(self):
551+
def __iter__(self) -> Iterator[Distinct]:
551552
return iter(self._reg.values())
552-
def __repr__(self):
553+
def __repr__(self) -> str:
553554
return f"{self.__class__.__name__}([{', '.join(repr(x) for x in self)}])"
554-
def __contains__(self, item):
555+
def __contains__(self, item: Any) -> bool:
555556
"""Return key in self. Accepts a key value or a `.Distinct` instance."""
556557
if isinstance(item, Distinct):
557558
item = item.get_key()
@@ -560,7 +561,7 @@ def clear(self) -> None:
560561
"""Remove all items from registry.
561562
"""
562563
self._reg.clear()
563-
def get(self, key: Any, default: Any=None) -> Distinct:
564+
def get(self, key: Any, default: _T=None) -> Distinct | _T:
564565
""" D.get(key[,d]) -> D[key] if key in D else d. d defaults to None.
565566
566567
Arguments:
@@ -580,11 +581,11 @@ def store(self, item: Distinct) -> Distinct:
580581
raise ValueError(f"Item already registered, key: '{key}'")
581582
self._reg[key] = item
582583
return item
583-
def remove(self, item: Distinct):
584+
def remove(self, item: Distinct) -> None:
584585
"""Removes item from registry (same as: del R[item]).
585586
"""
586587
del self._reg[item.get_key()]
587-
def update(self, _from: Distinct | Mapping | Sequence) -> None:
588+
def update(self, _from: Distinct | Mapping[Any, Distinct] | Sequence[Distinct]) -> None:
588589
"""Update items in the registry.
589590
590591
Arguments:
@@ -596,7 +597,7 @@ def update(self, _from: Distinct | Mapping | Sequence) -> None:
596597
else:
597598
for item in cast(Mapping, _from).values() if hasattr(_from, 'values') else _from:
598599
self[item] = item
599-
def extend(self, _from: Distinct | Mapping | Sequence) -> None:
600+
def extend(self, _from: Distinct | Mapping[Any, Distinct] | Sequence[Distinct]) -> None:
600601
"""Store one or more items to the registry.
601602
602603
Unlike `update`, this method requires that the items (or their keys)
@@ -617,17 +618,8 @@ def extend(self, _from: Distinct | Mapping | Sequence) -> None:
617618
def copy(self) -> Registry:
618619
"""Shalow copy of the registry.
619620
"""
620-
if self.__class__ is Registry:
621-
return Registry(self)
622-
data = self._reg
623-
try:
624-
self._reg = {}
625-
c = std_copy.copy(self)
626-
finally:
627-
self._reg = data
628-
c.update(self)
629-
return c
630-
def pop(self, key: Any, default: Any=...) -> Distinct:
621+
return self.__class__(self)
622+
def pop(self, key: Any, default: _T=...) -> Distinct | _T:
631623
"""Remove specified `key` and return the corresponding `.Distinct` object.
632624
633625
If `key` is not found, the `default` is returned if given, otherwise
@@ -653,4 +645,4 @@ def popitem(self, *, last: bool=True) -> Distinct:
653645
self.remove(item)
654646
return item
655647
except StopIteration:
656-
raise KeyError()
648+
raise KeyError() # noqa: B904

0 commit comments

Comments
 (0)