Skip to content

Commit ed3e267

Browse files
matejetzSimon Matejetzsamuelcolvin
authored
Fix creating schema from model using ConstrainedStr with regex str as dict key (#5223)
* add test for failing schema generation using ConstrainedStr as dict key * move get_pattern from ConstrainedStr to utils.py, use in schema.py when accessing pattern in regex * add change description md * move new test cases into existing test_schema_dict_constr test * undo moving get_pattern to utils.py, directly use ConstrainedStr._get_pattern function in schema.py instead * pull tests for ConstrainedStr model into separate def * use markdown backticks in change description. --------- Co-authored-by: Simon Matejetz <[email protected]> Co-authored-by: Samuel Colvin <[email protected]>
1 parent e12352c commit ed3e267

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

changes/5223-matejetz.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix creating schema from model using `ConstrainedStr` with `regex` as dict key

pydantic/schema.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
ConstrainedInt,
5656
ConstrainedList,
5757
ConstrainedSet,
58+
ConstrainedStr,
5859
SecretBytes,
5960
SecretStr,
6061
StrictBytes,
@@ -490,7 +491,7 @@ def field_type_schema(
490491
if regex:
491492
# Dict keys have a regex pattern
492493
# items_schema might be a schema or empty dict, add it either way
493-
f_schema['patternProperties'] = {regex.pattern: items_schema}
494+
f_schema['patternProperties'] = {ConstrainedStr._get_pattern(regex): items_schema}
494495
if items_schema:
495496
# The dict values are not simply Any, so they need a schema
496497
f_schema['additionalProperties'] = items_schema

tests/test_schema.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import math
33
import os
4+
import re
45
import sys
56
import tempfile
67
from datetime import date, datetime, time, timedelta
@@ -20,6 +21,7 @@
2021
NamedTuple,
2122
NewType,
2223
Optional,
24+
Pattern,
2325
Set,
2426
Tuple,
2527
Type,
@@ -3256,3 +3258,27 @@ class Baz(BaseModel):
32563258
'properties': {'a': {'title': 'A'}, 'b': {'title': 'B'}},
32573259
'required': ['a', 'b'],
32583260
}
3261+
3262+
3263+
@pytest.mark.parametrize(
3264+
'regex_val',
3265+
[
3266+
'^text$',
3267+
re.compile('^text$'),
3268+
],
3269+
)
3270+
def test_constrained_str_class_dict(regex_val: Union[str, Pattern[str]]):
3271+
class CustomStr(ConstrainedStr):
3272+
regex = regex_val
3273+
3274+
class Model(BaseModel):
3275+
a: Dict[CustomStr, Any]
3276+
3277+
json_schema = Model.schema()
3278+
3279+
assert json_schema == {
3280+
'title': 'Model',
3281+
'type': 'object',
3282+
'properties': {'a': {'patternProperties': {'^text$': {}}, 'title': 'A', 'type': 'object'}},
3283+
'required': ['a'],
3284+
}

0 commit comments

Comments
 (0)