Skip to content
This repository has been archived by the owner on Mar 1, 2023. It is now read-only.

Add validation #12

Open
meatballs opened this issue Apr 23, 2021 · 6 comments
Open

Add validation #12

meatballs opened this issue Apr 23, 2021 · 6 comments
Labels
enhancement New feature or request

Comments

@meatballs
Copy link
Member

Similar to how this is done by attrs and/or pydantic.

@s-cork
Copy link

s-cork commented Apr 23, 2021

I really need to push meredydd to ok the class annotations in skulpt!

@meatballs
Copy link
Member Author

API for when validation occurs...

How about on_validation and on_validation attributes which can be set to callable?

@s-cork
Copy link

s-cork commented Apr 24, 2021

good question I don't know enough about the library so ignore any code that is totally ignorant

# from the docs
@model_type
class Book:
    title = Attribute()
    published_on = Attribute()
    author = Relationship(cls="Author")

fluent_python = Book.search(title="Fluent Python")[0]
fluent_python.title = "Fluent Python (Clear, Concise, and Effective Programming)"
fluent_python.save()

Could be - almost straight form the pydantic code

@model_type
class Book:
    title = Attribute()
    published_on = Attribute()
    author = Relationship(cls="Author")

    @validate('title')
    def author_must_contain_space(v):
        if ' ' not in v:
            raise ValueError('must contain a space')
        return v.title()

And the model could have some sort of validate method

fluent_python = Book.search(title="Fluent Python")[0]
fluent_python.title = "Fluent Python (Clear, Concise, and Effective Programming)"
try:
    fluent_python.validate() # loops over all the validators
    fluent_python.validate(key='title') # loops over all validators registered for title
except anvil_orm.ValidationError as e:
    print(e)
else:
    fluent_python.save()

The @Validate would just append a method to a default_dict(list) whose key is the attribute

calling .validate() would catch ValueErrors, AssertionErrors and TypeErrors and eventually raise a ValidationError after all validators were checked in a similar way to pydantic.

It could also potentially be some sort of context manager

with anvil_orm.validate(fluent_python) as v:
    if v is not None:
        pass
    else:
        print(v.errors) # there are errors
        print(v.errors['title'])
        

just jamming so ignore what doesn't make sense.

@meatballs
Copy link
Member Author

My only reservation about raising errors is what then has to happen on a bound component using write back. Catching those errors becomes tricky.

Instead, I was wondering about either triggering an event or publishing a message. I opted for a generic callback so that the user can do whatever they like.

I like the decorators, though!

@s-cork
Copy link

s-cork commented Apr 24, 2021

For a writeback in my head it would be something like

def on_validate(self, **event_args):
    try:
        self.item.validate()
   except ValidationError as e:
       self.author_error.text = e.errors['author']

And then you just have event_bindings for methods like lost_focus set to on_validate.

But again just throwing pasta

@meatballs
Copy link
Member Author

Having some time to have a crack at this properly would be nice!

@meatballs meatballs added the enhancement New feature or request label Jun 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants