Skip to content

Commit

Permalink
[1.10.X] Fix field regex with StrictStr type annotation (#4538)
Browse files Browse the repository at this point in the history
* Fix field regex with StrictStr type annotation

* Add change file

* Improve regex caching
  • Loading branch information
sisp committed Sep 20, 2022
1 parent 3461bc9 commit b171a7e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
1 change: 1 addition & 0 deletions changes/4538-sisp.md
@@ -0,0 +1 @@
Fix field regex with `StrictStr` type annotation.
12 changes: 8 additions & 4 deletions pydantic/types.py
Expand Up @@ -403,7 +403,7 @@ class ConstrainedStr(str):
min_length: OptionalInt = None
max_length: OptionalInt = None
curtail_length: OptionalInt = None
regex: Optional[Pattern[str]] = None
regex: Optional[Union[str, Pattern[str]]] = None
strict = False

@classmethod
Expand All @@ -412,7 +412,7 @@ def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
field_schema,
minLength=cls.min_length,
maxLength=cls.max_length,
pattern=cls.regex and cls.regex.pattern,
pattern=cls.regex and cls._get_pattern(cls.regex),
)

@classmethod
Expand All @@ -430,11 +430,15 @@ def validate(cls, value: Union[str]) -> Union[str]:
value = value[: cls.curtail_length]

if cls.regex:
if not cls.regex.match(value):
raise errors.StrRegexError(pattern=cls.regex.pattern)
if not re.match(cls.regex, value):
raise errors.StrRegexError(pattern=cls._get_pattern(cls.regex))

return value

@staticmethod
def _get_pattern(regex: Union[str, Pattern[str]]) -> str:
return regex if isinstance(regex, str) else regex.pattern


def constr(
*,
Expand Down
39 changes: 39 additions & 0 deletions tests/test_types.py
Expand Up @@ -1759,6 +1759,45 @@ class Model(BaseModel):
Model(u='1234567')


def test_strict_str_regex():
class Model(BaseModel):
u: StrictStr = Field(..., regex=r'^[0-9]+$')

assert Model(u='123').u == '123'

with pytest.raises(ValidationError, match='str type expected'):
Model(u=123)

with pytest.raises(ValidationError) as exc_info:
Model(u='abc')
assert exc_info.value.errors() == [
{
'loc': ('u',),
'msg': 'string does not match regex "^[0-9]+$"',
'type': 'value_error.str.regex',
'ctx': {'pattern': '^[0-9]+$'},
}
]


def test_string_regex():
class Model(BaseModel):
u: str = Field(..., regex=r'^[0-9]+$')

assert Model(u='123').u == '123'

with pytest.raises(ValidationError) as exc_info:
Model(u='abc')
assert exc_info.value.errors() == [
{
'loc': ('u',),
'msg': 'string does not match regex "^[0-9]+$"',
'type': 'value_error.str.regex',
'ctx': {'pattern': '^[0-9]+$'},
}
]


def test_strict_bool():
class Model(BaseModel):
v: StrictBool
Expand Down

0 comments on commit b171a7e

Please sign in to comment.