pestifer.core.baseobj module

pydantic.BaseModel objects with attribute controls

The BaseObj class provides a framework for creating objects with controlled attributes. It is an abstract class that requires subclasses to implement the _adapt() static method that returns a dict that sets attribute values. It also provides a number of utility methods for creating objects from various input types, validating attributes, and comparing objects.

Any subclass that defines Field objects will automatically have their attributes validated according to the rules specified in the BaseObj class. Subclasses can also define their own ClassVar attributes that are outside the control logic of BaseObj.

Two types of Fields are supported:

  1. Required fields, which must be present in the input data and are validated by Pydantic.

  2. Optional fields, which are not required but can be included in the input data, and have default values defined.

Pairs of optional fields can be defined as mutually exclusive, meaning that if one field is present, the other cannot be. This is useful for cases where only one of a set of related fields should be specified.

Any field can also be constrained to a set of allowed values, and dependencies can be defined such that if one field is present, another must also be present.

Any field can also be assigned a list of dependent fields depending on its value, which must also be present if the field value is set. This allows for complex relationships between fields to be defined.

Any field can also be declared as ignored when comparing objects, meaning that it will not be included in the comparison logic.

class pestifer.core.baseobj.BaseObj(*args)[source]

Bases: BaseModel

assign_obj_to_attr(attr, objList, **matchattr)[source]

Given the dictionary matchattr that maps attribute names in self to corresponding attribute names in the objects in objList, pluck out the element in objList that matches self and assign it to the attr attribute of self.

Parameters:
  • attr (str) – attribute name that will receive the matched object from objList

  • objList (list) – list of objects that is searched

  • matchattr (dict) – attribute_in_searched_objects:attribute_in_self

copy(deep=False) Self[source]

Uses pydantic.BaseModel.model_copy() to create a copy of the instance. If deep is True, performs a deep copy of nested objects.

copy_attr(recv_attr, src_attr)[source]

Simple attribute copier

Parameters:
  • recv_attr (str) – name of receiver attribute; must exist

  • src_attr (str) – name of source attribute; must exist

dump()[source]

Simple dump of this item’s __dict__ in YAML format.

Returns:

yaml-format dump of calling instance

Return type:

str

inlist(a_list)[source]

Checks if the calling instance is a member of a_list This is a simple membership test that checks if the calling instance is equal to any element in a_list.

Parameters:

a_list (list) – the list of objects checked to see if object is a member

Returns:

True if calling instance is a member of a_list

Return type:

bool

map_attr(mapped_attr, key_attr, map)[source]

Simple cross-attribute mapper.

Parameters:
  • mapped_attr (str) – name of attribute to which the mapping result will be applied

  • key_attr (str) – name of attribute whose value is mapped

  • map (dict) – the map

Returns:

This method modifies the calling instance in place. It sets the mapped_attr to the value from the map corresponding to the key_attr’s value. If the key_attr’s value is not in the map, it does nothing.

Return type:

None

model_config = {'arbitrary_types_allowed': True, 'extra': 'forbid', 'frozen': False}

Configuration for pydantic.BaseModel.

property objcat
serialize() dict[str, Any][source]
set(shallow=False, **fields)[source]

Sets the values of the calling instance’s attributes to the values in fields. If shallow is False, and if there are nested objects, their attributes will also be set. If shallow is True, only the attributes of the calling instance will be set.

set_nested(**fields)[source]

Recursively sets attributes of nested BaseObj instances. This method is called by set() when shallow is False.

strhash(fields: list[str] | None = None, sep: str = '-', digest: str | None = None, exclude_none: bool = True, exclude_ignored: bool = True) str | bytes[source]

Generate a hash-like string from selected fields in the model.

Parameters:
  • fields (list of field names to include; if None, include all.)

  • sep (string separator for components (default: "-"))

  • digest (optional name of hashlib algorithm to use ("md5", "sha1", "sha256", etc.))

  • exclude_none (if True, skip fields with value None)

  • exclude_ignored (if True, exclude fields in _ignore_fields)

Returns:

Joined string or digest string (hex or binary, depending on digest)

Return type:

str or bytes

swap_attr(attr1, attr2)[source]

Simple attribute value swapper

Parameters:
  • attr1 (str) – name of first attribute in pair to swap

  • attr2 (str) – name of second attribute in pair to swap

update_attr_from_obj_attr(attr, obj_attr, attr_of_obj_attr)[source]

Update an attribute of self from an attribute of one of self’s object attributes.

Parameters:
  • attr (str) – attribute name of self that will be set to value of self.obj_attr.attr_of_obj_attr

  • obj_attr (str) – name of object attribute from which the attribute value is taken

  • attr_of_obj_attr (str) – name of attribute in obj_attr that is set to attr of caller

