44import warnings
55from abc import ABC , abstractmethod
66from dataclasses import dataclass
7- from typing import TYPE_CHECKING , Any , Generic , List , Optional , Sequence , TypeVar , overload
8-
9- from typing_extensions import Self
7+ from itertools import islice
8+ from typing import (
9+ TYPE_CHECKING ,
10+ Any ,
11+ Generic ,
12+ Iterable ,
13+ List ,
14+ Optional ,
15+ Sequence ,
16+ TypeVar ,
17+ overload ,
18+ )
1019
1120if TYPE_CHECKING :
1221 import requests
@@ -101,14 +110,13 @@ def __init__(self, ctx: Context, path: str, uid: str = "guid"):
101110 self ._ctx = ctx
102111 self ._path = path
103112 self ._uid = uid
104- self ._cache = None
105113
106114 @abstractmethod
107115 def _create_instance (self , path : str , / , ** kwargs : Any ) -> T :
108116 """Create an instance of 'T'."""
109117 raise NotImplementedError ()
110118
111- def fetch (self , ** conditions ) -> List [T ]:
119+ def fetch (self , ** conditions ) -> Iterable [T ]:
112120 """Fetch the collection.
113121
114122 Fetches the collection directly from Connect. This operation does not effect the cache state.
@@ -122,61 +130,57 @@ def fetch(self, **conditions) -> List[T]:
122130 results = response .json ()
123131 return [self ._to_instance (result ) for result in results ]
124132
125- def reload (self ) -> Self :
126- """Reloads the collection from Connect.
127-
128- Returns
129- -------
130- Self
131- """
132- self ._cache = None
133- return self
134-
135133 def _to_instance (self , result : dict ) -> T :
136134 """Converts a result into an instance of T."""
137135 uid = result [self ._uid ]
138136 path = posixpath .join (self ._path , uid )
139137 return self ._create_instance (path , ** result )
140138
141- @property
142- def _data (self ) -> List [T ]:
143- """Get the collection.
144-
145- Fetches the collection from Connect and caches the result. Subsequent invocations return the cached results unless the cache is explicitly reset.
146-
147- Returns
148- -------
149- List[T]
150-
151- See Also
152- --------
153- cached
154- reload
155- """
156- if self ._cache is None :
157- self ._cache = self .fetch ()
158- return self ._cache
159-
160139 @overload
161140 def __getitem__ (self , index : int ) -> T : ...
162141
163142 @overload
164143 def __getitem__ (self , index : slice ) -> Sequence [T ]: ...
165144
166- def __getitem__ (self , index ):
167- return self ._data [index ]
145+ def __getitem__ (self , index ) -> Sequence [T ] | T :
146+ data = self .fetch ()
147+
148+ if isinstance (index , int ):
149+ if index < 0 :
150+ # Handle negative indexing
151+ data = list (data )
152+ return data [index ]
153+ for i , value in enumerate (data ):
154+ if i == index :
155+ return value
156+ raise KeyError (f"Index { index } is out of range." )
157+
158+ if isinstance (index , slice ):
159+ # Handle slicing with islice
160+ start = index .start or 0
161+ stop = index .stop
162+ step = index .step or 1
163+ if step == 0 :
164+ raise ValueError ("slice step cannot be zero" )
165+ return [
166+ value
167+ for i , value in enumerate (islice (data , start , stop ))
168+ if (i + start ) % step == 0
169+ ]
170+
171+ raise TypeError (f"Index must be int or slice, not { type (index ).__name__ } ." )
168172
169173 def __iter__ (self ):
170- return iter (self ._data )
174+ return iter (self .fetch () )
171175
172176 def __len__ (self ) -> int :
173- return len (self ._data )
177+ return len (list ( self .fetch ()) )
174178
175179 def __str__ (self ) -> str :
176- return str (self ._data )
180+ return str (list ( self .fetch ()) )
177181
178182 def __repr__ (self ) -> str :
179- return repr (self ._data )
183+ return repr (list ( self .fetch ()) )
180184
181185
182186class ActiveFinderMethods (ActiveSequence [T ], ABC ):
@@ -220,5 +224,5 @@ def find_by(self, **conditions) -> Optional[T]:
220224 Optional[T]
221225 The first record matching the conditions, or `None` if no match is found.
222226 """
223- collection = self .fetch ()
227+ collection = self .fetch (** conditions )
224228 return next ((v for v in collection if v .items () >= conditions .items ()), None )
0 commit comments