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

Support integer Struct tags #135

Merged
merged 1 commit into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions docs/source/structs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,12 @@ A struct's tagging configuration is determined as follows.
a union.

- If a struct is tagged, ``tag`` defaults to the class name (e.g. ``"Get"``) if
not provided or inherited. This can be overridden by passing a tag value
explicitly (e.g. ``tag="get"``). or a callable from class name to ``str``
(e.g. ``tag=lambda name: name.lower()`` to lowercase the class name
automatically). Note that the tag value must be unique for all struct types
in a union.
not provided or inherited. This can be overridden by passing a string (or
less commonly an integer) value explicitly (e.g. ``tag="get"``). ``tag`` can
also be passed a callable that takes the class name and returns a valid tag
value (e.g. ``tag=str.lower``). Note that tag values must be unique for all
struct types in a union, and ``str`` and ``int`` tag types cannot both be
used within the same union.

If you like subclassing, both ``tag_field`` and ``tag`` are inheritable by
subclasses, allowing configuration to be set once on a base class and reused
Expand All @@ -353,7 +354,7 @@ for all struct types you wish to tag.
>>> # Create a base class for tagged structs, where:
... # - the tag field is "op"
... # - the tag is the class name lowercased
... class TaggedBase(msgspec.Struct, tag_field="op", tag=lambda name: name.lower()):
... class TaggedBase(msgspec.Struct, tag_field="op", tag=str.lower):
... pass

>>> # Use the base class to pass on the configuration
Expand Down
4 changes: 2 additions & 2 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ or doesn't match any valid `enum.IntEnum` member.
>>> msgspec.json.decode(b'4', type=JobState)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
msgspec.DecodeError: Invalid enum value `4`
msgspec.DecodeError: Invalid enum value 4

``Enum``
~~~~~~~~
Expand Down Expand Up @@ -565,7 +565,7 @@ values, or doesn't match any of their component types.
>>> msgspec.json.decode(b'4', type=Literal[1, 2, 3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
msgspec.DecodeError: Invalid enum value `4`
msgspec.DecodeError: Invalid enum value 4

>>> msgspec.json.decode(b'"bad"', type=Literal[1, 2, 3])
Traceback (most recent call last):
Expand Down
4 changes: 2 additions & 2 deletions msgspec/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Struct(metaclass=__StructMeta):
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
def __init_subclass__(
cls,
tag: Union[None, bool, str, Callable[[str], str]] = None,
tag: Union[None, bool, str, int, Callable[[str], Union[str, int]]] = None,
tag_field: Union[None, str] = None,
rename: Union[
None, Literal["lower", "upper", "camel", "pascal"], Callable[[str], str]
Expand All @@ -59,7 +59,7 @@ def defstruct(
bases: Tuple[Type[Struct], ...] = (),
module: Optional[str] = None,
namespace: Optional[Dict[str, Any]] = None,
tag: Union[None, bool, str, Callable[[str], str]] = None,
tag: Union[None, bool, str, int, Callable[[str], Union[str, int]]] = None,
tag_field: Union[None, str] = None,
rename: Union[
None, Literal["lower", "upper", "camel", "pascal"], Callable[[str], str]
Expand Down
Loading