def with_sequence_item( attr_spec: Attr, self, _item: Any = MISSING, *, _index: Any = MISSING, _insert: bool = False, _inplace: bool = False, _if: bool = True, **attrs, ) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=(attr_spec.get_collection_mutator(self, inplace=_inplace).add_item( item=_item, attrs=attrs, value_or_index=_index, by_index=True, insert=_insert, ).collection), inplace=_inplace, type_check=False, )
def transform_sequence_item( attr_spec: Attr, self, _value_or_index: Any, _transform: Callable[[Any], Any], *, _by_index: Any = MISSING, _inplace: bool = False, _if: bool = True, **attr_transforms: Dict[str, Callable[[Any], Any]], ) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=(attr_spec.get_collection_mutator( self, inplace=_inplace).transform_item( value_or_index=_value_or_index, transform=_transform, by_index=_by_index, attr_transforms=attr_transforms, ).collection), inplace=_inplace, type_check=False, )
def prepare_attr_value(attr_spec: Attr, instance: Any, value: Any, attrs: Optional[Dict[str, Any]] = None) -> Any: """ Prepare an incoming `value` for assignment to the attribute associated with `attr_spec`. This can be called independently, such as in `spec_property`, to ensure that dynamically generated values are consistent with the operations of `with_<attr>`. Args: attr_spec: The attribute specification for which the value is being prepared. instance: The spec-class instance for which the value is being prepared. value: The value to be prepared. attrs: Optional arguments to pass to the constructor/set on the value in `mutate_value`. Returns: The prepared value. """ value = mutate_value( old_value=MISSING, new_value=value, prepare=(functools.partial(attr_spec.prepare, instance) if attr_spec.prepare else None), constructor=attr_spec.type, attrs=attrs, ) if attr_spec.is_collection: value = (attr_spec.get_collection_mutator( instance=instance, collection=value).prepare().collection) return value
def update_sequence_item( attr_spec: Attr, self, _value_or_index: Any, _new_item: Any, *, _by_index: Any = MISSING, _inplace: bool = False, _if: bool = True, **attrs: Dict[str, Any], ) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=(attr_spec.get_collection_mutator( self, inplace=_inplace).add_item( item=_new_item, attrs=attrs, value_or_index=_value_or_index, by_index=_by_index, replace=False, ).collection), inplace=_inplace, type_check=False, )
def build_method(self) -> Callable: spec_class_key = self.spec_cls.__spec_class__.key key_default = inspect.Parameter.empty if spec_class_key: spec_class_key_spec = ( self.spec_cls.__spec_class__.attrs.get(spec_class_key) or Attr()) # If the key has a default, don't require it to be set during # construction. key_default = (MISSING if spec_class_key_spec.has_default else inspect.Parameter.empty) return (MethodBuilder( "__init__", functools.partial(self.init, self.spec_cls) ).with_preamble( f"Initialise this `{self.spec_cls.__name__}` instance." ).with_arg( spec_class_key, desc=f"The value to use for the `{spec_class_key}` key attribute.", default=key_default, annotation=self.spec_cls.__spec_class__.annotations.get( spec_class_key), only_if=spec_class_key, ).with_spec_attrs_for( self.spec_cls, desc_template=f"Initial value for `{self.spec_cls.__name__}.{{}}`.", ).build())
def with_mapping_item( attr_spec: Attr, self, _key: Any = None, _value: Any = None, *, _inplace: bool = False, _if: bool = True, **attrs, ) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=( attr_spec.get_collection_mutator(self, inplace=_inplace) .add_item( _key, _value, attrs=attrs, ) .collection ), inplace=_inplace, type_check=False, )
def transform_mapping_item( attr_spec: Attr, self, _key: Any, _transform: Callable[[Any], Any], *, _inplace: bool = False, _if: bool = True, **attr_transforms: Dict[str, Callable[[Any], Any]], ) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=( attr_spec.get_collection_mutator(self, inplace=_inplace) .transform_item( key=_key, transform=_transform, attr_transforms=attr_transforms, ) .collection ), inplace=_inplace, type_check=False, )
def update_mapping_item( attr_spec: Attr, self, _key: Any, _new_item: Any, *, _inplace: bool = False, _if: bool = True, **attrs: Dict[str, Any], ) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=( attr_spec.get_collection_mutator(self, inplace=_inplace) .add_item( key=_key, value=_new_item, attrs=attrs, replace=False, require_pre_existent=True, ) .collection ), inplace=_inplace, type_check=False, )
def without_set_item(attr_spec: Attr, self, _item: Any, *, _inplace: bool = False, _if: bool = True) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=(attr_spec.get_collection_mutator( self, inplace=_inplace).remove_item(_item).collection), inplace=_inplace, type_check=False, )
def without_sequence_item( attr_spec: Attr, self, _value_or_index: Any, *, _by_index: Any = MISSING, _inplace: bool = False, _if: bool = True, ) -> Any: if not _if: return self return mutate_attr( obj=self, attr=attr_spec.name, value=(attr_spec.get_collection_mutator( self, inplace=_inplace).remove_item( value_or_index=_value_or_index, by_index=_by_index, ).collection), inplace=_inplace, type_check=False, )