-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Make sure generated JSON Schemas are valid in tests #10182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Deploying pydantic-docs with
|
| Latest commit: |
c39d7da
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://916add11.pydantic-docs.pages.dev |
| Branch Preview URL: | https://10173-json-schema-tests.pydantic-docs.pages.dev |
CodSpeed Performance ReportMerging #10182 will not alter performanceComparing Summary
|
906009d to
d5867e8
Compare
|
Ok, one more case that I'm going to fix in a separate PR related to function arguments schemas. |
d5867e8 to
e5c9f64
Compare
Perfect, thanks for including these performance comparisons here. I'm fine with this slight slowdown for what feels like a large amount of added value. This is a great quality check. |
sydney-runkle
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great overall - just one small change request re the verbosity of the error message + a potential test for this new logic.
tests/conftest.py
Outdated
| try: | ||
| Draft202012Validator.check_schema(json_schema) | ||
| except SchemaError: | ||
| pytest.fail('Failed to validate the JSON Schema against the Draft 2020-12 spec') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps this could be a bit more verbose:
- Can we include the
SchemaErrorinformation in this result? - Could we add a note about the fact that this is purely a testing feature, not a runtime
pydanticcheck (at this point)?
Perhaps this is a bit excessive, but can we test this test? As in, run a test within a test, and check that this is raised for invalid schema? If not, no worries, but could you document an example of a failing test on this PR just to have as a reference for the blame later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Can we include the
SchemaErrorinformation in this result?
Pytest will display the exception by default. This is the output you would get for a failing test:
tests/test_json_schema.py F [100%]
tests/test_json_schema.py:6476 test_fails - Failed: Failed to validate the JSON Schema against the Draft 2020-12 spec… [100%]
======================================================================= FAILURES ========================================================================
______________________________________________________________________ test_fails _______________________________________________________________________
args = (<pydantic.json_schema.GenerateJsonSchema object at 0x7b80723f5820>, {'metadata': {'pydantic_js_annotation_functions':...onSchema.__get_pydantic_json_schema__ of WithJsonSchema(json_schema={'type': 'invalid'}, mode=None)>]}, 'type': 'int'})
kwargs = {'mode': 'validation'}, json_schema = {'type': 'invalid'}
def generate(*args: Any, **kwargs: Any) -> Any:
json_schema = orig_generate(*args, **kwargs)
if not request.node.get_closest_marker('skip_json_schema_validation'):
try:
> Draft202012Validator.check_schema(json_schema)
tests/conftest.py:166:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'jsonschema.validators.Draft202012Validator'>, schema = {'type': 'invalid'}
format_checker = <FormatChecker checkers=['date', 'email', 'idn-email', 'idn-hostname', 'ipv4', 'ipv6', 'regex', 'uuid']>
@classmethod
def check_schema(cls, schema, format_checker=_UNSET):
Validator = validator_for(cls.META_SCHEMA, default=cls)
if format_checker is _UNSET:
format_checker = Validator.FORMAT_CHECKER
validator = Validator(
schema=cls.META_SCHEMA,
format_checker=format_checker,
)
for error in validator.iter_errors(schema):
> raise exceptions.SchemaError.create_from(error)
E jsonschema.exceptions.SchemaError: 'invalid' is not valid under any of the given schemas
E
E Failed validating 'anyOf' in metaschema['allOf'][3]['properties']['type']:
E {'anyOf': [{'$ref': '#/$defs/simpleTypes'},
E {'type': 'array',
E 'items': {'$ref': '#/$defs/simpleTypes'},
E 'minItems': 1,
E 'uniqueItems': True}]}
E
E On schema['type']:
E 'invalid'
../../.pyenv/versions/3.12.4/envs/pydanticdev/lib/python3.12/site-packages/jsonschema/validators.py:317: SchemaError
During handling of the above exception, another exception occurred:
def test_fails():
> TypeAdapter(Annotated[int, WithJsonSchema({'type': 'invalid'})]).json_schema()
tests/test_json_schema.py:6478:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
pydantic/type_adapter.py:142: in wrapped
return func(self, *args, **kwargs)
pydantic/type_adapter.py:549: in json_schema
return schema_generator_instance.generate(self.core_schema, mode=mode)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
args = (<pydantic.json_schema.GenerateJsonSchema object at 0x7b80723f5820>, {'metadata': {'pydantic_js_annotation_functions':...onSchema.__get_pydantic_json_schema__ of WithJsonSchema(json_schema={'type': 'invalid'}, mode=None)>]}, 'type': 'int'})
kwargs = {'mode': 'validation'}, json_schema = {'type': 'invalid'}
def generate(*args: Any, **kwargs: Any) -> Any:
json_schema = orig_generate(*args, **kwargs)
if not request.node.get_closest_marker('skip_json_schema_validation'):
try:
Draft202012Validator.check_schema(json_schema)
except SchemaError:
> pytest.fail('Failed to validate the JSON Schema against the Draft 2020-12 spec')
E Failed: Failed to validate the JSON Schema against the Draft 2020-12 spec
tests/conftest.py:168: Failed
Summary of Failures
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ File ┃ Function ┃ Function Line ┃ Error Line ┃ Error ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ tests/test_json_schema.py │ test_fails │ 6477 │ 6478 │ Failed │
└─────────────────────────────┴──────────────┴─────────────────┴──────────────┴──────────┘
Results (1.65s):
1 failed
5846 deselected
2. Could we add a note about the fact that this is purely a testing feature, not a runtime
pydanticcheck (at this point)?
Added.
Perhaps this is a bit excessive, but can we test this test?
Seems like there are ways to do so, but they are pretty involved. I added a test with an expected failure.
1099a43 to
97529e3
Compare
97529e3 to
c39d7da
Compare
sydney-runkle
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, thanks for incorporating the feedback so promptly!

Fixes #10173
Edit: fixes #5164.
Requires:
Examplesclass #10181With the schema validation:
Without:
Change Summary
Related issue number
Checklist