Add ability to use min_length and max_length constraints with secret types#1974
Conversation
93c5c3b to
d7f897b
Compare
Codecov Report
@@ Coverage Diff @@
## master #1974 +/- ##
===========================================
- Coverage 100.00% 99.90% -0.10%
===========================================
Files 21 21
Lines 3909 4035 +126
Branches 788 805 +17
===========================================
+ Hits 3909 4031 +122
- Misses 0 3 +3
- Partials 0 1 +1
Continue to review full report at Codecov.
|
d7f897b to
43e47c1
Compare
samuelcolvin
left a comment
There was a problem hiding this comment.
looks good, please also check that schema() is correct.
|
@samuelcolvin Looks like I found a bug, correct me in a case when I missed smth. For instance, I define a custom type which inherits from class CustomStr(str):
...And I have to models: class Foo(BaseModel):
field: CustomStr # without constrain
class Bar(BaseModel):
field: CustomStr = Field(..., min_length=10) # with constrainExample of usage and results: foo = Foo(field='foo')
bar = Bar(field='bar')
print(type(foo.field))
print(type(bar.field))That's because of this code: # schema.py L835
if issubclass(type_, (str, SecretStr)) and not issubclass(type_, (EmailStr, AnyUrl, ConstrainedStr)):
attrs = ('max_length', 'min_length', 'regex')
constraint_func = constrSo with my current implementation, I have a future request and want to hear your opinion. I propose to add So, for instance, class SecretStr:
min_length: OptionalInt = None
max_length: OptionalInt = None
__constraints__: Set[str] = {'min_length', 'max_length'}
@classmethod
def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
update_not_none(
field_schema,
type='string',
writeOnly=True,
format='password',
minLength=cls.min_length,
maxLength=cls.max_length,
)With this approach, we can simplify For instance, we can define mixins: class LengthValidation:
min_length: OptionalInt = None
max_length: OptionalInt = None
__constraints__: Set[str] = {'min_length', 'max_length'}
@classmethod
def __modify_schema__(cls: Type[Sized], field_schema: Dict[str, Any]) -> None:
update_not_none(field_schema, minLength=cls.min_length, maxLength=cls.max_length)
@classmethod
def __get_validators__(cls) -> 'CallableGenerator':
yield constr_length_validator
class SecretStr(LengthValidation):
@classmethod
def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
super().__modify_schema__(field_schema)
field_schema.update(type='string', writeOnly=True, format='password')
def __len__(self) -> int:
return len(self._secret_value)@samuelcolvin What is your opinion regarding this feature? Also, I thought about API like this: class SecretBytes:
min_length: Constraint[OptionalInt] = None
max_length: Constraint[OptionalInt] = NoneI have already updated my PR using this feature. |
|
I think better to modify if issubclass(type_, SecretStr) and (field_info.min_items is not None or field_info.max_items is not None):
type_.min_length = field_info.min_items
type_.max_length = field_info.max_itemsThen allow yield the length validator from I think that would require a smaller change? |
ed05618 to
ce95302
Compare
|
@samuelcolvin I have updated PR, thanks for your suggestions. And what about the bug and feature request which I described above? |
ce95302 to
cd33263
Compare
samuelcolvin
left a comment
There was a problem hiding this comment.
otherwise this looks good.
if you have a bug or feature request, please create an issue or issues. But in general I think the current approach works pretty well, I don't want to change the interface or add more features until it's absolutely necessary. |
|
I have updated PR. |
|
thanks so much. |
|
nice, I am still getting the original error message tho with version 1.7: |
|
Hi @transfluxus, I just test it out, and it works as expected. I have run this code: from pydantic import BaseModel, Field, SecretStr
class Form(BaseModel):
password: SecretStr = Field(min_length=6)
form = Form(password="hello world")And I didn't receive any error. Please, make sure that you are using the latest available version of a pip install -U pydantic |
|
hey @uriyyo Would be nice if the constructor wouldn't have a warning about expecting a "SecretStr" instead of str.
actually fails with but this concerns all Secret Fieldtypes and is another issue. thanks! |
Change Summary
Add ability to use min_length and max_length constraints with
SecretStrandSecretBytestypes.For instance, this model is totally valid:
Related issue number
Fix #1461
Checklist
changes/<pull request or issue id>-<github username>.mdfile added describing change(see changes/README.md for details)