10BC0 [1.10.X] Fix field regex with StrictStr type annotation by sisp · Pull Request #4538 · pydantic/pydantic · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@sisp
Copy link
Contributor
@sisp sisp commented Sep 19, 2022

There's an inconsistency between constr(...) and ConstrainedStr, which is the base class of StrictStr, with regard to the expected type of the regex argument/attribute which causes a field of type StrictStr with a regex constraint specified via the Field(...) class to raise an error:

File "pydantic/main.py", line 340, in pydantic.main.BaseModel.__init__
File "pydantic/main.py", line 1076, in pydantic.main.validate_model
File "pydantic/fields.py", line 884, in pydantic.fields.ModelField.validate
File "pydantic/fields.py", line 1101, in pydantic.fields.ModelField._validate_singleton
File "pydantic/fields.py", line 1148, in pydantic.fields.ModelField._apply_validators
File "pydantic/class_validators.py", line 318, in pydantic.class_validators._generic_validator_basic.lambda13
File "pydantic/types.py", line 433, in pydantic.types.ConstrainedStr.validate
AttributeError: 'str' object has no attribute 'match'

I've fixed this inconsistency in a backwards compatible way by extending the type of regex in ConstrainedStr to also support a str value in addition to Pattern[str].

I hope this fix will be considered despite the ongoing efforts towards Pydantic v2. 🙂

Copy link
Member
@samuelcolvin samuelcolvin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise happy to accept this.

Comment on lines 433 to 435
regex = cls._regex()
if regex:
if not regex.match(value):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid this might be slow since the compiled regex might not be cached.

Better to do the following which I think should work in both cases

Suggested change
regex = cls._regex()
if regex:
if not regex.match(value):
if cls.regex:
if not re.match(cls.regex, value):


@classmethod
def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
regex = cls._regex()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you'll therefore still need an isinstance check here.

@sisp
Copy link
Contributor Author
sisp commented Sep 20, 2022

@samuelcolvin Thanks for your review feedback! I think I've made the changes accordingly which should improve regex caching. Happy to receive your feedback again. 🙂

Copy link
Member
@samuelcolvin samuelcolvin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@hramezani please review and check you're happy with this.

Copy link
Member
@hramezani hramezani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Thanks @sisp

@samuelcolvin samuelcolvin merged commit b171a7e into pydantic:1.10.X-fixes Sep 20, 2022
@samuelcolvin
Copy link
Member

thanks so much for this.

@sisp sisp deleted the fix/strict-str-regex branch September 20, 2022 13:45
@sisp
Copy link
Contributor Author
sisp commented Sep 20, 2022

Sure thing, thanks for the review parallel to all the v2 dev work! Can't wait to see v2 and all its improvements! 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

0