update_attr_from_objlist_elem_attr(attr, objlist_attr, index_of_obj_in_objlist_attr, attr_of_obj_attr)[source]

Set value of caller’s attribute from an attribute of an object in a list of objects

Parameters:
  • attr (str) – attribute name of self that will be set to value of self.objlist_attr[index_of_obj_in_objlist_attr].attr_of_obj_attr

  • objlist_attr (str) – name of the caller’s attribute that is a list of objects

  • index_of_obj_in_objlist_attr (int) – index of the object in the list

  • attr_of_obj_attr (str) – name of the attribute in the object that is set to attr of caller

weak_lt(other: object, attr=[]) bool[source]

Weak less than comparison that only checks fields listed in the attr parameter.

wildmatch(**fields) bool[source]

Check if the object matches any of the provided fields with wildcards. This allows for substring matching in the field names.

class pestifer.core.baseobj.BaseObjList(initlist: Iterable[T] = ())[source]

Bases: UserList[T], Generic[T]

append(item: BaseObj) None[source]

S.append(value) – append value to the end of the sequence

assign_objs_to_attr(attr: str, objList: BaseObjList, **matchattr) BaseObjList[source]

Assigns the single object from objList whose attributes match the matchattr dict to the calling instances attr attribute, but only if the result of the match-search is valid, otherwise assign None to attr

Parameters:
  • attr (str) – attribute name

  • objList (list) – list of objects that is searched

  • matchattr (dict) – attribute:values used in searching the list of objects

binnify(fields: list[str] = []) dict[str, BaseObjList][source]

Simple binning of all elements by unique hashes of values of fields

Parameters:

fields (list) – attribute names used to build the hash to test for uniqueness

Returns:

lists of items for each unique key

Return type:

dict

abstractmethod describe() str[source]

Abstract method to describe the contents of the BaseObjList. Subclasses should implement this method to provide a meaningful description.

static dict_to_condition(condition_dict: dict[str, Callable[[BaseObj], bool]], conjunction: str = 'and') Callable[[BaseObj], bool][source]

Converts a dictionary of conditions into a lambda function. The dictionary keys are attribute names, and the values are the conditions.

Returns a callable function that can be used in the filter method.

extend(other: Iterable[BaseObj]) None[source]

S.extend(iterable) – extend sequence by appending elements from the iterable

filter(func: Callable[[BaseObj], bool]) BaseObjList[source]

Filters the list of BaseObj instances based on a provided function.

Parameters:

func (Callable[[BaseObj], bool]) – A function that takes a BaseObj instance and returns True if it should be included in the filtered list.

Returns:

A new BaseObjList containing only the objects for which func returned True.

Return type:

BaseObjList

get(func: Callable[[BaseObj], bool]) BaseObj | BaseObjList | None[source]

Special implementation of filter that returns a single object if there is only one match; if there are multiple matches, all are returned in a list; if there are no matches, None is returned.

give_item(item: BaseObj, target_list: BaseObjList) bool[source]

Transfer an item from this list to another BaseObjList.

Parameters:
  • item (BaseObj) – The item to transfer.

  • target_list (BaseObjList) – The list to transfer the item to.

Returns:

True if the transfer was successful, False otherwise.

Return type:

bool

ifilter(func: Callable[[BaseObj], bool]) list[int][source]

Filters the list of BaseObj instances based on a provided function and returns the list of indices for items passing the filter

Parameters:

func (Callable[[BaseObj], bool]) – A function that takes a BaseObj instance and returns True if it should be included in the filtered list.

Returns:

A new BaseObjList containing only the objects for which func returned True.

Return type:

BaseObjList

iget(func: Callable[[BaseObj], bool]) int | list[int] | None[source]

Special implementation of ifilter that returns the index of a single index if there is only one match; if there are multiple matching indices, all are returned in a list; if there are no matches, None is returned.

insert(index: int, item: BaseObj) None[source]

S.insert(index, value) – insert value before index

map_attr(mapped_attr: str, key_attr: str, map: dict) None[source]

Simple cross-attribute mapper.

Parameters:
  • mapped_attr (str) – name of attribute to which the mapping result will be applied

  • key_attr (str) – name of attribute whose value is mapped

  • map (dict) – the map

Returns:

This method modifies the calling instance in place. It sets the mapped_attr to the value from the map corresponding to the key_attr’s value. If the key_attr’s value is not in the map, it does nothing.

Return type:

None

prune_exclusions(exclude_func: Callable[[BaseObj], bool]) BaseObjList[source]

