Fix Union with Literals#69
Conversation
0c5094b to
d70350f
Compare
|
Thoughts on this PR? IS this something you'd like to address? |
|
Hey @rhaps0dy, while I'm failing to see much practical applications 😉 this is a legit type of type hint that seems like it should deserializable by Databind. I think we could just say that the nested union serialization format is not supported when a |
|
Oh, I can give you practical applications for this one! Here's my configuration for describing a convolution layer, pay attention to the @dataclasses.dataclass(frozen=True)
class ConvConfig:
features: int
kernel_size: Tuple[int, ...]
strides: Tuple[int, ...]
padding: Literal["SAME", "VALID"] | Sequence[Tuple[int, ...]] = "SAME"
use_bias: bool = True
initialization: Literal["torch", "lecun"] = "lecun"from e.g. the Torch docs (https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html):
this would imply a type of -- The actual reason I fixed it is that I thought there were very few [bug] issues in the tracker and maybe I could make PRs for all of them. But now I'm making use of it. |
Add get_type_id_for_value(value) to UnionMembers so that Literal type
members can be resolved by value rather than by type (e.g. type("hi")
is str, which can't distinguish Literal["hi"] from Literal["bye"]).
- UnionMembers: add non-abstract get_type_id_for_value with default
fallback to get_type_id(type(value))
- StaticUnionMembers: override to check LiteralTypeHint members first,
handling both raw typing annotations and TypeHint instances
- ChainUnionMembers: override to delegate to children
- UnionConverter: include Literal members in the auto-generated members
dict, remove separate literal_types loop, use get_type_id_for_value
in the serialize path, wrap ValueError as ConversionError
- Tests: remove xfail from keyed literal test, simplify best_match
literal test, fix test_union_literal to include LiteralConverter
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
This comment was generated by Claude Code (claude-opus-4-6). Implementation: Integrate Literal types into UnionMembersThis commit properly integrates Problem
SolutionAdded
In
Tests
|
d70350f to
d6dc2e3
Compare
- Add -> None return type annotation - Use t.Union[...] syntax instead of | operator for type aliases with Literal members (fixes valid-type and operator errors) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #47 by enabling JSON serialization/deserialization for typing.Union types that include typing.Literal members, which previously failed due to union-member constraints and type-only member resolution.
Changes:
- Extend
UnionConverterto acceptLiteralTypeHintmembers in “plain” (non-annotated) unions and to resolve union members for serialization based on the actual value (to support Literals). - Add
UnionMembers.get_type_id_for_value()with implementations forStaticUnionMembersandChainUnionMembersto support value-based matching (especially for Literals). - Add regression tests covering best-match and keyed union behavior with Literal members, and document the fix in the changelog.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
databind/src/databind/json/tests/converters_test.py |
Adds regression tests for unions containing Literal members (best-match and keyed styles). |
databind/src/databind/json/converters.py |
Updates UnionConverter to allow Literal members in plain unions and to select union members by value for serialization. |
databind/src/databind/core/union.py |
Adds value-based union member resolution API and implements Literal-aware matching in StaticUnionMembers (and delegation in ChainUnionMembers). |
.changelog/_unreleased.toml |
Adds an unreleased changelog entry describing the fix for #47. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
NOTE: currently this PR has a test that fails: serializing a Keyed union with literals. Fixing this requires changing the signature of
get_type_idfor UnionMembers for a bunch of classes, which I don't feel like doing now. Do I need to do it?Partially Fixes #47
Unions with Literal types on them could not be serialized or deserialized. They now can.