Skip to content

Commit

Permalink
add mutation feature
Browse files Browse the repository at this point in the history
  • Loading branch information
ypankovych committed May 20, 2021
1 parent 24d186a commit 02b44c6
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 5 deletions.
9 changes: 6 additions & 3 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Lets create ``data.json`` as following:
Now lets load it:

.. code-block:: python
:emphasize-lines: 44
:emphasize-lines: 47
from pankoff.base import Container
from pankoff.combinator import combine
Expand All @@ -30,6 +30,9 @@ Now lets load it:
self.amount = amount
self.currency = currency
def mutate(self, instance, value):
return f"{instance.name} salary is: {value}"
def validate(self, instance, value):
amount, currency = value.split()
if int(amount) != self.amount or currency != self.currency:
Expand All @@ -54,14 +57,14 @@ Now lets load it:
)
position = Predicate(
# NOTE: we can use `salary` field at this point
predicate=lambda instance, value: value == "Manager" and instance.salary == "100 USD",
predicate=lambda instance, value: value == "Manager" and "100 USD" in instance.salary,
error_message="Invalid value for {field_name}, person got into wrong position: {value}"
)
payment = Alias("salary")
job_desc = LazyLoad(factory=lambda instance: f"{instance.position} at {instance.office}")
person = Person.from_path("data.json")
print(person) # Person(name=Yaroslav, age=22, salary=100 USD, office=Central Office, position=Manager, job_desc=Manager at Central Office)
print(person) # Person(name=Yaroslav, age=22, salary=Yaroslav salary is: 100 USD, office=Central Office, position=Manager, job_desc=Manager at Central Office)
Trying invalid data. Change your ``data.json``:

Expand Down
7 changes: 6 additions & 1 deletion docs/source/validators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,16 @@ You can define you ows validator by subclassing ``BaseValidator``.
>>> class EnumValidator(BaseValidator):
... def __setup__(self, allowed_values):
... self.allowed_values = allowed_values
... def mutate(self, instance, value):
... return f"Mutated value: {value}"
... def validate(self, instance, value):
... if value not in self.allowed_values:
... raise ValidationError(
... f"Invalid value in field {self.field_name}, value should be in {self.allowed_values} "
... f"got {value}"
... )

It is required for validators to define ``validate``, but ``__setup__`` is optional.
It is required for validators to define ``validate``, but ``__setup__`` and `mutate` is optional.

You can use ``mutate`` to modify returned value when its being accessed. It won't be cached, ``mutate`` is re-calculated on every
attribute access.
10 changes: 10 additions & 0 deletions pankoff/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,19 @@ def __set__(self, instance, value, __mro__=None, errors=None):
raise
super(base, self).__set__(instance, value, __mro__=__mro__, errors=errors)

def __get__(self, instance, owner):
value = vars(instance)[self.field_name]
mutated = self.mutate(instance, value)
if mutated is NotImplemented:
mutated = value
return mutated

def __setup__(self, *args, **kwargs):
return NotImplemented

@abstractmethod
def validate(self, instance, value):
return NotImplemented

def mutate(self, instance, value):
return NotImplemented
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
from distutils.core import setup

version = "13.0"
version = "14.0"
setup(
name='pankoff',
packages=['pankoff'],
Expand Down

0 comments on commit 02b44c6

Please sign in to comment.