keithasaurus / koda-validate

Typesafe, Composable Validation
MIT License
112 stars 0 forks source link

Runtime Function Signature Validation #11

Closed keithasaurus closed 1 year ago

keithasaurus commented 1 year ago

Motivation

A natural extension of Predicates is to retain some vestige of them on validated types. Then we can do things like

def reverse_long_string(x: Annotated[str, MinLength(20)]) -> Annotated[str, MinLength(20)]:
    return x[::-1]

validator = StringValidator(MinLength(4))

match validator("abc123"):
     case Valid(s):
            reverse_long_string(s)  # type error! Not long enough
     case Invalid():
            ....

Implementation

Presumably this is accomplished through typing.Annotated types. It would change the way we use Annotated. Breaking?

I think a plugin would be needed for Mypy to accomplish this.

Questions

keithasaurus commented 1 year ago

Note that annotated-types is similar. Probably not exactly the same. Should look into

keithasaurus commented 1 year ago

Sounds like Annotated is not really supported by plugins yet. https://github.com/python/mypy/issues/12619.

For now, the path that might make the most sense is to allow:

@validate_signature
def some_func(a: int, b: Annotated[str, StringValidator(MinLength(20))]) -> str:
     ...

Where int becomes a regular IntValidator and the Annotated StringValidator is used for the second arg.

This requires a few changes, since presumably we want function signature checks to be exact (not coerced):