示例#1
0
 def __setattr__(self, attr, value, force=False):
     attr_spec = self.__spec_class__.attrs.get(attr)
     if attr_spec:
         WithAttrMethod.with_attr(attr_spec, self, value, _inplace=True)
         return
     mutate_attr(self,
                 attr=attr,
                 value=value,
                 inplace=True,
                 force=force)
示例#2
0
 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,
     )
示例#3
0
 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,
     )
示例#4
0
 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,
     )
示例#5
0
 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,
     )
示例#6
0
 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,
     )
示例#7
0
 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 test_mutate_attr():
    @spec_class
    class Item:
        attr: str

    item = Item()

    with pytest.raises(
            AttributeError,
            match=r"`Item\.attr` has not yet been assigned a value\."):
        item.attr
    with pytest.raises(
            AttributeError,
            match=r"`Item\.attr` has not yet been assigned a value\."):
        mutate_attr(item, "attr", MISSING).attr
    assert mutate_attr(item, "attr", "string") is not item
    assert mutate_attr(item, "attr", "string").attr == "string"

    with pytest.raises(
            TypeError,
            match="Attempt to set `Item.attr` with an invalid type"):
        assert mutate_attr(item, "attr", 1)
示例#9
0
 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,
     )
示例#10
0
    def with_attr(
        attr_spec: Attr,
        self,
        _new_value=MISSING,
        *,
        _inplace: bool = False,
        _if: bool = True,
        **attrs,
    ):
        if not _if:
            return self

        return mutate_attr(
            obj=self,
            attr=attr_spec.name,
            value=prepare_attr_value(attr_spec=attr_spec,
                                     instance=self,
                                     value=_new_value,
                                     attrs=attrs),
            inplace=_inplace,
        )
示例#11
0
 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,
     )
示例#12
0
        def __delattr__(self, attr, force=False):
            if self.__spec_class__.frozen:
                raise FrozenInstanceError(
                    f"Cannot mutate attribute `{attr}` of frozen spec class `{self.__class__.__name__}`."
                )

            attr_spec = self.__spec_class__.attrs.get(attr)

            if (force or not attr_spec or attr_spec.default is MISSING
                    or attr_spec.is_masked):
                self.__delattr__.__raw__(self, attr)
                invalidate_attrs(self, attr)
                return None

            return mutate_attr(
                obj=self,
                attr=attr,
                value=protect_via_deepcopy(
                    attr_spec.default),  # handle default factory
                inplace=True,
                force=True,
            )