Fix inspect.type_info crashing on mixed-type Literals#1080
Open
gaoflow wants to merge 2 commits into
Open
Conversation
type_info sorted a Literal's values with a plain sorted(), which raises TypeError on mixed-type literals such as Literal[1, None] or Literal[True, "yes"] since Python 3 forbids ordering across types. The encoder/decoder already support these literals, so type_info crashing on them is a contract violation. Sort by (type name, value) so same-type ordering is unchanged and mixed-type literals are grouped deterministically, with a try/except fallback. Also widen the LiteralType.values annotation to allow mixed/None members. Adds test_bool_literal and test_mixed_literal.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1018.
Problem
msgspec.inspect.type_infocrashes on mixed-typeLiterals:type_infodoestuple(sorted(args))on the literal's values, and Python 3 forbids<between values of different types. The encoder/decoder already handle these mixed-type literals fine (e.g.Literal[1, None]decodes1/nulland rejects2), sotype_infofailing on them is a contract violation.Fix
Sort the literal values with a
(type name, value)key instead. This keeps existing same-type ordering identical (Literal[3,1,2]→(1,2,3),Literal[True,False]→(False,True)) while grouping mixed-type literals deterministically rather than crashing, and atry/except TypeErrorfalls back to the original order as a safety net. TheLiteralType.valuesannotation is widened to allow mixed andNonemembers.Tests
Added
test_mixed_literal(Literal[1, None],Literal[True, "yes"]) andtest_bool_literal. Without the fixtest_mixed_literalraises theTypeError; with it the fulltest_inspect.py/test_schema.pypass (276 passed, 13 skipped).I'll add a
docs/changelog.mdentry referencing this PR number in a follow-up commit.Disclosure: I used AI assistance (Claude) to help locate and draft this fix, under my direction and review.