diff --git a/changes/4388-hramezani.md b/changes/4388-hramezani.md new file mode 100644 index 0000000000..19284ee0ce --- /dev/null +++ b/changes/4388-hramezani.md @@ -0,0 +1 @@ +Fix `StrictStr` does not raise `ValidationError` when `max_length` is present in `Field` diff --git a/pydantic/schema.py b/pydantic/schema.py index 8dd7d1f074..48d49604a6 100644 --- a/pydantic/schema.py +++ b/pydantic/schema.py @@ -54,10 +54,10 @@ ConstrainedInt, ConstrainedList, ConstrainedSet, - ConstrainedStr, SecretBytes, SecretStr, StrictBytes, + StrictStr, conbytes, condecimal, confloat, @@ -1083,9 +1083,15 @@ def go(type_: Any) -> Type[Any]: def constraint_func(**kw: Any) -> Type[Any]: return type(type_.__name__, (type_,), kw) - elif issubclass(type_, str) and not issubclass(type_, (EmailStr, AnyUrl, ConstrainedStr)): + elif issubclass(type_, str) and not issubclass(type_, (EmailStr, AnyUrl)): attrs = ('max_length', 'min_length', 'regex') - constraint_func = constr + if issubclass(type_, StrictStr): + + def constraint_func(**kw: Any) -> Type[Any]: + return type(type_.__name__, (type_,), kw) + + else: + constraint_func = constr elif issubclass(type_, bytes): attrs = ('max_length', 'min_length', 'regex') if issubclass(type_, StrictBytes): diff --git a/tests/test_types.py b/tests/test_types.py index 354b359a28..a8021ec31b 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1690,6 +1690,19 @@ class Model(BaseModel): assert m.v == 'foobar' +def test_strict_str_max_length(): + class Model(BaseModel): + u: StrictStr = Field(..., max_length=5) + + assert Model(u='foo').u == 'foo' + + with pytest.raises(ValidationError, match='str type expected'): + Model(u=123) + + with pytest.raises(ValidationError, match='ensure this value has at most 5 characters'): + Model(u='1234567') + + def test_strict_bool(): class Model(BaseModel): v: StrictBool