5353 >>> d[1:4]
5454 SliceableDeque([2, 3, 4])
5555"""
56+
5657# pyright: reportIncompatibleMethodOverride=false
5758import abc
5859import collections
@@ -109,15 +110,16 @@ class CastedDictBase(types.Dict[KT, VT], abc.ABC):
109110 Sets the item in the dictionary, casting the key if a key cast
110111 callable is provided.
111112 """
113+
112114 _key_cast : KT_cast [KT ]
113115 _value_cast : VT_cast [VT ]
114116
115117 def __init__ (
116- self ,
117- key_cast : KT_cast [KT ] = None ,
118- value_cast : VT_cast [VT ] = None ,
119- * args : DictUpdateArgs [KT , VT ],
120- ** kwargs : VT ,
118+ self ,
119+ key_cast : KT_cast [KT ] = None ,
120+ value_cast : VT_cast [VT ] = None ,
121+ * args : DictUpdateArgs [KT , VT ],
122+ ** kwargs : VT ,
121123 ) -> None :
122124 """
123125 Initializes the CastedDictBase with optional key and value
@@ -138,10 +140,16 @@ def __init__(
138140 self .update (* args , ** kwargs )
139141
140142 def update (
141- self ,
142- * args : DictUpdateArgs [types .Any , types .Any ],
143- ** kwargs : types .Any
143+ self , * args : DictUpdateArgs [types .Any , types .Any ], ** kwargs : types .Any
144144 ) -> None :
145+ """
146+ Updates the dictionary with the given arguments.
147+
148+ Args:
149+ *args (DictUpdateArgs[types.Any, types.Any]): Arguments to update
150+ the dictionary.
151+ **kwargs (types.Any): Keyword arguments to update the dictionary.
152+ """
145153 if args :
146154 kwargs .update (* args )
147155
@@ -150,6 +158,14 @@ def update(
150158 self [key ] = value
151159
152160 def __setitem__ (self , key : types .Any , value : types .Any ) -> None :
161+ """
162+ Sets the item in the dictionary, casting the key if a key cast
163+ callable is provided.
164+
165+ Args:
166+ key (types.Any): The key to set in the dictionary.
167+ value (types.Any): The value to set in the dictionary.
168+ """
153169 if self ._key_cast is not None :
154170 key = self ._key_cast (key )
155171
@@ -246,12 +262,30 @@ class LazyCastedDict(CastedDictBase[KT, VT]):
246262 """
247263
248264 def __setitem__ (self , key : types .Any , value : types .Any ):
265+ """
266+ Sets the item in the dictionary, casting the key if a key cast
267+ callable is provided.
268+
269+ Args:
270+ key (types.Any): The key to set in the dictionary.
271+ value (types.Any): The value to set in the dictionary.
272+ """
249273 if self ._key_cast is not None :
250274 key = self ._key_cast (key )
251275
252276 super ().__setitem__ (key , value )
253277
254278 def __getitem__ (self , key : types .Any ) -> VT :
279+ """
280+ Gets the item from the dictionary, casting the value if a value cast
281+ callable is provided.
282+
283+ Args:
284+ key (types.Any): The key to get from the dictionary.
285+
286+ Returns:
287+ VT: The value from the dictionary.
288+ """
255289 if self ._key_cast is not None :
256290 key = self ._key_cast (key )
257291
@@ -263,15 +297,31 @@ def __getitem__(self, key: types.Any) -> VT:
263297 return value
264298
265299 def items ( # type: ignore
266- self ,
300+ self ,
267301 ) -> types .Generator [types .Tuple [KT , VT ], None , None ]:
302+ """
303+ Returns a generator of the dictionary's items, casting the values if a
304+ value cast callable is provided.
305+
306+ Yields:
307+ types.Generator[types.Tuple[KT, VT], None, None]: A generator of
308+ the dictionary's items.
309+ """
268310 if self ._value_cast is None :
269311 yield from super ().items ()
270312 else :
271313 for key , value in super ().items ():
272314 yield key , self ._value_cast (value )
273315
274316 def values (self ) -> types .Generator [VT , None , None ]: # type: ignore
317+ """
318+ Returns a generator of the dictionary's values, casting the values if a
319+ value cast callable is provided.
320+
321+ Yields:
322+ types.Generator[VT, None, None]: A generator of the dictionary's
323+ values.
324+ """
275325 if self ._value_cast is None :
276326 yield from super ().values ()
277327 else :
@@ -316,17 +366,36 @@ class UniqueList(types.List[HT]):
316366 _set : types .Set [HT ]
317367
318368 def __init__ (
319- self ,
320- * args : HT ,
321- on_duplicate : OnDuplicate = 'ignore' ,
369+ self ,
370+ * args : HT ,
371+ on_duplicate : OnDuplicate = 'ignore' ,
322372 ):
373+ """
374+ Initializes the UniqueList with optional duplicate handling behavior.
375+
376+ Args:
377+ *args (HT): Initial values for the list.
378+ on_duplicate (OnDuplicate, optional): Behavior on duplicates.
379+ Defaults to 'ignore'.
380+ """
323381 self .on_duplicate = on_duplicate
324382 self ._set = set ()
325383 super ().__init__ ()
326384 for arg in args :
327385 self .append (arg )
328386
329387 def insert (self , index : types .SupportsIndex , value : HT ) -> None :
388+ """
389+ Inserts a value at the specified index, ensuring uniqueness.
390+
391+ Args:
392+ index (types.SupportsIndex): The index to insert the value at.
393+ value (HT): The value to insert.
394+
395+ Raises:
396+ ValueError: If the value is a duplicate and `on_duplicate` is set
397+ to 'raise'.
398+ """
330399 if value in self ._set :
331400 if self .on_duplicate == 'raise' :
332401 raise ValueError (f'Duplicate value: { value } ' )
@@ -337,6 +406,16 @@ def insert(self, index: types.SupportsIndex, value: HT) -> None:
337406 super ().insert (index , value )
338407
339408 def append (self , value : HT ) -> None :
409+ """
410+ Appends a value to the list, ensuring uniqueness.
411+
412+ Args:
413+ value (HT): The value to append.
414+
415+ Raises:
416+ ValueError: If the value is a duplicate and `on_duplicate` is set
417+ to 'raise'.
418+ """
340419 if value in self ._set :
341420 if self .on_duplicate == 'raise' :
342421 raise ValueError (f'Duplicate value: { value } ' )
@@ -347,25 +426,45 @@ def append(self, value: HT) -> None:
347426 super ().append (value )
348427
349428 def __contains__ (self , item : HT ) -> bool : # type: ignore
429+ """
430+ Checks if the list contains the specified item.
431+
432+ Args:
433+ item (HT): The item to check for.
434+
435+ Returns:
436+ bool: True if the item is in the list, False otherwise.
437+ """
350438 return item in self ._set
351439
352440 @typing .overload
353441 def __setitem__ (
354- self , indices : types .SupportsIndex , values : HT
355- ) -> None :
356- ...
442+ self , indices : types .SupportsIndex , values : HT
443+ ) -> None : ...
357444
358445 @typing .overload
359446 def __setitem__ (
360- self , indices : slice , values : types .Iterable [HT ]
361- ) -> None :
362- ...
447+ self , indices : slice , values : types .Iterable [HT ]
448+ ) -> None : ...
363449
364450 def __setitem__ (
365- self ,
366- indices : types .Union [slice , types .SupportsIndex ],
367- values : types .Union [types .Iterable [HT ], HT ],
451+ self ,
452+ indices : types .Union [slice , types .SupportsIndex ],
453+ values : types .Union [types .Iterable [HT ], HT ],
368454 ) -> None :
455+ """
456+ Sets the item(s) at the specified index/indices, ensuring uniqueness.
457+
458+ Args:
459+ indices (types.Union[slice, types.SupportsIndex]): The index or
460+ slice to set the value(s) at.
461+ values (types.Union[types.Iterable[HT], HT]): The value(s) to set.
462+
463+ Raises:
464+ RuntimeError: If `on_duplicate` is 'ignore' and setting slices.
465+ ValueError: If the value(s) are duplicates and `on_duplicate` is
466+ set to 'raise'.
467+ """
369468 if isinstance (indices , slice ):
370469 values = types .cast (types .Iterable [HT ], values )
371470 if self .on_duplicate == 'ignore' :
@@ -394,8 +493,15 @@ def __setitem__(
394493 )
395494
396495 def __delitem__ (
397- self , index : types .Union [types .SupportsIndex , slice ]
496+ self , index : types .Union [types .SupportsIndex , slice ]
398497 ) -> None :
498+ """
499+ Deletes the item(s) at the specified index/indices.
500+
501+ Args:
502+ index (types.Union[types.SupportsIndex, slice]): The index or slice
503+ to delete the item(s) at.
504+ """
399505 if isinstance (index , slice ):
400506 for value in self [index ]:
401507 self ._set .remove (value )
@@ -408,28 +514,49 @@ def __delitem__(
408514# Type hinting `collections.deque` does not work consistently between Python
409515# runtime, mypy and pyright currently so we have to ignore the errors
410516class SliceableDeque (types .Generic [T ], collections .deque ): # type: ignore
517+ """
518+ A deque that supports slicing and enhanced equality checks.
519+
520+ Methods:
521+ __getitem__(index: types.Union[types.SupportsIndex, slice]) ->
522+ types.Union[T, 'SliceableDeque[T]']:
523+ Returns the item or slice at the given index.
524+ __eq__(other: types.Any) -> bool:
525+ Checks equality with another object, allowing for comparison with
526+ lists, tuples, and sets.
527+ pop(index: int = -1) -> T:
528+ Removes and returns the item at the given index. Only supports
529+ index 0 and the last index.
530+ """
531+
411532 @typing .overload
412- def __getitem__ (self , index : types .SupportsIndex ) -> T :
413- ...
533+ def __getitem__ (self , index : types .SupportsIndex ) -> T : ...
414534
415535 @typing .overload
416- def __getitem__ (self , index : slice ) -> 'SliceableDeque[T]' :
417- ...
536+ def __getitem__ (self , index : slice ) -> 'SliceableDeque[T]' : ...
418537
419538 def __getitem__ (
420- self , index : types .Union [types .SupportsIndex , slice ]
539+ self , index : types .Union [types .SupportsIndex , slice ]
421540 ) -> types .Union [T , 'SliceableDeque[T]' ]:
422541 """
423542 Return the item or slice at the given index.
424543
425- >>> d = SliceableDeque[int]([1, 2, 3, 4, 5])
426- >>> d[1:4]
427- SliceableDeque([2, 3, 4])
544+ Args:
545+ index (types.Union[types.SupportsIndex, slice]): The index or
546+ slice to retrieve.
428547
429- >>> d = SliceableDeque[str](['a', 'b', 'c'])
430- >>> d[-2:]
431- SliceableDeque(['b', 'c'])
548+ Returns:
549+ types.Union[T, 'SliceableDeque[T]']: The item or slice at the
550+ given index.
432551
552+ Examples:
553+ >>> d = SliceableDeque[int]([1, 2, 3, 4, 5])
554+ >>> d[1:4]
555+ SliceableDeque([2, 3, 4])
556+
557+ >>> d = SliceableDeque[str](['a', 'b', 'c'])
558+ >>> d[-2:]
559+ SliceableDeque(['b', 'c'])
433560 """
434561 if isinstance (index , slice ):
435562 start , stop , step = index .indices (len (self ))
@@ -438,7 +565,16 @@ def __getitem__(
438565 return types .cast (T , super ().__getitem__ (index ))
439566
440567 def __eq__ (self , other : types .Any ) -> bool :
441- # Allow for comparison with a list or tuple
568+ """
569+ Checks equality with another object, allowing for comparison with
570+ lists, tuples, and sets.
571+
572+ Args:
573+ other (types.Any): The object to compare with.
574+
575+ Returns:
576+ bool: True if the objects are equal, False otherwise.
577+ """
442578 if isinstance (other , list ):
443579 return list (self ) == other
444580 elif isinstance (other , tuple ):
@@ -449,8 +585,27 @@ def __eq__(self, other: types.Any) -> bool:
449585 return super ().__eq__ (other )
450586
451587 def pop (self , index : int = - 1 ) -> T :
452- # We need to allow for an index but a deque only allows the removal of
453- # the first or last item.
588+ """
589+ Removes and returns the item at the given index. Only supports index 0
590+ and the last index.
591+
592+ Args:
593+ index (int, optional): The index of the item to remove. Defaults to
594+ -1.
595+
596+ Returns:
597+ T: The removed item.
598+
599+ Raises:
600+ IndexError: If the index is not 0 or the last index.
601+
602+ Examples:
603+ >>> d = SliceableDeque([1, 2, 3])
604+ >>> d.pop(0)
605+ 1
606+ >>> d.pop()
607+ 3
608+ """
454609 if index == 0 :
455610 return typing .cast (T , super ().popleft ())
456611 elif index in {- 1 , len (self ) - 1 }:
0 commit comments