Prune elements from the calling instance based on a custom exclusion function.

Parameters:

exclude_func (Callable[[BaseObj], bool]) – A function that takes a BaseObj and returns True if it should be excluded.

Returns:

items removed from calling instance

Return type:

BaseObjList

puniq(fields: list[str] = []) bool[source]

Simple test that all elements of self are unique among fields

Parameters:

fields (list, optional) – attribute names used to build the hash to test for uniqueness

Returns:

bool

Return type:

True if all elements are unique

puniquify(attrs: list[str] = [], stash_attr_name: str = 'ORIGINAL_ATTRIBUTES') None[source]

Systematic attribute altering to make all elements unique

There may be a set of attributes for which no two elements may have the exact same set of respective values. This method scans the calling instance for such collisions and, if any is found, it adds one to the value of the attribute named in the first element of the ‘fields’ list (assumes this attribute is numeric!). This could lead to other collisions so multiple passes through the calling instance are made until there are no more collisions. Each such value change results in storing the original values in a new attribute.

Parameters:
  • fields (list, optional) – attribute names used to build the hash to test for uniqueness; if unset, all attributes are used

  • stash_attr_name (str, optional) – name given to a new dict attribute used to store all original attribute name:value pairs

remove_and_return(item: BaseObj) BaseObj | None[source]

Remove an item from the list and return it.

Parameters:

item (BaseObj) – The item to remove from the list.

Returns:

The removed item if it was found, otherwise None.

Return type:

BaseObj | None

remove_duplicates(fields: list[str] = []) None[source]

Removes duplicates from the calling instance The duplicates are determined by the hash of the values of the attributes named in the fields list.

Parameters:

fields (list, optional) – attribute names used to build the hash to test for uniqueness; if unset, all attributes are used

remove_instance(obj_to_remove: BaseObj)[source]

Remove the exact instance obj_to_remove from the list, by checking identity (not equality), avoiding __eq__ overhead. Raises ValueError if not found.

set(shallow=False, **fields)[source]

Element attribute-setter

Parameters:

fields (dict) – attribute-name:value pairs used to set the attributes of the calling instance

sort(by=None, reverse=False)[source]

ObjList sort function, a simple override of UserList.sort()

Parameters:
  • by (list, optional) – names of attributes used to execute __lt__ comparisons between elements of calling instance

  • reverse (bool, optional) – if true, reverse the sense of the sort

take_item(item: BaseObj, source_list: BaseObjList) bool[source]

Take an item from another BaseObjList and add it to this list.

Parameters:
  • item (BaseObj) – The item to take.

  • source_list (BaseObjList) – The list to take the item from.

Returns:

True if the transfer was successful, False otherwise.

Return type:

bool

uniqattrs(attrs: list[str] = [], with_counts: bool = False) dict[str, list][source]

Generates a dictionary of list of unique values for each attribute

Parameters:
  • attrs (list) – names of attributes for which uniqueness is requested

  • with_counts (bool) – if true, include the counts of occurences of each unique value such that each dictionary value is now a list of tuples, each of which is a concatentation of the unique value the count of its occurence among all elements in the calling instance

Returns:

lists of unique values for each attribute key, or, if with_counts is true, list of (value,count)

Return type:

dict

update_attr_from_obj_attr(attr: str, obj_attr: str, attr_of_obj_attr: str) None[source]

Set value of attributes of all elements of caller from another attribute of a separate object

Parameters:
  • attr (str) – attribute name

  • obj_attr (str) – name of object attribute from which the attribute value is taken

  • attr_of_obj_attr (str) – name of attribute in obj_attr that is set to attr of caller

update_attr_from_objlist_elem_attr(attr: str, objlist_attr: str, index_of_obj_in_objlist_attr: int, attr_of_obj_attr: str) None[source]

Set value of caller’s attribute from an attribute of an object in a list of objects

Parameters:
  • attr (str) – attribute name to be updated

  • objlist_attr (str) – name of the caller’s attribute that is a list of objects

  • index_of_obj_in_objlist_attr (int) – index of the object in the list

  • attr_of_obj_attr (str) – name of the attribute in the object that is set to attr of caller

classmethod validate(v)[source]
class pestifer.core.baseobj.GenericListMeta(name, bases, namespace, **kwargs)[source]

Bases: ABCMeta

Metaclass for abstract BaseObjList to handle generic type arguments.

A subclass of BaseObjList must be declared as class MyList(BaseObjList[MyType]) where MyType is a subclass of BaseObj.

Ultimately, this enables subclasses of BaseObj to have Fields that are subclasses of BaseObjList. We need this because certain objects when put into lists acquire new attributes that are not present in the original object.