|
7 | 7 | from annotated_types import MaxLen
|
8 | 8 | from typing_extensions import TypeAliasType
|
9 | 9 |
|
10 |
| -from pydantic import BaseModel, PydanticUserError, TypeAdapter, ValidationError |
| 10 | +from pydantic import BaseModel, PlainSerializer, PydanticUserError, TypeAdapter, ValidationError, WithJsonSchema |
11 | 11 |
|
12 | 12 | T = TypeVar('T')
|
13 | 13 |
|
@@ -430,3 +430,46 @@ class MyModel(BaseModel):
|
430 | 430 |
|
431 | 431 | assert exc_info.value.code == 'circular-reference-schema'
|
432 | 432 | assert exc_info.value.message.startswith('tests.test_type_alias_type.C')
|
| 433 | + |
| 434 | + |
| 435 | +def test_type_alias_type_with_serialization() -> None: |
| 436 | + """Regression test for https://github.com/pydantic/pydantic/issues/11642. |
| 437 | +
|
| 438 | + The issue lied in the definition resolving logic, which wasn't taking |
| 439 | + possible metadata or serialization attached to a `'definition-ref'` schema. |
| 440 | +
|
| 441 | + In this example, the core schema for `B` — before schema cleaning — will look like: |
| 442 | +
|
| 443 | + ```python |
| 444 | + { |
| 445 | + 'type': 'definition-ref', |
| 446 | + 'schema_ref': '__main__.A', |
| 447 | + 'serialization': {...}, |
| 448 | + 'ref': '__main__.B', |
| 449 | + } |
| 450 | + ``` |
| 451 | +
|
| 452 | + and the "main"/"top-level" core schema is a `'definition-ref'` schema pointing to |
| 453 | + `'__main__.B`. |
| 454 | +
|
| 455 | + In schema cleaning, when resolving this top-level core schema, we would recursively |
| 456 | + unpack `'definition-ref'` schemas (and would end up with the actual schema for `__main__.A`), |
| 457 | + without taking into account the fact that the schema of `B` had a `serialization` key! |
| 458 | + """ |
| 459 | + |
| 460 | + A = TypeAliasType('A', int) |
| 461 | + B = TypeAliasType('B', Annotated[A, PlainSerializer(lambda v: 3)]) |
| 462 | + |
| 463 | + ta = TypeAdapter(B) |
| 464 | + |
| 465 | + assert ta.dump_python(1) == 3 |
| 466 | + |
| 467 | + |
| 468 | +def test_type_alias_type_with_metadata() -> None: |
| 469 | + """Same as `test_type_alias_type_with_serialization()` but with JSON Metadata.""" |
| 470 | + |
| 471 | + A = TypeAliasType('A', int) |
| 472 | + B = TypeAliasType('B', Annotated[A, WithJsonSchema({'type': 'int', 'extra': 1})]) |
| 473 | + |
| 474 | + ta = TypeAdapter(B) |
| 475 | + assert ta.json_schema() == {'type': 'int', 'extra': 1} |
0 commit comments