Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Recursively unpackLiteral values if using PEP 695 type aliases#11114

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
sydney-runkle merged 1 commit intomainfromliteral-type-aliases
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes fromall 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
22 changes: 19 additions & 3 deletionspydantic/_internal/_typing_extra.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,11 +85,27 @@ def is_literal(tp: Any, /) -> bool:
return _is_typing_name(get_origin(tp), name='Literal')


# TODO remove and replace with `get_args` when we drop support for Python 3.8
# (see https://docs.python.org/3/whatsnew/3.9.html#id4).
def literal_values(tp: Any, /) -> list[Any]:
"""Return the values contained in the provided `Literal` special form."""
"""Return the values contained in the provided `Literal` special form.

If one of the literal values is a PEP 695 type alias, recursively parse
the type alias' `__value__` to unpack literal values as well. This function
*doesn't* check that the type alias is referencing a `Literal` special form,
so unexpected values could be unpacked.
"""
# TODO When we drop support for Python 3.8, there's no need to check of `is_literal`
# here, as Python unpacks nested `Literal` forms in 3.9+.
# (see https://docs.python.org/3/whatsnew/3.9.html#id4).
if not is_literal(tp):
# Note: we could also check for generic aliases with a type alias as an origin.
# However, it is very unlikely that this happens as type variables can't appear in
# `Literal` forms, so the only valid (but unnecessary) use case would be something like:
# `type Test[T] = Literal['whatever']` (and then use `Test[SomeType]`).
if is_type_alias_type(tp):
# Note: accessing `__value__` could raise a `NameError`, but we just let
# the exception be raised as there's not much we can do if this happens.
return literal_values(tp.__value__)

return [tp]

values = get_args(tp)
Expand Down
13 changes: 12 additions & 1 deletiontests/test_json_schema.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@
from packaging.version import Version
from pydantic_core import CoreSchema, SchemaValidator, core_schema, to_jsonable_python
from pydantic_core.core_schema import ValidatorFunctionWrapHandler
from typing_extensions import Annotated, Literal, Self, TypedDict, deprecated
from typing_extensions import Annotated, Literal, Self,TypeAliasType,TypedDict, deprecated

import pydantic
from pydantic import (
Expand DownExpand Up@@ -2378,6 +2378,17 @@ class Model(BaseModel):
}


def test_literal_schema_type_aliases() -> None:
TestType0 = TypeAliasType('TestType0', Literal['a'])
TestType1 = TypeAliasType('TestType1', Literal[TestType0, 'b'])
TestType2 = TypeAliasType('TestType2', Literal[TestType1, 'c'])

assert TypeAdapter(TestType2).json_schema() == {
'enum': ['a', 'b', 'c'],
'type': 'string',
}


def test_literal_enum():
class MyEnum(str, Enum):
FOO = 'foo'
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp