Skip to content

Commit 4e63595

Browse files
authored
Merge pull request #266 from python-openapi/fix/pattern-bad-escape-alignment
Align pattern error behavior with jsonschema validation paths
2 parents 737f40f + 9761ca4 commit 4e63595

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

docs/validation.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ In order to validate OpenAPI 3.0 schema, import and use ``OAS30Validator`` inste
127127
128128
validate({"name": "John", "age": None}, schema, cls=OAS30Validator)
129129
130+
Schema errors vs instance errors
131+
--------------------------------
132+
133+
The high-level ``validate(...)`` helper checks schema validity before instance
134+
validation, following ``jsonschema.validate(...)`` behavior.
135+
Malformed schema values (for example an invalid regex in ``pattern``) raise
136+
``SchemaError``.
137+
138+
If you instantiate a validator class directly and call ``.validate(...)``,
139+
schema checking is not performed automatically, matching
140+
``jsonschema`` validator-class behavior.
141+
For malformed regex patterns this may raise a lower-level regex error.
142+
143+
Use ``<ValidatorClass>.check_schema(schema)`` first when you need deterministic
144+
schema-validation errors with direct validator usage.
145+
130146
Read/write context
131147
------------------
132148

openapi_schema_validator/shortcuts.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ def validate(
1919
**kwargs: Any
2020
) -> None:
2121
"""
22-
Validate an instance against a given schema using the specified validator class.
22+
Validate an instance against a given schema using the specified
23+
validator class.
24+
25+
Unlike direct ``Validator(schema).validate(instance)`` usage, this helper
26+
checks schema validity first.
27+
Invalid schemas therefore raise ``SchemaError`` before any instance
28+
validation occurs.
2329
"""
2430
schema_dict = cast(dict[str, Any], schema)
2531

tests/integration/test_validators.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
import warnings
23
from base64 import b64encode
34
from typing import Any
@@ -30,6 +31,7 @@
3031
from openapi_schema_validator import oas30_strict_format_checker
3132
from openapi_schema_validator import oas31_format_checker
3233
from openapi_schema_validator import oas32_format_checker
34+
from openapi_schema_validator import validate
3335
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_ID
3436
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_METASCHEMA
3537
from openapi_schema_validator._dialects import OAS32_BASE_DIALECT_ID
@@ -124,6 +126,21 @@ def test_string_invalid(self, validator_class, value):
124126
with pytest.raises(ValidationError):
125127
validator.validate(value)
126128

129+
def test_invalid_pattern_raises_regex_error(self, validator_class):
130+
schema = {"type": "string", "pattern": "["}
131+
validator = validator_class(schema)
132+
133+
with pytest.raises(re.error):
134+
validator.validate("foo")
135+
136+
def test_invalid_pattern_rejected_by_validate_helper(
137+
self, validator_class
138+
):
139+
schema = {"type": "string", "pattern": "["}
140+
141+
with pytest.raises(SchemaError, match="is not a 'regex'"):
142+
validate("foo", schema, cls=validator_class)
143+
127144
def test_referencing(self, validator_class):
128145
name_schema = Resource.from_contents(
129146
{

0 commit comments

Comments
 (0)