1- """The classlist module. Contains the ClassList class, which defines a list containing instances of a particular
2- class.
3- """
1+ """The ClassList class, which defines a list containing instances of a particular class."""
42
53import collections
64import contextlib
@@ -24,18 +22,18 @@ class ClassList(collections.UserList, Generic[T]):
2422 attribute given in the ClassList's "name_field" attribute (the default is "name"), the ClassList will ensure that
2523 all objects within the ClassList have unique values for that attribute. It is then possible to use this attribute
2624 of an object in the .remove(), .count(), and .index() routines in place of the full object. Due to the requirement
27- of unique values of the name_field attribute, the multiplication operators __mul__, __rmul__, and __imul__ have
25+ of unique values of the `` name_field`` attribute, the multiplication operators __mul__, __rmul__, and __imul__ have
2826 been disabled, since they cannot allow for unique attribute values by definition.
2927
3028 We extend the UserList class to enable objects to be added and modified using just the keyword arguments, enable
31- the object name_field attribute to be used in place of the full object, and ensure all elements are of the
32- specified type, with unique name_field attributes defined.
29+ the object `` name_field`` attribute to be used in place of the full object, and ensure all elements are of the
30+ specified type, with unique `` name_field`` attributes defined.
3331
3432 Parameters
3533 ----------
3634 init_list : Sequence [T] or T, optional
3735 An instance, or list of instance(s), of the class to be used in this ClassList.
38- name_field : str, optional
36+ `` name_field`` : str, optional
3937 The field used to define unique objects in the ClassList (default is "name").
4038
4139 """
@@ -171,8 +169,9 @@ def __imul__(self, n: int) -> None:
171169 raise TypeError (f"unsupported operand type(s) for *=: '{ self .__class__ .__name__ } ' and '{ n .__class__ .__name__ } '" )
172170
173171 def append (self , obj : T = None , ** kwargs ) -> None :
174- """Append a new object to the ClassList using either the object itself, or keyword arguments to set attribute
175- values.
172+ """Append a new object to the ClassList.
173+
174+ This method can use the object itself, or can provide attribute values as keyword arguments for a new object.
176175
177176 Parameters
178177 ----------
@@ -184,7 +183,7 @@ def append(self, obj: T = None, **kwargs) -> None:
184183 Raises
185184 ------
186185 ValueError
187- Raised if the input arguments contain a name_field value already defined in the ClassList.
186+ Raised if the input arguments contain a `` name_field`` value already defined in the ClassList.
188187
189188 Warnings
190189 --------
@@ -216,8 +215,9 @@ def append(self, obj: T = None, **kwargs) -> None:
216215 self .data .append (self ._class_handle (** kwargs ))
217216
218217 def insert (self , index : int , obj : T = None , ** kwargs ) -> None :
219- """Insert a new object into the ClassList at a given index using either the object itself, or keyword arguments
220- to set attribute values.
218+ """Insert a new object at a given index.
219+
220+ This method can use the object itself, or can provide attribute values as keyword arguments for a new object.
221221
222222 Parameters
223223 ----------
@@ -231,7 +231,7 @@ def insert(self, index: int, obj: T = None, **kwargs) -> None:
231231 Raises
232232 ------
233233 ValueError
234- Raised if the input arguments contain a name_field value already defined in the ClassList.
234+ Raised if the input arguments contain a `` name_field`` value already defined in the ClassList.
235235
236236 Warnings
237237 --------
@@ -263,20 +263,25 @@ def insert(self, index: int, obj: T = None, **kwargs) -> None:
263263 self .data .insert (index , self ._class_handle (** kwargs ))
264264
265265 def remove (self , item : Union [T , str ]) -> None :
266- """Remove an object from the ClassList using either the object itself or its name_field value."""
266+ """Remove an object from the ClassList using either the object itself or its `` name_field`` value."""
267267 item = self ._get_item_from_name_field (item )
268268 self .data .remove (item )
269269
270270 def count (self , item : Union [T , str ]) -> int :
271- """Return the number of times an object appears in the ClassList using either the object itself or its
272- name_field value.
271+ """Return the number of times an object appears in the ClassList.
272+
273+ This method can use either the object itself or its ``name_field`` value.
274+
273275 """
274276 item = self ._get_item_from_name_field (item )
275277 return self .data .count (item )
276278
277279 def index (self , item : Union [T , str ], offset : bool = False , * args ) -> int :
278- """Return the index of a particular object in the ClassList using either the object itself or its
279- name_field value. If offset is specified, add one to the index. This is used to account for one-based indexing.
280+ """Return the index of a particular object in the ClassList.
281+
282+ This method can use either the object itself or its ``name_field`` value.
283+ If offset is specified, add one to the index. This is used to account for one-based indexing.
284+
280285 """
281286 item = self ._get_item_from_name_field (item )
282287 return self .data .index (item , * args ) + int (offset )
@@ -357,12 +362,12 @@ def __exit__(self, exctype, excinst, exctb):
357362 self ._class_handle .model_validate (self .data [index ])
358363
359364 def get_names (self ) -> list [str ]:
360- """Return a list of the values of the name_field attribute of each class object in the list.
365+ """Return a list of the values of the `` name_field`` attribute of each class object in the list.
361366
362367 Returns
363368 -------
364369 names : list [str]
365- The value of the name_field attribute of each object in the ClassList.
370+ The value of the `` name_field`` attribute of each object in the ClassList.
366371
367372 """
368373 return [getattr (model , self .name_field ) for model in self .data if hasattr (model , self .name_field )]
@@ -389,8 +394,7 @@ def get_all_matches(self, value: Any) -> list[tuple]:
389394 ]
390395
391396 def _validate_name_field (self , input_args : dict [str , Any ]) -> None :
392- """Raise a ValueError if the name_field attribute is passed as an object parameter, and its value is already
393- used within the ClassList.
397+ """Raise a ValueError if the user tries to add an object with a ``name_field`` already in the ClassList.
394398
395399 Parameters
396400 ----------
@@ -400,7 +404,7 @@ def _validate_name_field(self, input_args: dict[str, Any]) -> None:
400404 Raises
401405 ------
402406 ValueError
403- Raised if the input arguments contain a name_field value already defined in the ClassList.
407+ Raised if the input arguments contain a `` name_field`` value already defined in the ClassList.
404408
405409 """
406410 names = [name .lower () for name in self .get_names ()]
@@ -413,8 +417,7 @@ def _validate_name_field(self, input_args: dict[str, Any]) -> None:
413417 )
414418
415419 def _check_unique_name_fields (self , input_list : Sequence [T ]) -> None :
416- """Raise a ValueError if any value of the name_field attribute is used more than once in a list of class
417- objects.
420+ """Raise a ValueError if any value of the ``name_field`` attribute is repeated in a list of class objects.
418421
419422 Parameters
420423 ----------
@@ -470,17 +473,17 @@ def _check_unique_name_fields(self, input_list: Sequence[T]) -> None:
470473 )
471474
472475 def _check_classes (self , input_list : Sequence [T ]) -> None :
473- """Raise a ValueError if any object in a list of objects is not of the type specified by self._class_handle.
476+ """Raise a ValueError if any object in a list of objects is not of the type specified by `` self._class_handle`` .
474477
475478 Parameters
476479 ----------
477480 input_list : iterable
478- A list of instances of the class given in self._class_handle.
481+ A list of instances of the class given in `` self._class_handle`` .
479482
480483 Raises
481484 ------
482485 ValueError
483- Raised if the input list contains objects of any type other than that given in self._class_handle.
486+ If the input list contains objects of any type other than that given in `` self._class_handle`` .
484487
485488 """
486489 error_list = []
@@ -495,18 +498,18 @@ def _check_classes(self, input_list: Sequence[T]) -> None:
495498 )
496499
497500 def _get_item_from_name_field (self , value : Union [T , str ]) -> Union [T , str ]:
498- """Return the object with the given value of the name_field attribute in the ClassList.
501+ """Return the object with the given value of the `` name_field`` attribute in the ClassList.
499502
500503 Parameters
501504 ----------
502505 value : T or str
503- Either an object in the ClassList, or the value of the name_field attribute of an object in the ClassList.
506+ Either an object in the ClassList, or the value of the `` name_field`` for an object in the ClassList.
504507
505508 Returns
506509 -------
507510 instance : T or str
508- Either the object with the value of the name_field attribute given by value, or the input value if an
509- object with that value of the name_field attribute cannot be found.
511+ Either the object with the value of the `` name_field`` attribute given by value, or the input value if an
512+ object with that value of the `` name_field`` attribute cannot be found.
510513
511514 """
512515 try :
@@ -518,24 +521,27 @@ def _get_item_from_name_field(self, value: Union[T, str]) -> Union[T, str]:
518521
519522 @staticmethod
520523 def _determine_class_handle (input_list : Sequence [T ]):
521- """When inputting a sequence of object to a ClassList, the _class_handle should be set as the type of the
522- element which satisfies "issubclass" for all the other elements.
524+ """Determine the class handle from a sequence of objects.
525+
526+ The ``_class_handle`` of the sequence is the type of the first element in the sequence
527+ which is a subclass of all elements in the sequence. If no such element exists, the handle
528+ is set to be the type of the first element in the list.
523529
524530 Parameters
525531 ----------
526- input_list : Sequence [object ]
532+ input_list : Sequence[T ]
527533 A list of instances to populate the ClassList.
528534
529535 Returns
530536 -------
531537 class_handle : type
532- The type object of the element fulfilling the condition of satisfying "issubclass" for all of the other
533- elements.
538+ The type object of the first element which is a subcalss of all of the other
539+ elements, or the first element if no such element exists .
534540
535541 """
536- for this_element in input_list :
537- if all ([ issubclass (type (instance ), type (this_element )) for instance in input_list ] ):
538- class_handle = type (this_element )
542+ for element in input_list :
543+ if all (issubclass (type (instance ), type (element )) for instance in input_list ):
544+ class_handle = type (element )
539545 break
540546 else :
541547 class_handle = type (input_list [0 ])
0 commit comments