|
7 | 7 | import re |
8 | 8 | import traceback |
9 | 9 | import typing as t |
10 | | -from collections.abc import Mapping, Sequence |
| 10 | +from collections.abc import Iterable, Mapping, Sequence |
11 | 11 |
|
12 | | -T = t.TypeVar("T", t.Any, t.Any) |
| 12 | +T = t.TypeVar("T") |
13 | 13 | no_arg = object() |
14 | 14 |
|
15 | 15 |
|
@@ -312,7 +312,7 @@ def __init__(self, op: str, *args: object): |
312 | 312 | return super().__init__(f"{op} not in LOOKUP_NAME_MAP") |
313 | 313 |
|
314 | 314 |
|
315 | | -class QueryList(list[T]): |
| 315 | +class QueryList(t.Generic[T], list[T]): |
316 | 316 | """Filter list of object/dictionaries. For small, local datasets. |
317 | 317 |
|
318 | 318 | *Experimental, unstable*. |
@@ -464,7 +464,10 @@ class QueryList(list[T]): |
464 | 464 | data: Sequence[T] |
465 | 465 | pk_key: t.Optional[str] |
466 | 466 |
|
467 | | - def items(self) -> list[T]: |
| 467 | + def __init__(self, items: t.Optional["Iterable[T]"] = None) -> None: |
| 468 | + super().__init__(items if items is not None else []) |
| 469 | + |
| 470 | + def items(self) -> list[tuple[str, T]]: |
468 | 471 | if self.pk_key is None: |
469 | 472 | raise PKRequiredException() |
470 | 473 | return [(getattr(item, self.pk_key), item) for item in self] |
@@ -522,7 +525,7 @@ def filter_lookup(obj: t.Any) -> bool: |
522 | 525 | _filter = matcher |
523 | 526 | elif matcher is not None: |
524 | 527 |
|
525 | | - def val_match(obj: t.Union[str, list[t.Any]]) -> bool: |
| 528 | + def val_match(obj: t.Union[str, list[t.Any], T]) -> bool: |
526 | 529 | if isinstance(matcher, list): |
527 | 530 | return obj in matcher |
528 | 531 | else: |
|
0 commit comments