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.44k stars 75 forks source link

Please consider not restricting `Union` to one type. #582

Open wikiped opened 1 year ago

wikiped commented 1 year ago

Description

Suppose that an int field needs to be bound to some intervals:

from typing import Annotated
import msgspec as ms

LowerBounds = Annotated[int, ms.Meta(ge=-10, le=-1)]
UpperBounds = Annotated[int, ms.Meta(ge=1, le=10)]

class T(ms.Struct):
    n: LowerBounds | UpperBounds

As the docs state:

Unions may contain at most one type that encodes to an integer (int, enum.IntEnum)

the following will then expectedly fail:

ms.json.decode('{"n":-1}', type=T)
# msgspec.ValidationError: Expected `int` >= 1 - at `$.n`

Please consider lifting this restriction.

aspizu commented 1 year ago

I too require this feature for the following data type:

class Ok(Generic[A]):
    def __init__(self, value: A):
        self.value = value

    def to_json(self) -> JSON:
        return {"ok": self.value}

    def __bool__(self):
        return True

class Err(Generic[A]):
    def __init__(self, value: A):
        self.value = value

    def to_json(self) -> JSON:
        return {"err": self.value}

    def __bool__(self):
        return False

Result = Ok[A] | Err[B]