1+ import dataclasses
12import re
23import traceback
3- from typing import Any , Callable , Optional , Protocol , Sequence , TypeVar , Union
4+ from typing import Any , Callable , Generic , Optional , Protocol , Sequence , TypeVar , Union
45
56T = TypeVar ("T" , Any , Any )
67
@@ -120,9 +121,13 @@ def lookup_iregex(data, rhs):
120121}
121122
122123
123- class QueryList (list [T ]):
124+ @dataclasses .dataclass (eq = False )
125+ class QueryList (Generic [T ]):
124126 """Filter list of object/dicts. For small, local datasets. *Experimental, unstable*.
125127
128+ :py:func:`dataclasses.dataclass` is only used for ``__repr__`` and pytest comparison
129+ details.
130+
126131 >>> query = QueryList(
127132 ... [
128133 ... {
@@ -139,35 +144,44 @@ class QueryList(list[T]):
139144 ... },
140145 ... ]
141146 ... )
142- >>> query.filter(place="Chicago suburbs")[0]['city']
147+ >>> query.filter(place="Chicago suburbs").data [0]['city']
143148 'Elmhurst'
144- >>> query.filter(place__icontains="chicago")[0]['city']
149+ >>> query.filter(place__icontains="chicago").data [0]['city']
145150 'Elmhurst'
146- >>> query.filter(foods__breakfast="waffles")[0]['city']
151+ >>> query.filter(foods__breakfast="waffles").data [0]['city']
147152 'Elmhurst'
148- >>> query.filter(foods__fruit__in="cantelope")[0]['city']
153+ >>> query.filter(foods__fruit__in="cantelope").data [0]['city']
149154 'Elmhurst'
150- >>> query.filter(foods__fruit__in="orange")[0]['city']
155+ >>> query.filter(foods__fruit__in="orange").data [0]['city']
151156 'Tampa'
152157 """
153158
159+ __slots__ = ("data" , "pk_key" )
154160 data : Sequence [T ]
155161
162+ # def __init__(self, data, pk_key: Optional[str] = None):
163+ # self.data: Sequence[T] = data
164+ # #: Primary key for objects, optional.
165+ # #: Use for .get(), .items()
166+ # self.pk_key: Optional[Any] = pk_key
167+
156168 def items (self ):
157169 data : Sequence [T ]
158170
159171 if self .pk_key is None :
160172 raise Exception ("items() require a pk_key exists" )
161- return [(getattr (item , self .pk_key ), item ) for item in self ]
173+ return [(getattr (item , self .pk_key ), item ) for item in self . data ]
162174
163175 def __eq__ (self , other ):
164176 data = other
177+ if hasattr (data , "data" ):
178+ data = getattr (data , "data" )
165179
166- if not isinstance (self , list ) or not isinstance (data , list ):
180+ if not isinstance (self . data , list ) or not isinstance (data , list ):
167181 return False
168182
169- if len (self ) == len (data ):
170- for (a , b ) in zip (self , data ):
183+ if len (self . data ) == len (data ):
184+ for (a , b ) in zip (self . data , data ):
171185 if isinstance (a , dict ):
172186 a_keys = a .keys ()
173187 if a .keys == b .keys ():
@@ -216,4 +230,4 @@ def val_match(obj):
216230 else :
217231 _filter = filter_lookup
218232
219- return self .__class__ (k for k in self if _filter (k ))
233+ return self .__class__ (data = [ k for k in self . data if _filter (k )] )
0 commit comments