Skip to content

Commit

Permalink
Add support for re.Pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
hramezani committed Aug 11, 2022
1 parent fa6b978 commit 9f1d3f4
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 8 deletions.
1 change: 1 addition & 0 deletions changes/4366-hramezani.md
@@ -0,0 +1 @@
Add support for `re.Pattern`
3 changes: 2 additions & 1 deletion pydantic/fields.py
@@ -1,4 +1,5 @@
import copy
import re
from collections import Counter as CollectionCounter, defaultdict, deque
from collections.abc import Callable, Hashable as CollectionsHashable, Iterable as CollectionsIterable
from typing import (
Expand Down Expand Up @@ -595,7 +596,7 @@ def _type_analysis(self) -> None: # noqa: C901 (ignore complexity)
self.required = False
self.allow_none = True
return
elif self.type_ is Pattern:
elif self.type_ is Pattern or self.type_ is re.Pattern:
# python 3.7 only, Pattern is a typing object but without sub fields
return
elif is_literal_type(self.type_):
Expand Down
2 changes: 1 addition & 1 deletion pydantic/schema.py
Expand Up @@ -804,7 +804,7 @@ def add_field_type_to_schema(field_type: Any, schema_: Dict[str, Any]) -> None:
"""
for type_, t_schema in field_class_to_schema:
# Fallback for `typing.Pattern` as it is not a valid class
if lenient_issubclass(field_type, type_) or field_type is type_ is Pattern:
if lenient_issubclass(field_type, type_) or (type_ is Pattern or type_ is re.Pattern):
schema_.update(t_schema)
break

Expand Down
2 changes: 1 addition & 1 deletion pydantic/validators.py
Expand Up @@ -684,7 +684,7 @@ def find_validators( # noqa: C901 (ignore complexity)
if is_none_type(type_):
yield none_validator
return
if type_ is Pattern:
if type_ is Pattern or type_ is re.Pattern:
yield pattern_validator
return
if type_ is Hashable or type_ is CollectionsHashable:
Expand Down
12 changes: 7 additions & 5 deletions tests/test_types.py
Expand Up @@ -2540,9 +2540,10 @@ class JsonRequired(BaseModel):
assert JsonRequired().dict() == {'json_obj': None}


def test_pattern():
@pytest.mark.parametrize('pattern_type', [re.Pattern, Pattern])
def test_pattern1(pattern_type):
class Foobar(BaseModel):
pattern: Pattern
pattern: pattern_type

f = Foobar(pattern=r'^whatev.r\d$')
assert f.pattern.__class__.__name__ == 'Pattern'
Expand All @@ -2558,14 +2559,15 @@ class Foobar(BaseModel):
assert Foobar.schema() == {
'type': 'object',
'title': 'Foobar',
'properties': {'pattern': {'type': 'string', 'format': 'regex', 'title': 'Pattern'}},
'properties': {'pattern': {'type': 'sting', 'format': 'regex', 'title': 'Pattern'}},
'required': ['pattern'],
}


def test_pattern_error():
@pytest.mark.parametrize('pattern_type', [re.Pattern, Pattern])
def test_pattern_error(pattern_type):
class Foobar(BaseModel):
pattern: Pattern
pattern: pattern_type

with pytest.raises(ValidationError) as exc_info:
Foobar(pattern='[xx')
Expand Down

0 comments on commit 9f1d3f4

Please sign in to comment.