jcrist / msgspec

A fast serialization and validation library, with builtin support for JSON, MessagePack, YAML, and TOML
https://jcristharif.com/msgspec/
BSD 3-Clause "New" or "Revised" License
2.46k stars 76 forks source link

How to validate Annotation on __init__ #776

Open raidgar98 opened 3 days ago

raidgar98 commented 3 days ago

Question

I have example like this:

AccountName = Annotated[str, ms.Meta(min_length=3, max_length=16, pattern="^([a-z]+)$")]

but this does not throw any error:

AccountName("0")

how to force validation? I thought about something like this:

class AccountName(Annotated[str, ms.Meta(min_length=3, max_length=16, pattern="^([a-z]+)$")]):
    def __init__(self, value: Any) -> None:
        super().__init__(value)
        msgspec.validate(self)  # something like this

or

AccountNameImpl = Annotated[str, ms.Meta(min_length=3, max_length=16, pattern="^([a-z]+)$")]

def AccountName(value: str) -> AccountNameImpl:
    result = AccountNameImpl(value)
    msgspec.validate(result)
    # msgspec.json.encode(result)  # i don't want it to validate like this
    return result

But i can't find validate method and because of large amount of objects that are created in my project i don't want to encode to validate all the time. If dedicated method was exposed i can deal with this

jack-mcivor commented 3 days ago
msgspec.convert("0", type=AccountName)

However in general the idea is that you can rely on a type checker to perform validation when types can be statically determined. This is a really good read https://jcristharif.com/msgspec/structs.html#type-validation

See also https://jcristharif.com/msgspec/converters.html for info on the convert method

jack-mcivor commented 3 days ago

There is an existing discussion here https://github.com/jcrist/msgspec/issues/513