diff --git a/changes/4380-JeanArhancet.md b/changes/4380-JeanArhancet.md new file mode 100644 index 0000000000..f880042377 --- /dev/null +++ b/changes/4380-JeanArhancet.md @@ -0,0 +1 @@ +Fix `StrictBytes` does not raise `ValidationError` when `max_length` is present in `Field` diff --git a/pydantic/schema.py b/pydantic/schema.py index b2abae33d7..8dd7d1f074 100644 --- a/pydantic/schema.py +++ b/pydantic/schema.py @@ -57,6 +57,7 @@ ConstrainedStr, SecretBytes, SecretStr, + StrictBytes, conbytes, condecimal, confloat, @@ -1087,7 +1088,13 @@ def constraint_func(**kw: Any) -> Type[Any]: constraint_func = constr elif issubclass(type_, bytes): attrs = ('max_length', 'min_length', 'regex') - constraint_func = conbytes + if issubclass(type_, StrictBytes): + + def constraint_func(**kw: Any) -> Type[Any]: + return type(type_.__name__, (type_,), kw) + + else: + constraint_func = conbytes elif issubclass(type_, numeric_types) and not issubclass( type_, ( diff --git a/tests/test_types.py b/tests/test_types.py index b9ec8128ff..354b359a28 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1634,6 +1634,18 @@ class Model(BaseModel): Model(v=0.42) +def test_strict_bytes_max_length(): + class Model(BaseModel): + u: StrictBytes = Field(..., max_length=5) + + assert Model(u=b'foo').u == b'foo' + + with pytest.raises(ValidationError, match='byte type expected'): + Model(u=123) + with pytest.raises(ValidationError, match='ensure this value has at most 5 characters'): + Model(u=b'1234567') + + def test_strict_bytes_subclass(): class MyStrictBytes(StrictBytes): pass