Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide an auto-fields feature like attrs/pydantic for python 3.6+ #55

Closed
smarie opened this issue Dec 12, 2019 · 0 comments
Closed

Provide an auto-fields feature like attrs/pydantic for python 3.6+ #55

smarie opened this issue Dec 12, 2019 · 0 comments

Comments

@smarie
Copy link
Owner

smarie commented Dec 12, 2019

the idea came from implementing pydantic's benchmark today (by the way, early results show that cythonized version of pyfields is better than pydantic and non-cythonized is equivalent).

It ended up being quite heavy to implement the model's benchmark:

class Model:
        __init__ = make_init()
        id: int = field(check_type=True)
        client_name: str = field(check_type=True,
                                 validators={'max length is 255': lambda s: len(s) <= 255})   # constr(max_length=255)
        sort_index: float = field(check_type=True)
        # client_email: EmailStr = None
        client_phone: str = field(check_type=True, default=None,
                                  validators={'max length is 255': lambda s: len(s) <= 255})  # constr(max_length=255)

        class Location:
            __init__ = make_init()
            latitude: float = field(check_type=True, default=None)
            longitude: float = field(check_type=True, default=None)

        location: Location = field(check_type=True, default=None, converters={dict: lambda d: Model.Location(**d)})

        contractor: int = field(check_type=True, default=None,
                                converters={str: lambda s: int(s)},
                                validators={'positive int': lambda x: x >= 0})  # PositiveInt
        upstream_http_referrer: str = field(check_type=True, default=None,
                                            validators={'max length is 1023': lambda s: len(s) <= 1023})  # constr(max_length=1023)
        grecaptcha_response: str = field(check_type=True,
                                         validators={'length should be between 20 and 1000': lambda s: 20 <= len(s) <= 1000})  # constr(min_length=20, max_length=1000)
        last_updated: datetime = field(check_type=True, default=None,
                                       converters={str: lambda isostring: parse_datetime_iso(isostring)})

        class Skill:
            __init__ = make_init()
            subject: str = field(check_type=True, )
            subject_id: int = field(check_type=True, )
            category: str = field(check_type=True, )
            qual_level: str = field(check_type=True, )
            qual_level_id: int = field(check_type=True, )
            qual_level_ranking: float = field(check_type=True, default=0)

        skills: List[Skill] = field(check_type=True, default_factory=copy_value([]),
                                    converters={Iterable: lambda l: [Model.Skill(**o) if isinstance(o, dict) else o for o in l]})

    self.model = Model

This could be simplified by a few things:

  • the main is that in python 3.6+, it is possible to create a new decorator @autofields, that one would use to say "every member in this class that is not a function is a field and its value if provided is its default value"

  • also there could maybe be a way to automatically add converters from dict to classes decorated with @autofields (calling <type>(**dct))

@smarie smarie closed this as completed in 9602c0e Dec 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant