8000 Fix models_json_schema for generic models (#7654) · pydantic/pydantic@ea9aa13 · GitHub
[go: up one dir, main page]

Skip to content

Commit ea9aa13

Browse files
adriangbdmontaguhramezani
authored
Fix models_json_schema for generic models (#7654)
Co-authored-by: David Montague <35119617+dmontagu@users.noreply.github.com> Co-authored-by: Hasan Ramezani <hasan.r67@gmail.com>
1 parent 97c0199 commit ea9aa13

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

pydantic/_internal/_repr.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ def display_as_type(obj: Any) -> str:
101101
args = ', '.join(map(display_as_type, typing_extensions.get_args(obj)))
102102
return f'Union[{args}]'
103103
elif isinstance(obj, _typing_extra.WithArgsTypes):
104-
args = ', '.join(map(display_as_type, typing_extensions.get_args(obj)))
104+
if typing_extensions.get_origin(obj) == typing_extensions.Literal:
105+
args = ', '.join(map(repr, typing_extensions.get_args(obj)))
106+
else:
107+
args = ', '.join(map(display_as_type, typing_extensions.get_args(obj)))
105108
return f'{obj.__qualname__}[{args}]'
106109
elif isinstance(obj, type):
107110
return obj.__qualname__

pydantic/json_schema.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,10 @@ def models_json_schema(
21802180
- The second element is a JSON schema containing all definitions referenced in the first returned
21812181
element, along with the optional title and description keys.
21822182
"""
2183+
for cls, _ in models:
2184+
if isinstance(cls.__pydantic_validator__, _mock_val_ser.MockValSer):
2185+
cls.__pydantic_validator__.rebuild()
2186+
21832187
instance = schema_generator(by_alias=by_alias, ref_template=ref_template)
21842188
inputs = [(m, mode, m.__pydantic_core_schema__) for m, mode in models]
21852189
json_schemas_map, definitions = instance.generate_definitions(inputs)

tests/test_json_schema.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5629,6 +5629,46 @@ class SerializationModel(Model):
56295629
assert SerializationModel.model_json_schema(mode='validation') == Model.model_json_schema(mode='serialization')
56305630

56315631

5632+
def test_models_json_schema_generics() -> None:
5633+
class G(BaseModel, Generic[T]):
5634+
foo: T
5635+
5636+
class M(BaseModel):
5637+
foo: Literal['a', 'b']
5638+
5639+
GLiteral = G[Literal['a', 'b']]
5640+
5641+
assert models_json_schema(
5642+
[
5643+
(GLiteral, 'serialization'),
5644+
(GLiteral, 'validation'),
5645+
(M, 'validation'),
5646+
]
5647+
) == (
5648+
{
5649+
(GLiteral, 'serialization'): {'$ref': '#/$defs/G_Literal__a____b___'},
5650+
(GLiteral, 'validation'): {'$ref': '#/$defs/G_Literal__a____b___'},
5651+
(M, 'validation'): {'$ref': '#/$defs/M'},
5652+
},
5653+
{
5654+
'$defs': {
5655+
'G_Literal__a____b___': {
5656+
'properties': {'foo': {'enum': ['a', 'b'], 'title': 'Foo', 'type': 'string'}},
5657+
'required': ['foo'],
5658+
'title': "G[Literal['a', 'b']]",
5659+
'type': 'object',
5660+
},
5661+
'M': {
5662+
'properties': {'foo': {'enum': ['a', 'b'], 'title': 'Foo', 'type': 'string'}},
5663+
'required': ['foo'],
5664+
'title': 'M',
5665+
'type': 'object',
5666+
},
5667+
}
5668+
},
5669+
)
5670+
5671+
56325672
def test_recursive_non_generic_model() -> None:
56335673
class Foo(BaseModel):
56345674
maybe_bar: Union[None, 'Bar']

0 commit comments

Comments
 (0)
0