8000 Add regex patterns to JSON schema for `Decimal` type by Dima-Bulavenko · Pull Request #11987 · pydantic/pydantic · GitHub
[go: up one dir, main page]

Skip to content
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
test: update existing tests for Decimal JSON schema pattern validation
Old tests have been updated to align with the new validation pattern
for Decimal fields in the JSON schema.
  • Loading branch information
Dima-Bulavenko committed Jun 16, 2025
commit 07db8207ec89a943defb56c1c50a6fd21b427198
162 changes: 147 additions & 15 deletions tests/test_json_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,15 +525,30 @@ class Model(BaseModel):
assert model_json_schema_validation == {
'properties': {
'a': {'default': 'foobar', 'format': 'binary', 'title': 'A', 'type': 'string'},
'b': {'anyOf': [{'type': 'number'}, {'type': 'string'}], 'default': '12.34', 'title': 'B'},
'b': {
'anyOf': [
{'type': 'number'},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
],
'default': '12.34',
'title': 'B',
},
},
'title': 'Model',
'type': 'object',
}
assert model_json_schema_serialization == {
'properties': {
'a': {'default': 'foobar', 'format': 'binary', 'title': 'A', 'type': 'string'},
'b': {'default': '12.34', 'title': 'B', 'type': 'string'},
'b': {
'default': '12.34',
8000 'title': 'B',
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
},
'title': 'Model',
'type': 'object',
Expand Down Expand Up @@ -1053,7 +1068,18 @@ class Model(BaseModel):
base_schema = {
'title': 'Model',
'type': 'object',
'properties': {'a': {'anyOf': [{'type': 'number'}, {'type': 'string'}], 'title': 'A'}},
'properties': {
'a': {
'anyOf': [
{'type': 'number'},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
],
'title': 'A',
}
},
'required': ['a'],
}
base_schema['properties']['a']['anyOf'][0].update(expected_schema)
Expand Down Expand Up @@ -2006,11 +2032,71 @@ class A(BaseModel):
({'ge': -math.inf}, float, {'type': 'number'}),
({'le': math.inf}, float, {'type': 'number'}),
({'multiple_of': 5}, float, {'type': 'number', 'multipleOf': 5}),
({'gt': 2}, Decimal, {'anyOf': [{'exclusiveMinimum': 2.0, 'type': 'number'}, {'type': 'string'}]}),
({'lt': 5}, Decimal, {'anyOf': [{'type': 'number', 'exclusiveMaximum': 5}, {'type': 'string'}]}),
({'ge': 2}, Decimal, {'anyOf': [{'type': 'number', 'minimum': 2}, {'type': 'string'}]}),
({'le': 5}, Decimal, {'anyOf': [{'type': 'number', 'maximum': 5}, {'type': 'string'}]}),
({'multiple_of': 5}, Decimal, {'anyOf': [{'type': 'number', 'multipleOf': 5}, {'type': 'string'}]}),
(
{'gt': 2},
Decimal,
{
'anyOf': [
{'exclusiveMinimum': 2.0, 'type': 'number'},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
]
},
),
(
{'lt': 5},
Decimal,
{
'anyOf': [
{'type': 'number', 'exclusiveMaximum': 5},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
]
},
),
(
{'ge': 2},
Decimal,
{
'anyOf': [
{'type': 'number', 'minimum': 2},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
]
},
),
(
{'le': 5},
Decimal,
{
'anyOf': [
{'type': 'number', 'maximum': 5},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
]
},
),
(
{'multiple_of': 5},
Decimal,
{
'anyOf': [
{'type': 'number', 'multipleOf': 5},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
]
},
),
],
)
def test_constraints_schema_validation(kwargs, type_, expected_extra):
Expand Down Expand Up @@ -2049,11 +2135,46 @@ class Foo(BaseModel):
({'ge': -math.inf}, float, {'type': 'number'}),
({'le': math.inf}, float, {'type': 'number'}),
({'multiple_of': 5}, float, {'type': 'number', 'multipleOf': 5}),
({'gt': 2}, Decimal, {'type': 'string'}),
({'lt': 5}, Decimal, {'type': 'string'}),
({'ge': 2}, Decimal, {'type': 'string'}),
({'le': 5}, Decimal, {'type': 'string'}),
({'multiple_of': 5}, Decimal, {'type': 'string'}),
(
{'gt': 2},
Decimal,
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
),
(
{'lt': 5},
Decimal,
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
),
(
{'ge': 2},
Decimal,
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
),
(
{'le': 5},
Decimal,
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
),
(
{'multiple_of': 5},
Decimal,
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
),
],
)
def test_constraints_schema_serialization(kwargs, type_, expected_extra):
Expand Down Expand Up @@ -5734,8 +5855,19 @@ class Model(BaseModel):
)
assert result == (
{
('Decimal', 'serialization'): {'type': 'string'},
('Decimal', 'validation'): {'anyOf': [{'type': 'number'}, {'type': 'string'}]},
('Decimal', 'serialization'): {
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
('Decimal', 'validation'): {
'anyOf': [
{'type': 'number'},
{
'type': 'string',
'pattern': '^(?!^[+-\\.]*$)[+-]?0*(?:\\d{0,}$|(?=[\\d\\.]{1,}0*$)\\d{0,}\\.\\d{0,}0*$)',
},
]
},
('Model', 'validation'): {'$ref': '#/$defs/Model'},
},
{'Model': {'properties': {}, 'title': 'Model', 'type': 'object'}},
Expand Down
0