Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,22 @@ In order to validate OpenAPI 3.0 schema, import and use ``OAS30Validator`` inste

validate({"name": "John", "age": None}, schema, cls=OAS30Validator)

Schema errors vs instance errors
--------------------------------

The high-level ``validate(...)`` helper checks schema validity before instance
validation, following ``jsonschema.validate(...)`` behavior.
Malformed schema values (for example an invalid regex in ``pattern``) raise
``SchemaError``.

If you instantiate a validator class directly and call ``.validate(...)``,
schema checking is not performed automatically, matching
``jsonschema`` validator-class behavior.
For malformed regex patterns this may raise a lower-level regex error.

Use ``<ValidatorClass>.check_schema(schema)`` first when you need deterministic
schema-validation errors with direct validator usage.

Read/write context
------------------

Expand Down
8 changes: 7 additions & 1 deletion openapi_schema_validator/shortcuts.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ def validate(
**kwargs: Any
) -> None:
"""
Validate an instance against a given schema using the specified validator class.
Validate an instance against a given schema using the specified
validator class.

Unlike direct ``Validator(schema).validate(instance)`` usage, this helper
checks schema validity first.
Invalid schemas therefore raise ``SchemaError`` before any instance
validation occurs.
"""
schema_dict = cast(dict[str, Any], schema)

Expand Down
17 changes: 17 additions & 0 deletions tests/integration/test_validators.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
import warnings
from base64 import b64encode
from typing import Any
Expand Down Expand Up @@ -30,6 +31,7 @@
from openapi_schema_validator import oas30_strict_format_checker
from openapi_schema_validator import oas31_format_checker
from openapi_schema_validator import oas32_format_checker
from openapi_schema_validator import validate
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_ID
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_METASCHEMA
from openapi_schema_validator._dialects import OAS32_BASE_DIALECT_ID
Expand Down Expand Up @@ -124,6 +126,21 @@ def test_string_invalid(self, validator_class, value):
with pytest.raises(ValidationError):
validator.validate(value)

def test_invalid_pattern_raises_regex_error(self, validator_class):
schema = {"type": "string", "pattern": "["}
validator = validator_class(schema)

with pytest.raises(re.error):
validator.validate("foo")

def test_invalid_pattern_rejected_by_validate_helper(
self, validator_class
):
schema = {"type": "string", "pattern": "["}

with pytest.raises(SchemaError, match="is not a 'regex'"):
validate("foo", schema, cls=validator_class)

def test_referencing(self, validator_class):
name_schema = Resource.from_contents(
{
Expand Down
Loading