Ejemplo n.º 1
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,
     )
Ejemplo n.º 2
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,
     )
Ejemplo n.º 3
0
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
Ejemplo n.º 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,
     )
Ejemplo n.º 5
0
    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())
Ejemplo n.º 6
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,
     )
Ejemplo n.º 7
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,
     )
Ejemplo n.º 8
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,
     )
Ejemplo n.º 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,
     )
Ejemplo n.º 10
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,
     )