-
Notifications
You must be signed in to change notification settings - Fork 319
Closed
Labels
Description
Issue Description
On Pydantic 2.8.2 with Pydantic-core 2.20.0 I've noticed some inconsistent behavior validating strings using a pattern where passing the pattern as a string allows invalid inputs to pass validation, while passing the pattern as a compiled Pattern object from re.compile exhibits the expected behavior and rejects the invalid input.
Example:
import re
from pydantic import BaseModel, Field
# Note: this regular expression is based on the lowercase RFC1123 subdomain name regular expression
# the Kubernetes project uses to validate the names of Secrets and other resources.
COMPILED = re.compile(r"[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*")
NOT_COMPILED = r"[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*"
class NotCompiled(BaseModel):
name: str = Field(pattern=NOT_COMPILED)
class Compiled(BaseModel):
name: str = Field(pattern=COMPILED)
model = NotCompiled.model_validate({"name": "ShouldntPass"})
print(repr(model))
# NotCompiled(name='ShouldntPass')
model = Compiled.model_validate({"name": "ShouldntPass"})
print(repr(model)) # unreachable, previous line raises ValidationError as expectedThis can be reproduced by adding the following two test cases to tests/validators/test_string.py:
(
{'pattern': r'[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*'},
'ShouldntPass',
'ShouldntPass',
),
(
{'pattern': re.compile(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')},
'ShouldntPass',
Err(
"String should match pattern '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' [type=string_pattern_mismatch"
),
),Environment Info
Here is some information on the environment where I noticed the issue:
$ pdm info --env
{
"implementation_name": "cpython",
"implementation_version": "3.9.18",
"os_name": "posix",
"platform_machine": "x86_64",
"platform_release": "6.9.7-100.fc39.x86_64",
"platform_system": "Linux",
"platform_version": "#1 SMP PREEMPT_DYNAMIC Thu Jun 27 18:06:32 UTC 2024",
"python_full_version": "3.9.18",
"platform_python_implementation": "CPython",
"python_version": "3.9",
"sys_platform": "linux"
}
$ pdm show pydantic
Name: pydantic
Latest version: 2.8.2
Latest stable version: 2.8.2
Installed version: 2.8.2
Summary: Data validation using Python type hints
Requires Python: >=3.8
... # Truncated for brevity
$ pdm show pydantic-core
Name: pydantic_core
Latest version: 2.20.1
Latest stable version: 2.20.1
Installed version: 2.20.1
Summary: Core functionality for Pydantic validation and serialization
Requires Python: >=3.8
... # Truncated for brevity