Skip to content

Commit 8e1cbe8

Browse files
authored
fix!(QueryList): Generic fixes (#453)
2 parents 6f898b6 + e12b880 commit 8e1cbe8

File tree

3 files changed

+16
-9
lines changed

3 files changed

+16
-9
lines changed

CHANGES

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ $ pip install --user --upgrade --pre libvcs
1515

1616
<!-- Maintainers, insert changes / features for the next release here -->
1717

18+
### Improvement
19+
20+
- `QueryList` generic support improved (#453)
21+
1822
## libvcs 0.27.0 (2024-02-06)
1923

2024
### Development

src/libvcs/_internal/query_list.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
import re
88
import traceback
99
import typing as t
10-
from collections.abc import Mapping, Sequence
10+
from collections.abc import Iterable, Mapping, Sequence
1111

12-
T = t.TypeVar("T", t.Any, t.Any)
12+
T = t.TypeVar("T")
1313
no_arg = object()
1414

1515

@@ -312,7 +312,7 @@ def __init__(self, op: str, *args: object):
312312
return super().__init__(f"{op} not in LOOKUP_NAME_MAP")
313313

314314

315-
class QueryList(list[T]):
315+
class QueryList(t.Generic[T], list[T]):
316316
"""Filter list of object/dictionaries. For small, local datasets.
317317
318318
*Experimental, unstable*.
@@ -464,7 +464,10 @@ class QueryList(list[T]):
464464
data: Sequence[T]
465465
pk_key: t.Optional[str]
466466

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]]:
468471
if self.pk_key is None:
469472
raise PKRequiredException()
470473
return [(getattr(item, self.pk_key), item) for item in self]
@@ -522,7 +525,7 @@ def filter_lookup(obj: t.Any) -> bool:
522525
_filter = matcher
523526
elif matcher is not None:
524527

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:
526529
if isinstance(matcher, list):
527530
return obj in matcher
528531
else:

tests/_internal/test_query_list.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import dataclasses
2-
from typing import Any, Optional, Union
2+
import typing as t
33

44
import pytest
55

@@ -249,9 +249,9 @@ class Obj:
249249
],
250250
)
251251
def test_filter(
252-
items: list[dict[str, Any]],
253-
filter_expr: Optional[dict[str, Union[str, list[str]]]],
254-
expected_result: Union[QueryList[Any], list[dict[str, Any]]],
252+
items: list[dict[str, t.Any]],
253+
filter_expr: t.Optional[t.Union[t.Callable[[t.Any], bool], t.Any]],
254+
expected_result: t.Union[QueryList[t.Any], list[dict[str, t.Any]]],
255255
) -> None:
256256
qs = QueryList(items)
257257
if filter_expr is not None:

0 commit comments

Comments
 (0)