Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-openapi-schema-validator for
openSUSE:Factory checked in at 2026-05-18 17:48:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-openapi-schema-validator (Old)
and /work/SRC/openSUSE:Factory/.python-openapi-schema-validator.new.1966
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-openapi-schema-validator"
Mon May 18 17:48:09 2026 rev:14 rq:1353768 version:0.9.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-openapi-schema-validator/python-openapi-schema-validator.changes
2026-03-16 14:21:16.383113348 +0100
+++
/work/SRC/openSUSE:Factory/.python-openapi-schema-validator.new.1966/python-openapi-schema-validator.changes
2026-05-18 17:49:01.382797543 +0200
@@ -1,0 +2,15 @@
+Mon May 18 09:59:49 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.9.0:
+ * Enforce properties required flag #290
+ * OAS 3.1/3.2 discriminator is annotation-only #279
+ * `OAS31Validator` and `OAS32Validator` no longer use
+ discriminator-driven schema selection for `oneOf`, `anyOf`,
+ or `allOf`.
+ * For OpenAPI 3.1 and 3.2, `discriminator` is now treated as a
+ hint/annotation and does not change validation outcome.
+ * Validation results may change for schemas that previously
+ relied on discriminator-based narrowing or on discriminator
+ mapping resolution errors during validation.
+
+-------------------------------------------------------------------
Old:
----
openapi_schema_validator-0.8.1.tar.gz
New:
----
openapi_schema_validator-0.9.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-openapi-schema-validator.spec ++++++
--- /var/tmp/diff_new_pack.4fMYVo/_old 2026-05-18 17:49:02.066825808 +0200
+++ /var/tmp/diff_new_pack.4fMYVo/_new 2026-05-18 17:49:02.070825974 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-openapi-schema-validator
-Version: 0.8.1
+Version: 0.9.0
Release: 0
Summary: OpenAPI schema validator for Python
License: BSD-3-Clause
++++++ openapi_schema_validator-0.8.1.tar.gz ->
openapi_schema_validator-0.9.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openapi-schema-validator-0.8.1/.github/workflows/docs-build.yml
new/openapi-schema-validator-0.9.0/.github/workflows/docs-build.yml
--- old/openapi-schema-validator-0.8.1/.github/workflows/docs-build.yml
2026-03-02 09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/.github/workflows/docs-build.yml
2026-04-27 19:30:35.000000000 +0200
@@ -47,7 +47,7 @@
run: |
poetry run python -m sphinx -T -b html -d docs/_build/doctrees -D
language=en docs docs/_build/html -n -W
- - uses: actions/upload-artifact@v6
+ - uses: actions/upload-artifact@v7
name: Upload docs as artifact
with:
name: docs-html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openapi-schema-validator-0.8.1/.github/workflows/python-tests.yml
new/openapi-schema-validator-0.9.0/.github/workflows/python-tests.yml
--- old/openapi-schema-validator-0.8.1/.github/workflows/python-tests.yml
2026-03-02 09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/.github/workflows/python-tests.yml
2026-04-27 19:30:35.000000000 +0200
@@ -60,7 +60,7 @@
run: poetry run deptry .
- name: Upload coverage
- uses: codecov/codecov-action@v5
+ uses: codecov/codecov-action@v6
tests_no_extras:
name: "py3.14 no extras"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/openapi-schema-validator-0.8.1/README.rst
new/openapi-schema-validator-0.9.0/README.rst
--- old/openapi-schema-validator-0.8.1/README.rst 2026-03-02
09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/README.rst 2026-04-27
19:30:35.000000000 +0200
@@ -60,6 +60,7 @@
cls=OAS32Validator,
allow_remote_references=False,
check_schema=True,
+ enforce_properties_required=False,
**kwargs,
)
@@ -94,6 +95,12 @@
validating an instance. For trusted pre-validated schemas in hot paths, set
``check_schema=False`` to skip schema checking.
+When ``enforce_properties_required=True`` is passed, all properties declared
+in the schema's ``properties`` object are strictly required to be present in
+the instance (except those marked as ``writeOnly`` or ``readOnly`` where
+appropriate), regardless of the schema's ``required`` array. This is useful for
+response or contract testing to ensure no documented fields are missing.
+
The ``validate`` helper keeps an internal compiled-validator cache. You can
control cache size using the
``OPENAPI_SCHEMA_VALIDATOR_COMPILED_VALIDATOR_CACHE_MAX_SIZE`` environment
variable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/openapi-schema-validator-0.8.1/docs/validation.rst
new/openapi-schema-validator-0.9.0/docs/validation.rst
--- old/openapi-schema-validator-0.8.1/docs/validation.rst 2026-03-02
09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/docs/validation.rst 2026-04-27
19:30:35.000000000 +0200
@@ -16,6 +16,7 @@
cls=OAS32Validator,
allow_remote_references=False,
check_schema=True,
+ enforce_properties_required=False,
**kwargs,
)
@@ -39,6 +40,12 @@
For trusted pre-validated schemas in hot paths, set ``check_schema=False`` to
skip schema checking.
+When ``enforce_properties_required=True`` is passed, all properties declared
+in the schema's ``properties`` object are strictly required to be present in
+the instance (except those marked as ``writeOnly`` or ``readOnly`` where
+appropriate), regardless of the schema's ``required`` array. This is useful for
+response or contract testing to ensure no documented fields are missing.
+
The shortcut keeps an internal compiled-validator cache.
Use ``OPENAPI_SCHEMA_VALIDATOR_COMPILED_VALIDATOR_CACHE_MAX_SIZE`` to control
cache
capacity (default: ``128``).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openapi-schema-validator-0.8.1/openapi_schema_validator/__init__.py
new/openapi-schema-validator-0.9.0/openapi_schema_validator/__init__.py
--- old/openapi-schema-validator-0.8.1/openapi_schema_validator/__init__.py
2026-03-02 09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/openapi_schema_validator/__init__.py
2026-04-27 19:30:35.000000000 +0200
@@ -14,7 +14,7 @@
__author__ = "Artur Maciag"
__email__ = "[email protected]"
-__version__ = "0.8.1"
+__version__ = "0.9.0"
__url__ = "https://github.com/python-openapi/openapi-schema-validator"
__license__ = "3-clause BSD License"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openapi-schema-validator-0.8.1/openapi_schema_validator/shortcuts.py
new/openapi-schema-validator-0.9.0/openapi_schema_validator/shortcuts.py
--- old/openapi-schema-validator-0.8.1/openapi_schema_validator/shortcuts.py
2026-03-02 09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/openapi_schema_validator/shortcuts.py
2026-04-27 19:30:35.000000000 +0200
@@ -12,6 +12,9 @@
from openapi_schema_validator._dialects import OAS31_BASE_DIALECT_ID
from openapi_schema_validator._dialects import OAS32_BASE_DIALECT_ID
from openapi_schema_validator.validators import OAS32Validator
+from openapi_schema_validator.validators import (
+ build_enforce_properties_required_validator,
+)
from openapi_schema_validator.validators import check_openapi_schema
_LOCAL_ONLY_REGISTRY = Registry()
@@ -42,6 +45,7 @@
*args: Any,
allow_remote_references: bool = False,
check_schema: bool = True,
+ enforce_properties_required: bool = False,
**kwargs: Any,
) -> None:
"""
@@ -65,6 +69,11 @@
check_schema: If ``True`` (default), validate the provided schema
before validating ``instance``. If ``False``, skip schema
validation and run instance validation directly.
+ enforce_properties_required: If ``True``, all properties declared in
+ the schema's ``properties`` object are strictly required to be
+ present in the instance (except those marked as ``writeOnly`` or
+ ``readOnly`` where appropriate), regardless of the schema's
+ ``required`` array. Defaults to ``False``.
**kwargs: Keyword arguments forwarded to ``cls`` constructor
(for example ``registry`` and ``format_checker``). If omitted,
a local-only empty ``Registry`` is used to avoid implicit remote
@@ -74,6 +83,9 @@
jsonschema.exceptions.SchemaError: If ``schema`` is invalid.
jsonschema.exceptions.ValidationError: If ``instance`` is invalid.
"""
+ if enforce_properties_required:
+ cls = build_enforce_properties_required_validator(cls) # type:
ignore[arg-type]
+
schema_dict = cast(dict[str, Any], schema)
validator_kwargs = kwargs.copy()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openapi-schema-validator-0.8.1/openapi_schema_validator/validators.py
new/openapi-schema-validator-0.9.0/openapi_schema_validator/validators.py
--- old/openapi-schema-validator-0.8.1/openapi_schema_validator/validators.py
2026-03-02 09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/openapi_schema_validator/validators.py
2026-04-27 19:30:35.000000000 +0200
@@ -1,10 +1,14 @@
+from functools import lru_cache
from typing import Any
+from typing import Iterator
+from typing import Mapping
from typing import cast
from jsonschema import _keywords
from jsonschema import _legacy_keywords
from jsonschema.exceptions import SchemaError
from jsonschema.exceptions import ValidationError
+from jsonschema.protocols import Validator
from jsonschema.validators import Draft202012Validator
from jsonschema.validators import create
from jsonschema.validators import extend
@@ -115,12 +119,10 @@
Draft202012Validator,
{
# adjusted to OAS
- "allOf": oas_keywords.allOf,
- "oneOf": oas_keywords.oneOf,
- "anyOf": oas_keywords.anyOf,
"pattern": oas_keywords.pattern,
"description": oas_keywords.not_implemented,
# fixed OAS fields
+ # discriminator is annotation-only in OAS 3.1+
"discriminator": oas_keywords.not_implemented,
"xml": oas_keywords.not_implemented,
"externalDocs": oas_keywords.not_implemented,
@@ -189,3 +191,47 @@
OAS30Validator.check_schema = classmethod(check_openapi_schema)
OAS31Validator.check_schema = classmethod(check_openapi_schema)
OAS32Validator.check_schema = classmethod(check_openapi_schema)
+
+
+@lru_cache(maxsize=None)
+def build_enforce_properties_required_validator(
+ validator_class: Any,
+) -> type[Validator]:
+ properties_validator = validator_class.VALIDATORS.get("properties")
+ required_validator = validator_class.VALIDATORS.get("required")
+
+ def enforce_properties(
+ validator: Any,
+ properties: Any,
+ instance: Any,
+ schema: Mapping[str, Any],
+ ) -> Iterator[Any]:
+ if properties_validator is not None:
+ yield from properties_validator(
+ validator, properties, instance, schema
+ )
+
+ if not validator.is_type(instance, "object"):
+ return
+
+ if required_validator is not None:
+ schema_required = (
+ schema.get("required", []) if isinstance(schema, dict) else []
+ )
+ missing_props = [
+ p for p in properties.keys() if p not in schema_required
+ ]
+ if missing_props:
+ yield from required_validator(
+ validator, missing_props, instance, schema
+ )
+
+ extended_validator = extend(
+ validator_class,
+ validators={"properties": enforce_properties},
+ )
+ if hasattr(validator_class, "check_schema"):
+ extended_validator.check_schema = classmethod(
+ validator_class.check_schema.__func__
+ )
+ return cast(type[Validator], extended_validator)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/openapi-schema-validator-0.8.1/poetry.lock
new/openapi-schema-validator-0.9.0/poetry.lock
--- old/openapi-schema-validator-0.8.1/poetry.lock 2026-03-02
09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/poetry.lock 2026-04-27
19:30:35.000000000 +0200
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.1.1 and should not be
changed by hand.
+# This file is automatically @generated by Poetry 2.2.1 and should not be
changed by hand.
[[package]]
name = "alabaster"
@@ -65,39 +65,39 @@
[[package]]
name = "black"
-version = "26.1.0"
+version = "26.3.1"
description = "The uncompromising code formatter."
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "black-26.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:ca699710dece84e3ebf6e92ee15f5b8f72870ef984bf944a57a777a48357c168"},
- {file = "black-26.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash =
"sha256:5e8e75dabb6eb83d064b0db46392b25cabb6e784ea624219736e8985a6b3675d"},
- {file =
"black-26.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:eb07665d9a907a1a645ee41a0df8a25ffac8ad9c26cdb557b7b88eeeeec934e0"},
- {file = "black-26.1.0-cp310-cp310-win_amd64.whl", hash =
"sha256:7ed300200918147c963c87700ccf9966dceaefbbb7277450a8d646fc5646bf24"},
- {file = "black-26.1.0-cp310-cp310-win_arm64.whl", hash =
"sha256:c5b7713daea9bf943f79f8c3b46f361cc5229e0e604dcef6a8bb6d1c37d9df89"},
- {file = "black-26.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash =
"sha256:3cee1487a9e4c640dc7467aaa543d6c0097c391dc8ac74eb313f2fbf9d7a7cb5"},
- {file = "black-26.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash =
"sha256:d62d14ca31c92adf561ebb2e5f2741bf8dea28aef6deb400d49cca011d186c68"},
- {file =
"black-26.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:fb1dafbbaa3b1ee8b4550a84425aac8874e5f390200f5502cf3aee4a2acb2f14"},
- {file = "black-26.1.0-cp311-cp311-win_amd64.whl", hash =
"sha256:101540cb2a77c680f4f80e628ae98bd2bd8812fb9d72ade4f8995c5ff019e82c"},
- {file = "black-26.1.0-cp311-cp311-win_arm64.whl", hash =
"sha256:6f3977a16e347f1b115662be07daa93137259c711e526402aa444d7a88fdc9d4"},
- {file = "black-26.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash =
"sha256:6eeca41e70b5f5c84f2f913af857cf2ce17410847e1d54642e658e078da6544f"},
- {file = "black-26.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash =
"sha256:dd39eef053e58e60204f2cdf059e2442e2eb08f15989eefe259870f89614c8b6"},
- {file =
"black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:9459ad0d6cd483eacad4c6566b0f8e42af5e8b583cee917d90ffaa3778420a0a"},
- {file = "black-26.1.0-cp312-cp312-win_amd64.whl", hash =
"sha256:a19915ec61f3a8746e8b10adbac4a577c6ba9851fa4a9e9fbfbcf319887a5791"},
- {file = "black-26.1.0-cp312-cp312-win_arm64.whl", hash =
"sha256:643d27fb5facc167c0b1b59d0315f2674a6e950341aed0fc05cf307d22bf4954"},
- {file = "black-26.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash =
"sha256:ba1d768fbfb6930fc93b0ecc32a43d8861ded16f47a40f14afa9bb04ab93d304"},
- {file = "black-26.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash =
"sha256:2b807c240b64609cb0e80d2200a35b23c7df82259f80bef1b2c96eb422b4aac9"},
- {file =
"black-26.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:1de0f7d01cc894066a1153b738145b194414cc6eeaad8ef4397ac9abacf40f6b"},
- {file = "black-26.1.0-cp313-cp313-win_amd64.whl", hash =
"sha256:91a68ae46bf07868963671e4d05611b179c2313301bd756a89ad4e3b3db2325b"},
- {file = "black-26.1.0-cp313-cp313-win_arm64.whl", hash =
"sha256:be5e2fe860b9bd9edbf676d5b60a9282994c03fbbd40fe8f5e75d194f96064ca"},
- {file = "black-26.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash =
"sha256:9dc8c71656a79ca49b8d3e2ce8103210c9481c57798b48deeb3a8bb02db5f115"},
- {file = "black-26.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash =
"sha256:b22b3810451abe359a964cc88121d57f7bce482b53a066de0f1584988ca36e79"},
- {file =
"black-26.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:53c62883b3f999f14e5d30b5a79bd437236658ad45b2f853906c7cbe79de00af"},
- {file = "black-26.1.0-cp314-cp314-win_amd64.whl", hash =
"sha256:f016baaadc423dc960cdddf9acae679e71ee02c4c341f78f3179d7e4819c095f"},
- {file = "black-26.1.0-cp314-cp314-win_arm64.whl", hash =
"sha256:66912475200b67ef5a0ab665011964bf924745103f51977a78b4fb92a9fc1bf0"},
- {file = "black-26.1.0-py3-none-any.whl", hash =
"sha256:1054e8e47ebd686e078c0bb0eaf31e6ce69c966058d122f2c0c950311f9f3ede"},
- {file = "black-26.1.0.tar.gz", hash =
"sha256:d294ac3340eef9c9eb5d29288e96dc719ff269a88e27b396340459dd85da4c58"},
+ {file = "black-26.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash =
"sha256:86a8b5035fce64f5dcd1b794cf8ec4d31fe458cf6ce3986a30deb434df82a1d2"},
+ {file = "black-26.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash =
"sha256:5602bdb96d52d2d0672f24f6ffe5218795736dd34807fd0fd55ccd6bf206168b"},
+ {file =
"black-26.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:6c54a4a82e291a1fee5137371ab488866b7c86a3305af4026bdd4dc78642e1ac"},
+ {file = "black-26.3.1-cp310-cp310-win_amd64.whl", hash =
"sha256:6e131579c243c98f35bce64a7e08e87fb2d610544754675d4a0e73a070a5aa3a"},
+ {file = "black-26.3.1-cp310-cp310-win_arm64.whl", hash =
"sha256:5ed0ca58586c8d9a487352a96b15272b7fa55d139fc8496b519e78023a8dab0a"},
+ {file = "black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash =
"sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff"},
+ {file = "black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash =
"sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c"},
+ {file =
"black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5"},
+ {file = "black-26.3.1-cp311-cp311-win_amd64.whl", hash =
"sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e"},
+ {file = "black-26.3.1-cp311-cp311-win_arm64.whl", hash =
"sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5"},
+ {file = "black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash =
"sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1"},
+ {file = "black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash =
"sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f"},
+ {file =
"black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7"},
+ {file = "black-26.3.1-cp312-cp312-win_amd64.whl", hash =
"sha256:ddb113db38838eb9f043623ba274cfaf7d51d5b0c22ecb30afe58b1bb8322983"},
+ {file = "black-26.3.1-cp312-cp312-win_arm64.whl", hash =
"sha256:dfdd51fc3e64ea4f35873d1b3fb25326773d55d2329ff8449139ebaad7357efb"},
+ {file = "black-26.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash =
"sha256:855822d90f884905362f602880ed8b5df1b7e3ee7d0db2502d4388a954cc8c54"},
+ {file = "black-26.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash =
"sha256:8a33d657f3276328ce00e4d37fe70361e1ec7614da5d7b6e78de5426cb56332f"},
+ {file =
"black-26.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:f1cd08e99d2f9317292a311dfe578fd2a24b15dbce97792f9c4d752275c1fa56"},
+ {file = "black-26.3.1-cp313-cp313-win_amd64.whl", hash =
"sha256:c7e72339f841b5a237ff14f7d3880ddd0fc7f98a1199e8c4327f9a4f478c1839"},
+ {file = "black-26.3.1-cp313-cp313-win_arm64.whl", hash =
"sha256:afc622538b430aa4c8c853f7f63bc582b3b8030fd8c80b70fb5fa5b834e575c2"},
+ {file = "black-26.3.1-cp314-cp314-macosx_10_15_x86_64.whl", hash =
"sha256:2d6bfaf7fd0993b420bed691f20f9492d53ce9a2bcccea4b797d34e947318a78"},
+ {file = "black-26.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash =
"sha256:f89f2ab047c76a9c03f78d0d66ca519e389519902fa27e7a91117ef7611c0568"},
+ {file =
"black-26.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl",
hash =
"sha256:b07fc0dab849d24a80a29cfab8d8a19187d1c4685d8a5e6385a5ce323c1f015f"},
+ {file = "black-26.3.1-cp314-cp314-win_amd64.whl", hash =
"sha256:0126ae5b7c09957da2bdbd91a9ba1207453feada9e9fe51992848658c6c8e01c"},
+ {file = "black-26.3.1-cp314-cp314-win_arm64.whl", hash =
"sha256:92c0ec1f2cc149551a2b7b47efc32c866406b6891b0ee4625e95967c8f4acfb1"},
+ {file = "black-26.3.1-py3-none-any.whl", hash =
"sha256:2bd5aa94fc267d38bb21a70d7410a89f1a1d318841855f698746f8e7f51acd1b"},
+ {file = "black-26.3.1.tar.gz", hash =
"sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07"},
]
[package.dependencies]
@@ -106,7 +106,7 @@
packaging = ">=22.0"
pathspec = ">=1.0.0"
platformdirs = ">=2"
-pytokens = ">=0.3.0"
+pytokens = ">=0.4.0,<0.5.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.0.1", markers = "python_version <
\"3.11\""}
@@ -114,7 +114,7 @@
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.10)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
-uvloop = ["uvloop (>=0.15.2)"]
+uvloop = ["uvloop (>=0.15.2) ; sys_platform != \"win32\"", "winloop (>=0.5.0)
; sys_platform == \"win32\""]
[[package]]
name = "certifi"
@@ -122,7 +122,7 @@
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
-groups = ["docs"]
+groups = ["dev", "docs"]
files = [
{file = "certifi-2026.1.4-py3-none-any.whl", hash =
"sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c"},
{file = "certifi-2026.1.4.tar.gz", hash =
"sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120"},
@@ -146,7 +146,7 @@
description = "The Real First Universal Charset Detector. Open, modern and
actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7"
-groups = ["docs"]
+groups = ["dev", "docs"]
files = [
{file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl",
hash =
"sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"},
{file =
"charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl",
hash =
"sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"},
@@ -432,28 +432,28 @@
[[package]]
name = "deptry"
-version = "0.24.0"
+version = "0.25.1"
description = "A command line utility to check for unused, missing and
transitive dependencies in a Python project."
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "deptry-0.24.0-cp39-abi3-macosx_10_12_x86_64.whl", hash =
"sha256:a575880146bab671a62babb9825b85b4f1bda8aeaade4fcb59f9262caf91d6c7"},
- {file = "deptry-0.24.0-cp39-abi3-macosx_11_0_arm64.whl", hash =
"sha256:00ec34b968a13c03a5268ce0211f891ace31851d916415e0a748fae9596c00d5"},
- {file =
"deptry-0.24.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:6ddfedafafe5cbfce31a50d4ea99d7b9074edcd08b9b94350dc739e2fb6ed7f9"},
- {file =
"deptry-0.24.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:dd22fa2dbbdf4b38061ca9504f2a6ce41ec14fa5c9fe9b0b763ccc1275efebd5"},
- {file = "deptry-0.24.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash =
"sha256:0fbe50a2122d79cec53fdfd73a7092c05f316555a1139bcbacf3432572675977"},
- {file = "deptry-0.24.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash =
"sha256:92bd8d331a5a6f8e6247436bc6fe384bcf86a8d69fe33442d195996fb9b20547"},
- {file = "deptry-0.24.0-cp39-abi3-win_amd64.whl", hash =
"sha256:94b354848130d45e16d3a3039ae8177bce33828f62028c4ff8f2e1b04f7182ba"},
- {file = "deptry-0.24.0-cp39-abi3-win_arm64.whl", hash =
"sha256:ea58709e5f3aa77c0737d8fb76166b7703201cf368fbbb14072ccda968b6703a"},
- {file = "deptry-0.24.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash =
"sha256:6ae96785aaee5540c144306506f1480dcfa4d096094e6bd09dc8c9a9bfda1d46"},
- {file = "deptry-0.24.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash =
"sha256:4267d74a600ac7fdd05a0d3e219c9386670db0d3bb316ae7b94c9b239d1187cb"},
- {file =
"deptry-0.24.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:3a047e53b76c36737f8bb392bb326fb66c6af4bedafeaa4ad274c7ed82e91862"},
- {file =
"deptry-0.24.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:841bf35d62e1facc0c244b9430455705249cc93552ed4964d367befe9be6a313"},
- {file = "deptry-0.24.0-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash
= "sha256:5152ffa478e62f9aea9df585ce49d758087fd202f6d92012216aa0ecad22c267"},
- {file = "deptry-0.24.0-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash
= "sha256:68d90735042c169e2a12846ac5af9e20d0ad1a5a7a894a9e4eb0bd8f3c655add"},
- {file = "deptry-0.24.0-pp311-pypy311_pp73-win_amd64.whl", hash =
"sha256:03d375db3e56821803aeca665dbb4c2fd935024310350cc18e8d8b6421369d2b"},
- {file = "deptry-0.24.0.tar.gz", hash =
"sha256:852e88af2087e03cdf9ece6916f3f58b74191ab51cc8074897951bd496ee7dbb"},
+ {file = "deptry-0.25.1-cp310-abi3-macosx_10_12_x86_64.whl", hash =
"sha256:a4dd1148db24a1ddacfa8b840836c6019c2f864fcb7579dd089fd217606338c8"},
+ {file = "deptry-0.25.1-cp310-abi3-macosx_11_0_arm64.whl", hash =
"sha256:c67c666d916ef12013c0772e40d78be0f21577a495d8d99ec5fcb18c332d393d"},
+ {file =
"deptry-0.25.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:58d39279828dbf4efc1abb40bf50a71b21499c36759bed5a8d8a3c0e3149b091"},
+ {file =
"deptry-0.25.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash
= "sha256:14bfcc28b4326ed8c6abb30691b19077d4ef8613cfba6c37ef5b1f471775bf6f"},
+ {file = "deptry-0.25.1-cp310-abi3-musllinux_1_1_aarch64.whl", hash =
"sha256:555f5f9a487899ec9bf301eecba1745e14d212c4b354f4d3a5fd691e907366d3"},
+ {file = "deptry-0.25.1-cp310-abi3-musllinux_1_1_x86_64.whl", hash =
"sha256:18d21b3545ab2bfec53f3f45c6f5f201d55f713323327f8d12674505469ae6b7"},
+ {file = "deptry-0.25.1-cp310-abi3-win_amd64.whl", hash =
"sha256:b59a560cb7dffb21832a98bb80d33d614cfb5630ea36ce21833eabf4eae3df99"},
+ {file = "deptry-0.25.1-cp310-abi3-win_arm64.whl", hash =
"sha256:6efffd8116fb9d2c45a251382ce4ce1c38dbb17179f581ec9231ed5390f7fc12"},
+ {file = "deptry-0.25.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash =
"sha256:30d64d4df1c08bc69de56cb0b4ec1f4cd9fa2e42582347d5b1eb25fd0e401745"},
+ {file = "deptry-0.25.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash =
"sha256:87bcd90f99a98bb059c7580bc315c3f87d97fe2db725530030bc974176834735"},
+ {file =
"deptry-0.25.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
hash =
"sha256:80f31eb5c520651b102568dd91f738222b250a3e44c9e95d4941322109b8d40a"},
+ {file =
"deptry-0.25.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
hash =
"sha256:df88952a2bab7517ef23cb304b979199b28449e5d9db2e9ba9bc27a286ac852b"},
+ {file = "deptry-0.25.1-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash
= "sha256:e6f7b8fa72932e51e86799b10dcd29381b2132dc799c790dca3b28ab08dffb28"},
+ {file = "deptry-0.25.1-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash
= "sha256:e3fa3321078e11cd1ac3f10ce3ff0547731c53f9253b87c757a8749c76fe8fa9"},
+ {file = "deptry-0.25.1-pp311-pypy311_pp73-win_amd64.whl", hash =
"sha256:03c032c32492fde434736954fbcaff09c02bf207b0f793b77e9040300e34b344"},
+ {file = "deptry-0.25.1.tar.gz", hash =
"sha256:45c8cd982c85cd4faae573ddff6920de7eec735336db6973f26a765ae7950f7d"},
]
[package.dependencies]
@@ -461,7 +461,7 @@
colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""}
packaging = ">=23.2"
requirements-parser = ">=0.11.0,<1"
-tomli = {version = ">=2.0.1", markers = "python_full_version < \"3.11.0\""}
+tomli = {version = ">=2.0.1", markers = "python_full_version < \"3.15.0\""}
[[package]]
name = "distlib"
@@ -585,7 +585,7 @@
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.8"
-groups = ["docs"]
+groups = ["dev", "docs"]
files = [
{file = "idna-3.11-py3-none-any.whl", hash =
"sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"},
{file = "idna-3.11.tar.gz", hash =
"sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"},
@@ -620,14 +620,14 @@
[[package]]
name = "isort"
-version = "8.0.0"
+version = "8.0.1"
description = "A Python utility / library to sort Python imports."
optional = false
python-versions = ">=3.10.0"
groups = ["dev"]
files = [
- {file = "isort-8.0.0-py3-none-any.whl", hash =
"sha256:184916a933041c7cf718787f7e52064f3c06272aff69a5cb4dc46497bd8911d9"},
- {file = "isort-8.0.0.tar.gz", hash =
"sha256:fddea59202f231e170e52e71e3510b99c373b6e571b55d9c7b31b679c0fed47c"},
+ {file = "isort-8.0.1-py3-none-any.whl", hash =
"sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75"},
+ {file = "isort-8.0.1.tar.gz", hash =
"sha256:171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d"},
]
[package.extras]
@@ -1294,14 +1294,14 @@
[[package]]
name = "pygments"
-version = "2.19.2"
+version = "2.20.0"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
groups = ["dev", "docs"]
files = [
- {file = "pygments-2.19.2-py3-none-any.whl", hash =
"sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"},
- {file = "pygments-2.19.2.tar.gz", hash =
"sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"},
+ {file = "pygments-2.20.0-py3-none-any.whl", hash =
"sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"},
+ {file = "pygments-2.20.0.tar.gz", hash =
"sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"},
]
[package.extras]
@@ -1309,14 +1309,14 @@
[[package]]
name = "pytest"
-version = "9.0.2"
+version = "9.0.3"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "pytest-9.0.2-py3-none-any.whl", hash =
"sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"},
- {file = "pytest-9.0.2.tar.gz", hash =
"sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"},
+ {file = "pytest-9.0.3-py3-none-any.whl", hash =
"sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"},
+ {file = "pytest-9.0.3.tar.gz", hash =
"sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"},
]
[package.dependencies]
@@ -1333,14 +1333,14 @@
[[package]]
name = "pytest-cov"
-version = "7.0.0"
+version = "7.1.0"
description = "Pytest plugin for measuring coverage."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "pytest_cov-7.0.0-py3-none-any.whl", hash =
"sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861"},
- {file = "pytest_cov-7.0.0.tar.gz", hash =
"sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1"},
+ {file = "pytest_cov-7.1.0-py3-none-any.whl", hash =
"sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678"},
+ {file = "pytest_cov-7.1.0.tar.gz", hash =
"sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2"},
]
[package.dependencies]
@@ -1677,25 +1677,26 @@
[[package]]
name = "requests"
-version = "2.32.5"
+version = "2.33.0"
description = "Python HTTP for Humans."
optional = false
-python-versions = ">=3.9"
-groups = ["docs"]
+python-versions = ">=3.10"
+groups = ["dev", "docs"]
files = [
- {file = "requests-2.32.5-py3-none-any.whl", hash =
"sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"},
- {file = "requests-2.32.5.tar.gz", hash =
"sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"},
+ {file = "requests-2.33.0-py3-none-any.whl", hash =
"sha256:3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b"},
+ {file = "requests-2.33.0.tar.gz", hash =
"sha256:c7ebc5e8b0f21837386ad0e1c8fe8b829fa5f544d8df3b2253bff14ef29d7652"},
]
[package.dependencies]
-certifi = ">=2017.4.17"
+certifi = ">=2023.5.7"
charset_normalizer = ">=2,<4"
idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
+urllib3 = ">=1.26,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+test = ["PySocks (>=1.5.6,!=1.5.7)", "pytest (>=3)", "pytest-cov",
"pytest-httpbin (==2.1.0)", "pytest-mock", "pytest-xdist"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<8)"]
[[package]]
name = "requirements-parser"
@@ -2141,7 +2142,7 @@
{file = "tomli-2.4.0-py3-none-any.whl", hash =
"sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"},
{file = "tomli-2.4.0.tar.gz", hash =
"sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"},
]
-markers = {dev = "python_full_version <= \"3.11.0a6\"", docs = "python_version
< \"3.11\""}
+markers = {dev = "python_version < \"3.15\"", docs = "python_version <
\"3.11\""}
[[package]]
name = "tomlkit"
@@ -2200,7 +2201,7 @@
description = "HTTP library with thread-safe connection pooling, file post,
and more."
optional = false
python-versions = ">=3.9"
-groups = ["docs"]
+groups = ["dev", "docs"]
files = [
{file = "urllib3-2.6.3-py3-none-any.whl", hash =
"sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"},
{file = "urllib3-2.6.3.tar.gz", hash =
"sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"},
@@ -2241,4 +2242,4 @@
[metadata]
lock-version = "2.1"
python-versions = "^3.10.0"
-content-hash =
"8fe026e86eb5cc5fca2b05d1f0b4c3313eca02c7eebb30bff216d1d381a95ee7"
+content-hash =
"96cf4e09bdcae07474f44bd3de949b358cf8bb865f49ba4d34f3d1233c618652"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/openapi-schema-validator-0.8.1/pyproject.toml
new/openapi-schema-validator-0.9.0/pyproject.toml
--- old/openapi-schema-validator-0.8.1/pyproject.toml 2026-03-02
09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/pyproject.toml 2026-04-27
19:30:35.000000000 +0200
@@ -36,7 +36,7 @@
github_url = "https://github.com/python-openapi/openapi-schema-validator"
[tool.tbump.version]
-current = "0.8.1"
+current = "0.9.0"
regex = '''
(?P<major>\d+)
\.
@@ -57,7 +57,7 @@
[tool.poetry]
name = "openapi-schema-validator"
-version = "0.8.1"
+version = "0.9.0"
description = "OpenAPI schema validation for Python"
authors = ["Artur Maciag <[email protected]>"]
license = "BSD-3-Clause"
@@ -105,7 +105,7 @@
pytest-cov = "*"
mypy = "^1.14"
flynt = "^1.0"
-deptry = ">=0.16.2,<0.25.0"
+deptry = ">=0.16.2,<0.26.0"
tbump = "^6.11.0"
[tool.poetry.group.docs.dependencies]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openapi-schema-validator-0.8.1/tests/integration/test_validators.py
new/openapi-schema-validator-0.9.0/tests/integration/test_validators.py
--- old/openapi-schema-validator-0.8.1/tests/integration/test_validators.py
2026-03-02 09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/tests/integration/test_validators.py
2026-04-27 19:30:35.000000000 +0200
@@ -1107,6 +1107,79 @@
]
assert any(error in str(excinfo.value) for error in errors)
+ def test_discriminator_is_annotation_only(self, validator_class):
+ schema = {
+ "components": {
+ "schemas": {
+ "A": {
+ "type": "object",
+ "properties": {"kind": {"type": "string"}},
+ "required": ["kind"],
+ },
+ "B": {
+ "type": "object",
+ "properties": {
+ "kind": {"type": "string"},
+ "other": {"type": "string"},
+ },
+ "required": ["kind"],
+ },
+ }
+ },
+ "oneOf": [
+ {"$ref": "#/components/schemas/A"},
+ {"$ref": "#/components/schemas/B"},
+ ],
+ "discriminator": {"propertyName": "kind"},
+ }
+
+ validator = validator_class(schema)
+
+ # A payload valid for both schemas A and B
+ instance = {"kind": "B"}
+
+ # oneOf fails because it matches BOTH A and B, discriminator does not
restrict it
+ with pytest.raises(ValidationError):
+ validator.validate(instance)
+
+ @pytest.mark.parametrize(
+ "mapping_ref",
+ [
+ "#/components/schemas/Missing",
+ "#missing-anchor",
+ "#bad/frag",
+ ],
+ )
+ def test_discriminator_unresolvable_reference_ignored(
+ self, validator_class, mapping_ref
+ ):
+ schema = {
+ "oneOf": [{"$ref": "#/components/schemas/MountainHiking"}],
+ "discriminator": {
+ "propertyName": "discipline",
+ "mapping": {"mountain_hiking": mapping_ref},
+ },
+ "components": {
+ "schemas": {
+ "MountainHiking": {
+ "type": "object",
+ "properties": {
+ "discipline": {"type": "string"},
+ "length": {"type": "integer"},
+ },
+ "required": ["discipline", "length"],
+ },
+ },
+ },
+ }
+
+ validator = validator_class(schema)
+
+ # It should not raise any referencing errors because discriminator
mapping is annotation-only
+ validator.validate(
+ {"discipline": "mountain_hiking", "length": 10},
+ )
+
class TestOAS32ValidatorValidate(TestOAS31ValidatorValidate):
"""OAS 3.2 uses the OAS 3.2 published dialect resources."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/openapi-schema-validator-0.8.1/tests/unit/test_shortcut.py
new/openapi-schema-validator-0.9.0/tests/unit/test_shortcut.py
--- old/openapi-schema-validator-0.8.1/tests/unit/test_shortcut.py
2026-03-02 09:45:02.000000000 +0100
+++ new/openapi-schema-validator-0.9.0/tests/unit/test_shortcut.py
2026-04-27 19:30:35.000000000 +0200
@@ -13,6 +13,11 @@
from openapi_schema_validator._regex import has_ecma_regex
from openapi_schema_validator.settings import reset_settings_cache
from openapi_schema_validator.shortcuts import clear_validate_cache
+from openapi_schema_validator.validators import OAS30ReadValidator
+from openapi_schema_validator.validators import OAS30Validator
+from openapi_schema_validator.validators import OAS30WriteValidator
+from openapi_schema_validator.validators import OAS31Validator
+from openapi_schema_validator.validators import OAS32Validator
@pytest.fixture(scope="function")
@@ -195,3 +200,186 @@
validate("foo", schema_a, cls=OAS32Validator)
assert check_schema_mock.call_count == 3
+
+
[email protected](
+ "schema, cls, instance, enforce, expected_error",
+ [
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string"},
+ "nickname": {"type": "string"},
+ },
+ "required": ["id"],
+ },
+ OAS30Validator,
+ {"id": "42"},
+ False,
+ None,
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string"},
+ "nickname": {"type": "string"},
+ },
+ "required": ["id"],
+ },
+ OAS30Validator,
+ {"id": "42"},
+ True,
+ "'nickname' is a required property",
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string", "readOnly": True},
+ "password": {"type": "string", "writeOnly": True},
+ "normal": {"type": "string"},
+ },
+ },
+ OAS30ReadValidator,
+ {"id": "123"},
+ True,
+ "'normal' is a required property",
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string", "readOnly": True},
+ "password": {"type": "string", "writeOnly": True},
+ "normal": {"type": "string"},
+ },
+ },
+ OAS30ReadValidator,
+ {"normal": "abc"},
+ True,
+ "'id' is a required property",
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string", "readOnly": True},
+ "password": {"type": "string", "writeOnly": True},
+ "normal": {"type": "string"},
+ },
+ },
+ OAS30ReadValidator,
+ {"id": "123", "normal": "abc"},
+ True,
+ None,
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string", "readOnly": True},
+ "password": {"type": "string", "writeOnly": True},
+ "normal": {"type": "string"},
+ },
+ },
+ OAS30WriteValidator,
+ {"normal": "abc"},
+ True,
+ "'password' is a required property",
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string", "readOnly": True},
+ "password": {"type": "string", "writeOnly": True},
+ "normal": {"type": "string"},
+ },
+ },
+ OAS30WriteValidator,
+ {"password": "secret"},
+ True,
+ "'normal' is a required property",
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "id": {"type": "string", "readOnly": True},
+ "password": {"type": "string", "writeOnly": True},
+ "normal": {"type": "string"},
+ },
+ },
+ OAS30WriteValidator,
+ {"password": "secret", "normal": "abc"},
+ True,
+ None,
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "foo": True,
+ },
+ },
+ OAS31Validator,
+ {},
+ False,
+ None,
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "foo": True,
+ },
+ },
+ OAS31Validator,
+ {},
+ True,
+ "'foo' is a required property",
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "foo": {"type": "string"},
+ },
+ },
+ OAS32Validator,
+ {},
+ False,
+ None,
+ ),
+ (
+ {
+ "type": "object",
+ "properties": {
+ "foo": {"type": "string"},
+ },
+ },
+ OAS32Validator,
+ {},
+ True,
+ "'foo' is a required property",
+ ),
+ ],
+)
+def test_enforce_properties_required(
+ schema, cls, instance, enforce, expected_error
+):
+ if expected_error:
+ with pytest.raises(ValidationError) as exc:
+ validate(
+ instance,
+ schema,
+ cls=cls,
+ enforce_properties_required=enforce,
+ )
+ assert expected_error in str(exc.value)
+ else:
+ validate(
+ instance, schema, cls=cls, enforce_properties_required=enforce
+ )