From e2c3a06301b119b5749968a55e494ee2cabf0ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Thu, 22 Dec 2022 09:35:11 +0100 Subject: [PATCH 001/212] Add typing to some methods of ``_Error`` --- jsonschema/exceptions.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 149d83890..e46d3defc 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -6,7 +6,7 @@ from collections import defaultdict, deque from pprint import pformat from textwrap import dedent, indent -from typing import ClassVar +from typing import TYPE_CHECKING, Any, ClassVar import heapq import itertools @@ -14,6 +14,9 @@ from jsonschema import _utils +if TYPE_CHECKING: + from jsonschema import _types + WEAK_MATCHES: frozenset[str] = frozenset(["anyOf", "oneOf"]) STRONG_MATCHES: frozenset[str] = frozenset() @@ -66,10 +69,10 @@ def __init__( for error in context: error.parent = self - def __repr__(self): + def __repr__(self) -> str: return f"<{self.__class__.__name__}: {self.message!r}>" - def __str__(self): + def __str__(self) -> str: essential_for_verbose = ( self.validator, self.validator_value, self.instance, self.schema, ) @@ -99,11 +102,11 @@ def __str__(self): ) @classmethod - def create_from(cls, other): + def create_from(cls, other: _Error): return cls(**other._contents()) @property - def absolute_path(self): + def absolute_path(self) -> deque[str | int]: parent = self.parent if parent is None: return self.relative_path @@ -113,7 +116,7 @@ def absolute_path(self): return path @property - def absolute_schema_path(self): + def absolute_schema_path(self) -> deque[str | int]: parent = self.parent if parent is None: return self.relative_schema_path @@ -123,7 +126,7 @@ def absolute_schema_path(self): return path @property - def json_path(self): + def json_path(self) -> str: path = "$" for elem in self.absolute_path: if isinstance(elem, int): @@ -132,7 +135,11 @@ def json_path(self): path += "." + elem return path - def _set(self, type_checker=None, **kwargs): + def _set( + self, + type_checker: _types.TypeChecker | None = None, + **kwargs: Any, + ) -> None: if type_checker is not None and self._type_checker is _unset: self._type_checker = type_checker @@ -188,7 +195,7 @@ class RefResolutionError(Exception): _cause = attr.ib() - def __str__(self): + def __str__(self) -> str: return str(self._cause) @@ -197,10 +204,10 @@ class UndefinedTypeCheck(Exception): A type checker was asked to check a type it did not have registered. """ - def __init__(self, type): + def __init__(self, type: str) -> None: self.type = type - def __str__(self): + def __str__(self) -> str: return f"Type {self.type!r} is unknown to this type checker" From efa28c690074fe597aea039caa8831b45cf11102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Thu, 22 Dec 2022 09:54:35 +0100 Subject: [PATCH 002/212] Add typing and check to ``_Error._matches_type`` --- jsonschema/exceptions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index e46d3defc..c3a1aa2cd 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -154,12 +154,16 @@ def _contents(self): ) return dict((attr, getattr(self, attr)) for attr in attrs) - def _matches_type(self): + def _matches_type(self) -> bool: try: - expected = self.schema["type"] + # We ignore this as we want to simply crash if this happens + expected = self.schema["type"] # type: ignore[index] except (KeyError, TypeError): return False + if isinstance(self._type_checker, _utils.Unset): + return False + if isinstance(expected, str): return self._type_checker.is_type(self.instance, expected) From 7fd4d38f3bc124e3b493443431c85a75cabf3b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Noord?= <13665637+DanielNoord@users.noreply.github.com> Date: Thu, 22 Dec 2022 09:54:45 +0100 Subject: [PATCH 003/212] Add typing to ``_Error.__init__`` --- jsonschema/exceptions.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index c3a1aa2cd..29863232b 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections import defaultdict, deque +from collections.abc import Iterable, Mapping from pprint import pformat from textwrap import dedent, indent from typing import TYPE_CHECKING, Any, ClassVar @@ -31,17 +32,17 @@ class _Error(Exception): def __init__( self, message: str, - validator=_unset, - path=(), - cause=None, + validator: str | _utils.Unset = _unset, + path: Iterable[str | int] = (), + cause: Exception | None = None, context=(), validator_value=_unset, - instance=_unset, - schema=_unset, - schema_path=(), - parent=None, - type_checker=_unset, - ): + instance: Any = _unset, + schema: Mapping[str, Any] | bool | _utils.Unset = _unset, + schema_path: Iterable[str | int] = (), + parent: _Error | None = None, + type_checker: _types.TypeChecker | _utils.Unset = _unset, + ) -> None: super(_Error, self).__init__( message, validator, From 32106fd24edaae1fc3082969d3838d2c69eff670 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 19:30:30 +0000 Subject: [PATCH 004/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.2 → v0.4.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.2...v0.4.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 50b548389..79b6f6de3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.2" + rev: "v0.4.3" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 124d6de0ca41558b212980f26fba9291c0b09ee2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 19:26:03 +0000 Subject: [PATCH 005/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.3 → v0.4.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.3...v0.4.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 79b6f6de3..7f0fb2a1d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.3" + rev: "v0.4.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 9df3ab01c275d1a6cf46a95c7b7e90942cbef162 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 20 May 2024 18:25:27 +0300 Subject: [PATCH 006/212] Update requirements. --- docs/requirements.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 6b44e8ebb..df1cb66e1 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -8,13 +8,13 @@ alabaster==0.7.16 # via sphinx anyascii==0.3.2 # via sphinx-autoapi -astroid==3.1.0 +astroid==3.2.2 # via sphinx-autoapi attrs==23.2.0 # via # jsonschema # referencing -babel==2.14.0 +babel==2.15.0 # via sphinx beautifulsoup4==4.12.3 # via furo @@ -24,13 +24,13 @@ charset-normalizer==3.3.2 # via requests docutils==0.21.2 # via sphinx -furo==2024.4.27 +furo==2024.5.6 # via -r docs/requirements.in idna==3.7 # via requests imagesize==1.4.1 # via sphinx -jinja2==3.1.3 +jinja2==3.1.4 # via # sphinx # sphinx-autoapi @@ -38,7 +38,7 @@ file:.#egg=jsonschema # via -r docs/requirements.in jsonschema-specifications==2023.12.1 # via jsonschema -lxml==5.2.1 +lxml==5.2.2 # via # -r docs/requirements.in # sphinx-json-schema-spec @@ -50,19 +50,19 @@ pyenchant==3.3.0rc1 # via # -r docs/requirements.in # sphinxcontrib-spelling -pygments==2.17.2 +pygments==2.18.0 # via # furo # sphinx pyyaml==6.0.1 # via sphinx-autoapi -referencing==0.35.0 +referencing==0.35.1 # via # jsonschema # jsonschema-specifications requests==2.31.0 # via sphinx -rpds-py==0.18.0 +rpds-py==0.18.1 # via # jsonschema # referencing From d68a2c2a59c8c4361bfce6b61c183e779b7c6b77 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 19:27:35 +0000 Subject: [PATCH 007/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.4 → v0.4.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.4...v0.4.5) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7f0fb2a1d..be5e6e1fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.4" + rev: "v0.4.5" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 6a16e61ccadf74fc7438f5d8d1d6c129a63d7d07 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 3 Jun 2024 12:00:24 +0300 Subject: [PATCH 008/212] Minor workflow trigger tweaking. --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb3b232ce..99449fd0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,12 +2,17 @@ name: CI on: push: + branches-ignore: + - "wip*" + tags: + - "v*" pull_request: release: types: [published] schedule: # Daily at 3:21 - cron: "21 3 * * *" + workflow_dispatch: env: PIP_DISABLE_PIP_VERSION_CHECK: "1" From adc71541f1e9286dd4deb4cabd5075e087ee0bc6 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 3 Jun 2024 12:01:10 +0300 Subject: [PATCH 009/212] Update docs requirements. --- docs/requirements.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index df1cb66e1..3db278783 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -6,8 +6,6 @@ # alabaster==0.7.16 # via sphinx -anyascii==0.3.2 - # via sphinx-autoapi astroid==3.2.2 # via sphinx-autoapi attrs==23.2.0 @@ -18,7 +16,7 @@ babel==2.15.0 # via sphinx beautifulsoup4==4.12.3 # via furo -certifi==2024.2.2 +certifi==2024.6.2 # via requests charset-normalizer==3.3.2 # via requests @@ -60,7 +58,7 @@ referencing==0.35.1 # via # jsonschema # jsonschema-specifications -requests==2.31.0 +requests==2.32.3 # via sphinx rpds-py==0.18.1 # via @@ -81,7 +79,7 @@ sphinx==7.3.7 # sphinx-json-schema-spec # sphinxcontrib-spelling # sphinxext-opengraph -sphinx-autoapi==3.0.0 +sphinx-autoapi==3.1.1 # via -r docs/requirements.in sphinx-autodoc-typehints==2.1.0 # via -r docs/requirements.in From 5c300db2a80e410aa4a9598ac64d00bd32e936a4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 19:35:14 +0000 Subject: [PATCH 010/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.5 → v0.4.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.5...v0.4.7) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index be5e6e1fd..3a970f239 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.5" + rev: "v0.4.7" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 0151efd061d7a0dd324d83351ddfd7392dc5505f Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 5 Jun 2024 09:50:00 +0300 Subject: [PATCH 011/212] Loosen the type for error paths. --- jsonschema/exceptions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index de66e9f9c..1f1d7c011 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -17,7 +17,7 @@ from jsonschema import _utils if TYPE_CHECKING: - from collections.abc import Iterable, Mapping, MutableMapping + from collections.abc import Iterable, Mapping, MutableMapping, Sequence from jsonschema import _types @@ -121,7 +121,7 @@ def create_from(cls, other: _Error): return cls(**other._contents()) @property - def absolute_path(self) -> deque[str | int]: + def absolute_path(self) -> Sequence[str | int]: parent = self.parent if parent is None: return self.relative_path @@ -131,7 +131,7 @@ def absolute_path(self) -> deque[str | int]: return path @property - def absolute_schema_path(self) -> deque[str | int]: + def absolute_schema_path(self) -> Sequence[str | int]: parent = self.parent if parent is None: return self.relative_schema_path From 0024b584c6b6f332f0f5fa5452488901b73328f9 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 5 Jun 2024 09:58:29 +0300 Subject: [PATCH 012/212] Remove references to Unset in the typing annotations. I don't want them appearing in public documentation. The public types of these arguments do not include Unset, a user may only pass them the declared type, even though internally the type is larger. Refs: https://github.com/python-jsonschema/jsonschema/pull/1019#discussion_r1055672054 --- jsonschema/exceptions.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 1f1d7c011..d7965468c 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -46,16 +46,16 @@ class _Error(Exception): def __init__( self, message: str, - validator: str | _utils.Unset = _unset, + validator: str = _unset, # type: ignore[assignment] path: Iterable[str | int] = (), cause: Exception | None = None, context=(), validator_value: Any = _unset, instance: Any = _unset, - schema: Mapping[str, Any] | bool | _utils.Unset = _unset, + schema: Mapping[str, Any] | bool = _unset, # type: ignore[assignment] schema_path: Iterable[str | int] = (), parent: _Error | None = None, - type_checker: _types.TypeChecker | _utils.Unset = _unset, + type_checker: _types.TypeChecker = _unset, # type: ignore[assignment] ) -> None: super().__init__( message, @@ -176,9 +176,6 @@ def _matches_type(self) -> bool: except (KeyError, TypeError): return False - if isinstance(self._type_checker, _utils.Unset): - return False - if isinstance(expected, str): return self._type_checker.is_type(self.instance, expected) From 9f7cae7f1f576b56ee93b5dc52a59e2f1c846ca6 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 9 Jun 2024 10:36:50 +0300 Subject: [PATCH 013/212] Don't reorder dicts (particularly schemas) when rendering errors. Schemas, particularly longer ones, are often written intentionally with their keywords in some specific human-understandable order. pprint, which we currently use (for better or worse) for rendering schemas and instances, supports *not* sorting dicts now that they maintain their insertion order. So we now pass that argument, and thereby preserve the order the schema was written in. Refs: #243 --- docs/errors.rst | 4 ++-- jsonschema/exceptions.py | 15 +++++++++++---- jsonschema/tests/test_exceptions.py | 23 +++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/docs/errors.rst b/docs/errors.rst index 79c830e9e..9e8046ee6 100644 --- a/docs/errors.rst +++ b/docs/errors.rst @@ -216,8 +216,8 @@ easier debugging. 3 is not valid under any of the given schemas Failed validating 'anyOf' in schema['items']: - {'anyOf': [{'maxLength': 2, 'type': 'string'}, - {'minimum': 5, 'type': 'integer'}]} + {'anyOf': [{'type': 'string', 'maxLength': 2}, + {'type': 'integer', 'minimum': 5}]} On instance[1]: 3 diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index d7965468c..78da49fcd 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -27,6 +27,13 @@ _unset = _utils.Unset() +def _pretty(thing: Any, prefix: str): + """ + Format something for an error message as prettily as we currently can. + """ + return indent(pformat(thing, width=72, sort_dicts=False), prefix).lstrip() + + def __getattr__(name): if name == "RefResolutionError": warnings.warn( @@ -109,10 +116,10 @@ def __str__(self) -> str: {self.message} Failed validating {self.validator!r} in {schema_path}: - {indent(pformat(self.schema, width=72), prefix).lstrip()} + {_pretty(self.schema, prefix=prefix)} On {instance_path}: - {indent(pformat(self.instance, width=72), prefix).lstrip()} + {_pretty(self.instance, prefix=prefix)} """.rstrip(), ) @@ -278,10 +285,10 @@ def __str__(self): return dedent( f"""\ Unknown type {self.type!r} for validator with schema: - {indent(pformat(self.schema, width=72), prefix).lstrip()} + {_pretty(self.schema, prefix=prefix)} While checking instance: - {indent(pformat(self.instance, width=72), prefix).lstrip()} + {_pretty(self.instance, prefix=prefix)} """.rstrip(), ) diff --git a/jsonschema/tests/test_exceptions.py b/jsonschema/tests/test_exceptions.py index 5b3b43621..69114e182 100644 --- a/jsonschema/tests/test_exceptions.py +++ b/jsonschema/tests/test_exceptions.py @@ -648,6 +648,29 @@ def test_uses_pprint(self): validator="maxLength", ) + def test_does_not_reorder_dicts(self): + self.assertShows( + """ + Failed validating 'type' in schema: + {'do': 3, 'not': 7, 'sort': 37, 'me': 73} + + On instance: + {'here': 73, 'too': 37, 'no': 7, 'sorting': 3} + """, + schema={ + "do": 3, + "not": 7, + "sort": 37, + "me": 73, + }, + instance={ + "here": 73, + "too": 37, + "no": 7, + "sorting": 3, + }, + ) + def test_str_works_with_instances_having_overriden_eq_operator(self): """ Check for #164 which rendered exceptions unusable when a From 88a0be1dbbe2895e1fd077dc2df21b38f0af71b3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 19:38:28 +0000 Subject: [PATCH 014/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.7 → v0.4.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.7...v0.4.8) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3a970f239..2800fd595 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.7" + rev: "v0.4.8" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From a1fccdccc9e2282bdcf2fb03f8f703c30ed6b8f4 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 17 Jun 2024 16:52:40 +0200 Subject: [PATCH 015/212] Update docs requirements. --- docs/requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 3db278783..ca1958ab6 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -42,7 +42,7 @@ lxml==5.2.2 # sphinx-json-schema-spec markupsafe==2.1.5 # via jinja2 -packaging==24.0 +packaging==24.1 # via sphinx pyenchant==3.3.0rc1 # via @@ -81,7 +81,7 @@ sphinx==7.3.7 # sphinxext-opengraph sphinx-autoapi==3.1.1 # via -r docs/requirements.in -sphinx-autodoc-typehints==2.1.0 +sphinx-autodoc-typehints==2.1.1 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo @@ -105,5 +105,5 @@ sphinxcontrib-spelling==8.0.0 # via -r docs/requirements.in sphinxext-opengraph==0.9.1 # via -r docs/requirements.in -urllib3==2.2.1 +urllib3==2.2.2 # via requests From 7fd28c3936375deb1180a45624d37c58d1576cac Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 17 Jun 2024 17:09:57 +0200 Subject: [PATCH 016/212] Update the (ancient draft3) color format for newer webcolors. Bumps the pin to the newer version, where validating these seems to now require a function call. Really we should have a better strategy in CI for ensuring we run all the format tests we intend to run, but this should happen really really rarely. Closes: ##1268 --- jsonschema/_format.py | 16 ++++++---------- pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 9e4827e08..6e87620cc 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -413,20 +413,16 @@ def is_draft3_time(instance: object) -> bool: with suppress(ImportError): - from webcolors import CSS21_NAMES_TO_HEX import webcolors - def is_css_color_code(instance: object) -> bool: - return webcolors.normalize_hex(instance) - @_checks_drafts(draft3="color", raises=(ValueError, TypeError)) def is_css21_color(instance: object) -> bool: - if ( - not isinstance(instance, str) - or instance.lower() in CSS21_NAMES_TO_HEX - ): - return True - return is_css_color_code(instance) + if isinstance(instance, str): + try: + webcolors.name_to_hex(instance) + except ValueError: + webcolors.normalize_hex(instance.lower()) + return True with suppress(ImportError): diff --git a/pyproject.toml b/pyproject.toml index 45dbc8c4f..c4f7695c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,7 +66,7 @@ format-nongpl = [ "rfc3339-validator", "rfc3986-validator>0.1.0", "uri_template", - "webcolors>=1.11", + "webcolors>=24.6.0", ] [project.scripts] From deb53982d59d98f86ef18f50cd098066af70003e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 19:33:44 +0000 Subject: [PATCH 017/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.8 → v0.4.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.8...v0.4.9) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2800fd595..20bb33b7a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.8" + rev: "v0.4.9" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From a90d6e29c65e661c22afef81d575e84a14e85cd4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:35:02 +0000 Subject: [PATCH 018/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.9 → v0.4.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.9...v0.4.10) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 20bb33b7a..7d783dfe0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.9" + rev: "v0.4.10" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 6a00e35d5d1e304c99308e57a5fb0d7da29508fe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 20:01:16 +0000 Subject: [PATCH 019/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.10 → v0.5.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.10...v0.5.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d783dfe0..a42390115 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.4.10" + rev: "v0.5.0" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 40410c45e7851816cc7f426aa6699530eb0d589e Mon Sep 17 00:00:00 2001 From: Roman Inflianskas Date: Mon, 8 Jul 2024 19:23:18 +0300 Subject: [PATCH 020/212] Declare support for 3.13 Fixes: https://github.com/python-jsonschema/jsonschema/issues/1264. Hardcode the `LATEST_STABLE` variable in `noxfile.py` to equal the latest stable Python release. --- .github/workflows/ci.yml | 1 + CHANGELOG.rst | 5 +++++ noxfile.py | 6 +++--- pyproject.toml | 1 + 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99449fd0c..a01200b60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -87,6 +87,7 @@ jobs: 3.10 3.11 3.12 + 3.13 pypy3.10 allow-prereleases: true - name: Set up nox diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0da30a6b5..4c7c86e1b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +v4.22.1 +======= + +* Declare support for Py3.13 + v4.22.0 ======= diff --git a/noxfile.py b/noxfile.py index 2c611278b..fada3e1f8 100644 --- a/noxfile.py +++ b/noxfile.py @@ -35,13 +35,13 @@ "The Unlicense (Unlicense)", ] -SUPPORTED = ["3.8", "3.9", "3.10", "pypy3.10", "3.11", "3.12"] -LATEST = SUPPORTED[-1] +SUPPORTED = ["3.8", "3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"] +LATEST_STABLE = "3.12" nox.options.sessions = [] -def session(default=True, python=LATEST, **kwargs): # noqa: D103 +def session(default=True, python=LATEST_STABLE, **kwargs): # noqa: D103 def _session(fn): if default: nox.options.sessions.append(kwargs.get("name", fn.__name__)) diff --git a/pyproject.toml b/pyproject.toml index c4f7695c0..1eea228f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: File Formats :: JSON", From cfe8a4071672b9652c8f083faed1c4ffa7d67705 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 8 Jul 2024 13:42:11 -0400 Subject: [PATCH 021/212] Document the other change, and call this 4.23.0. --- CHANGELOG.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4c7c86e1b..a7b9d86eb 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,7 @@ -v4.22.1 +v4.23.0 ======= +* Do not reorder dictionaries (schemas, instances) that are printed as part of validation errors. * Declare support for Py3.13 v4.22.0 From e8fc7b89a3cb0fe4c245d49257e980edfe2648c4 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 8 Jul 2024 13:42:54 -0400 Subject: [PATCH 022/212] Update docs requirements. --- docs/requirements.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index ca1958ab6..5267e5a81 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -16,7 +16,7 @@ babel==2.15.0 # via sphinx beautifulsoup4==4.12.3 # via furo -certifi==2024.6.2 +certifi==2024.7.4 # via requests charset-normalizer==3.3.2 # via requests @@ -60,7 +60,7 @@ referencing==0.35.1 # jsonschema-specifications requests==2.32.3 # via sphinx -rpds-py==0.18.1 +rpds-py==0.19.0 # via # jsonschema # referencing @@ -79,9 +79,9 @@ sphinx==7.3.7 # sphinx-json-schema-spec # sphinxcontrib-spelling # sphinxext-opengraph -sphinx-autoapi==3.1.1 +sphinx-autoapi==3.1.2 # via -r docs/requirements.in -sphinx-autodoc-typehints==2.1.1 +sphinx-autodoc-typehints==2.2.2 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo From a48161e0b05776f0b356da199f155995291f396e Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 8 Jul 2024 13:43:07 -0400 Subject: [PATCH 023/212] Update pre-commit hooks. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a42390115..79ecd0ec0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.0" + rev: "v0.5.1" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 9d70d58e79403de07b5b69cb61ece5eff4e8fe21 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:44:25 +0000 Subject: [PATCH 024/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.5.1 → v0.5.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.1...v0.5.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 79ecd0ec0..a18f23c86 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.1" + rev: "v0.5.2" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From e028780453d29753ef3331d1970b2a68a62cf2df Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:44:32 +0000 Subject: [PATCH 025/212] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- jsonschema/tests/test_deprecations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema/tests/test_deprecations.py b/jsonschema/tests/test_deprecations.py index aea922d23..a54b02f38 100644 --- a/jsonschema/tests/test_deprecations.py +++ b/jsonschema/tests/test_deprecations.py @@ -183,7 +183,7 @@ def test_RefResolver(self): self.assertEqual(w.filename, __file__) with self.assertWarnsRegex(DeprecationWarning, message) as w: - from jsonschema.validators import RefResolver # noqa: F401, F811 + from jsonschema.validators import RefResolver # noqa: F401 self.assertEqual(w.filename, __file__) def test_RefResolutionError(self): From bc3ba8ebe8eae2109bb6f97324ae3e52c0965cf0 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 19 Jul 2024 09:36:28 -0400 Subject: [PATCH 026/212] Update pre-commit hooks. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a18f23c86..cd645842a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.2" + rev: "v0.5.3" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From d2aa2ba124417484eb8ed0950d48527a50b0f773 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 19 Jul 2024 11:45:22 -0400 Subject: [PATCH 027/212] Don't peek at our iterator when computing best_match. Someone added a cool `default` argument to `max`, and all versions we support have it. --- jsonschema/exceptions.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 78da49fcd..3dcd29667 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -8,7 +8,6 @@ from textwrap import dedent, indent from typing import TYPE_CHECKING, Any, ClassVar import heapq -import itertools import warnings from attrs import define @@ -471,11 +470,9 @@ def best_match(errors, key=relevance): set of inputs from version to version if better heuristics are added. """ - errors = iter(errors) - best = next(errors, None) + best = max(errors, key=key, default=None) if best is None: return - best = max(itertools.chain([best], errors), key=key) while best.context: # Calculate the minimum via nsmallest, because we don't recurse if From ba24c83ad0fce885a83ce1f5f96bf800b067b7e2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 19:46:15 +0000 Subject: [PATCH 028/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.5.3 → v0.5.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.3...v0.5.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cd645842a..7f1201577 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.3" + rev: "v0.5.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From fe5071f3bfa6465d06b8083f762a39ac0291b7b8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 19:45:28 +0000 Subject: [PATCH 029/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.5.4 → v0.5.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.4...v0.5.5) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7f1201577..7855ef5dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.4" + rev: "v0.5.5" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 4dc00313dcef9defdadf68fb7b90df865b73cbe0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 20:04:45 +0000 Subject: [PATCH 030/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.5.5 → v0.5.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.5...v0.5.6) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7855ef5dd..e321cf5f3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.5" + rev: "v0.5.6" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From c0deed1b2d4e1d560f99f8abb8cada3067c94a6d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:42:51 +0000 Subject: [PATCH 031/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.5.6 → v0.5.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.6...v0.5.7) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e321cf5f3..08cc6e63e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.6" + rev: "v0.5.7" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 997073ccbb97876d50271ffcd916552ae6c80767 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:47:08 +0000 Subject: [PATCH 032/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.5.7 → v0.6.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.7...v0.6.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 08cc6e63e..f509a212e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.5.7" + rev: "v0.6.1" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 21f788128a006c3262d3c0ccf74a586e7f6e70a5 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 19 Aug 2024 19:39:04 -0400 Subject: [PATCH 033/212] 'Preemptively' ignore a new rule. --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 1eea228f3..6cd7c18fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -185,6 +185,7 @@ ignore = [ "PLR0913", "PLR0915", "PLR1714", # This makes for uglier comparisons sometimes + "PLW0642", # Shadowing self also isn't a big deal. "PLW2901", # Shadowing for loop variables is occasionally fine. "PT", # We use unittest "PYI025", # wat, I'm not confused, thanks. From dd7dff60909a6c75cc0ebf8b8ad9cd5bfc8df3b7 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 22 Aug 2024 12:00:08 -0400 Subject: [PATCH 034/212] The packaging docs apparently discourage license. julian@Airm They say to just use the classifier. See https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license which says: If you are using a standard, well-known license, it is not necessary to use this field. Instead, you should use one of the classifiers starting with License ::. Though we'll keep an eye on PEP639 which hopefully gets accepted soon, and which slightly tweaks some of these fields. --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6cd7c18fa..be4adabf6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ source = "vcs" name = "jsonschema" description = "An implementation of JSON Schema validation for Python" requires-python = ">=3.8" -license = {text = "MIT"} keywords = [ "validation", "data validation", From 5486d9367380fb75748bdd7a77aecbbbec1b83c7 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 22 Aug 2024 12:19:55 -0400 Subject: [PATCH 035/212] Revert "The packaging docs apparently discourage license. julian@Airm" Interesting -- this actually breaks `pip show` showing the license. There must be some upstream solution to that but let's revert for this moment until we investigate. This reverts commit dd7dff60909a6c75cc0ebf8b8ad9cd5bfc8df3b7. --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index be4adabf6..6cd7c18fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ source = "vcs" name = "jsonschema" description = "An implementation of JSON Schema validation for Python" requires-python = ">=3.8" +license = {text = "MIT"} keywords = [ "validation", "data validation", From a605a21287f2a49ce713044a0f9dbb14a3806a7e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 19:54:52 +0000 Subject: [PATCH 036/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.1 → v0.6.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.1...v0.6.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f509a212e..fc4a3fb8b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.1" + rev: "v0.6.2" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From cf86259a093e66fcac3a2e031a8b97486ee28aa3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 19:43:40 +0000 Subject: [PATCH 037/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.2 → v0.6.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.2...v0.6.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fc4a3fb8b..723beb4b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.2" + rev: "v0.6.3" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 2cd0db8698aee9313edfcbd43177d317339ee72b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 19:50:30 +0000 Subject: [PATCH 038/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.3 → v0.6.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.3...v0.6.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 723beb4b4..00354aeec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.3" + rev: "v0.6.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From ee03ec4fc6ec93d7e4ce9b0a6be8c0aa5edc4deb Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 11 Sep 2024 11:20:29 -0400 Subject: [PATCH 039/212] Drop support for 3.8, which is near EOL. --- .github/workflows/ci.yml | 1 - CHANGELOG.rst | 5 ++++ jsonschema/_format.py | 4 +--- jsonschema/_types.py | 6 ++++- jsonschema/_typing.py | 5 ++-- jsonschema/protocols.py | 11 ++------- .../tests/test_jsonschema_test_suite.py | 24 +++---------------- noxfile.py | 2 +- pyproject.toml | 5 ++-- 9 files changed, 22 insertions(+), 41 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a01200b60..37ccb705c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,7 +82,6 @@ jobs: uses: actions/setup-python@v5 with: python-version: | - 3.8 3.9 3.10 3.11 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a7b9d86eb..070573bb5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +v4.24.0 +======= + +* Support for Python 3.8 has been dropped, as it is nearing end-of-life. + v4.23.0 ======= diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 6e87620cc..789fe4f27 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -13,9 +13,7 @@ _FormatCheckCallable = typing.Callable[[object], bool] #: A format checker callable. _F = typing.TypeVar("_F", bound=_FormatCheckCallable) -_RaisesType = typing.Union[ - typing.Type[Exception], typing.Tuple[typing.Type[Exception], ...], -] +_RaisesType = typing.Union[type[Exception], tuple[type[Exception], ...]] _RE_DATE = re.compile(r"^\d{4}-\d{2}-\d{2}$", re.ASCII) diff --git a/jsonschema/_types.py b/jsonschema/_types.py index bf25e7e6f..0cd175aad 100644 --- a/jsonschema/_types.py +++ b/jsonschema/_types.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Callable, Mapping +from typing import TYPE_CHECKING import numbers from attrs import evolve, field, frozen @@ -8,6 +8,10 @@ from jsonschema.exceptions import UndefinedTypeCheck +if TYPE_CHECKING: + from collections.abc import Mapping + from typing import Any, Callable + # unfortunately, the type of HashTrieMap is generic, and if used as an attrs # converter, the generic type is presented to mypy, which then fails to match diff --git a/jsonschema/_typing.py b/jsonschema/_typing.py index d283dc48d..1d091d70c 100644 --- a/jsonschema/_typing.py +++ b/jsonschema/_typing.py @@ -1,7 +1,8 @@ """ Some (initially private) typing helpers for jsonschema's types. """ -from typing import Any, Callable, Iterable, Protocol, Tuple, Union +from collections.abc import Iterable +from typing import Any, Callable, Protocol, Union import referencing.jsonschema @@ -24,5 +25,5 @@ def __call__( ApplicableValidators = Callable[ [referencing.jsonschema.Schema], - Iterable[Tuple[str, Any]], + Iterable[tuple[str, Any]], ] diff --git a/jsonschema/protocols.py b/jsonschema/protocols.py index 39e56d0fa..93cd99f4f 100644 --- a/jsonschema/protocols.py +++ b/jsonschema/protocols.py @@ -7,21 +7,14 @@ from __future__ import annotations -from typing import ( - TYPE_CHECKING, - Any, - ClassVar, - Iterable, - Protocol, - runtime_checkable, -) +from typing import TYPE_CHECKING, ClassVar, Protocol, runtime_checkable # in order for Sphinx to resolve references accurately from type annotations, # it needs to see names like `jsonschema.TypeChecker` # therefore, only import at type-checking time (to avoid circular references), # but use `jsonschema` for any types which will otherwise not be resolvable if TYPE_CHECKING: - from collections.abc import Mapping + from collections.abc import Any, Iterable, Mapping import referencing.jsonschema diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 282c1369c..d1b0ebc05 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -6,7 +6,6 @@ See https://github.com/json-schema-org/JSON-Schema-Test-Suite for details. """ -import sys from jsonschema.tests._suite import Suite import jsonschema @@ -66,18 +65,6 @@ def complex_email_validation(test): )(test) -if sys.version_info < (3, 9): # pragma: no cover - message = "Rejecting leading zeros is 3.9+" - allowed_leading_zeros = skip( - message=message, - subject="ipv4", - description="invalid leading zeroes, as they are treated as octals", - ) -else: - def allowed_leading_zeros(test): # pragma: no cover - return - - def leap_second(test): message = "Leap seconds are unsupported." return skip( @@ -149,8 +136,7 @@ def leap_second(test): Validator=jsonschema.Draft4Validator, format_checker=jsonschema.Draft4Validator.FORMAT_CHECKER, skip=lambda test: ( - allowed_leading_zeros(test) - or leap_second(test) + leap_second(test) or missing_format(jsonschema.Draft4Validator)(test) or complex_email_validation(test) ), @@ -167,8 +153,7 @@ def leap_second(test): Validator=jsonschema.Draft6Validator, format_checker=jsonschema.Draft6Validator.FORMAT_CHECKER, skip=lambda test: ( - allowed_leading_zeros(test) - or leap_second(test) + leap_second(test) or missing_format(jsonschema.Draft6Validator)(test) or complex_email_validation(test) ), @@ -187,8 +172,7 @@ def leap_second(test): Validator=jsonschema.Draft7Validator, format_checker=jsonschema.Draft7Validator.FORMAT_CHECKER, skip=lambda test: ( - allowed_leading_zeros(test) - or leap_second(test) + leap_second(test) or missing_format(jsonschema.Draft7Validator)(test) or complex_email_validation(test) ), @@ -224,7 +208,6 @@ def leap_second(test): format_checker=jsonschema.Draft201909Validator.FORMAT_CHECKER, skip=lambda test: ( complex_email_validation(test) - or allowed_leading_zeros(test) or leap_second(test) or missing_format(jsonschema.Draft201909Validator)(test) or complex_email_validation(test) @@ -261,7 +244,6 @@ def leap_second(test): format_checker=jsonschema.Draft202012Validator.FORMAT_CHECKER, skip=lambda test: ( complex_email_validation(test) - or allowed_leading_zeros(test) or leap_second(test) or missing_format(jsonschema.Draft202012Validator)(test) or complex_email_validation(test) diff --git a/noxfile.py b/noxfile.py index fada3e1f8..c574abca9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -35,7 +35,7 @@ "The Unlicense (Unlicense)", ] -SUPPORTED = ["3.8", "3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"] +SUPPORTED = ["3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"] LATEST_STABLE = "3.12" nox.options.sessions = [] diff --git a/pyproject.toml b/pyproject.toml index 6cd7c18fa..a76862eaf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ source = "vcs" [project] name = "jsonschema" description = "An implementation of JSON Schema validation for Python" -requires-python = ">=3.8" +requires-python = ">=3.9" license = {text = "MIT"} keywords = [ "validation", @@ -26,7 +26,6 @@ classifiers = [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -198,7 +197,7 @@ ignore = [ "SLF001", # Private usage within this package itself is fine "TD", # These TODO style rules are also silly "TRY003", # Some exception classes are essentially intended for free-form - "UP007", # We support 3.8 + 3.9 + "UP007", # We support 3.9 ] [tool.ruff.lint.flake8-pytest-style] From 6b12cf853912d8eaff6e029053510e0892c983af Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 11 Sep 2024 11:41:00 -0400 Subject: [PATCH 040/212] Wrongly moved import. --- jsonschema/protocols.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsonschema/protocols.py b/jsonschema/protocols.py index 93cd99f4f..0fd993eec 100644 --- a/jsonschema/protocols.py +++ b/jsonschema/protocols.py @@ -7,14 +7,14 @@ from __future__ import annotations -from typing import TYPE_CHECKING, ClassVar, Protocol, runtime_checkable +from typing import TYPE_CHECKING, Any, ClassVar, Protocol, runtime_checkable # in order for Sphinx to resolve references accurately from type annotations, # it needs to see names like `jsonschema.TypeChecker` # therefore, only import at type-checking time (to avoid circular references), # but use `jsonschema` for any types which will otherwise not be resolvable if TYPE_CHECKING: - from collections.abc import Any, Iterable, Mapping + from collections.abc import Iterable, Mapping import referencing.jsonschema From efd60fb9f5cfed0c39bf7aa7df5cdec279bb8b5e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:49:04 +0000 Subject: [PATCH 041/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.4 → v0.6.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.4...v0.6.7) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 00354aeec..f38002dce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.4" + rev: "v0.6.7" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 819f865afae0e81af25473a674b6de742ca7c69e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:57:58 +0000 Subject: [PATCH 042/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.6.7 → v0.6.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.7...v0.6.8) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f38002dce..cf79efe8a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.7" + rev: "v0.6.8" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 08395e9655f680874c55fbba5f95c36aacc90849 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 6 Oct 2024 17:37:50 -0400 Subject: [PATCH 043/212] Fix a broken link which has changed on the JSON Schema website. This new link seems a bit wrong and likely to change again to me, but for now, the old link is a 404... Refs: json-schema-org/website#955 --- docs/faq.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index b724f4f1c..8a5e525a2 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -56,10 +56,9 @@ Difficult as this may sound for new users, at this point it at least means they .. seealso:: - `Draft 2019-09's release notes on format `_ + `Draft 2019-09's release notes on format `_ - for upstream details on the behavior of format and how it has changed - in ``draft2019-09`` + for upstream details on the behavior of format and how it has changed in ``draft2019-09`` `validating formats` From 3e6b81ffc8b984b278463bbac497ac98d192e41f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:48:58 +0000 Subject: [PATCH 044/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.6.0 → v5.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.6.0...v5.0.0) - [github.com/astral-sh/ruff-pre-commit: v0.6.8 → v0.6.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.8...v0.6.9) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cf79efe8a..c16dc3ecf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ exclude: json/ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: check-ast - id: check-json @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.8" + rev: "v0.6.9" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 328c2f10577e0c579c3a928d5bcf876a5d9852f0 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 17 Oct 2024 09:15:46 -0400 Subject: [PATCH 045/212] Revert "Fix a broken link which has changed on the JSON Schema website." It was reverted upstream in json-schema-org/website#1010. This reverts commit 08395e9655f680874c55fbba5f95c36aacc90849. --- docs/faq.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index 8a5e525a2..b724f4f1c 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -56,9 +56,10 @@ Difficult as this may sound for new users, at this point it at least means they .. seealso:: - `Draft 2019-09's release notes on format `_ + `Draft 2019-09's release notes on format `_ - for upstream details on the behavior of format and how it has changed in ``draft2019-09`` + for upstream details on the behavior of format and how it has changed + in ``draft2019-09`` `validating formats` From d71f96a6523875c9694fcdf468c9f458323d07f2 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 17 Oct 2024 09:36:35 -0400 Subject: [PATCH 046/212] Fix the annotation for validator_for's default. This still doesn't seem to satisfy mypy, so tell it to be quiet. --- jsonschema/validators.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 85c39160d..b8ca3bd45 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -857,7 +857,7 @@ def extend( version="draft2020-12", ) -_LATEST_VERSION = Draft202012Validator +_LATEST_VERSION: type[Validator] = Draft202012Validator class _RefResolver: @@ -1334,7 +1334,7 @@ def validate(instance, schema, cls=None, *args, **kwargs): # noqa: D417 def validator_for( schema, - default: Validator | _utils.Unset = _UNSET, + default: type[Validator] | _utils.Unset = _UNSET, ) -> type[Validator]: """ Retrieve the validator class appropriate for validating the given schema. @@ -1396,7 +1396,7 @@ class is returned: DefaultValidator = _LATEST_VERSION if default is _UNSET else default if schema is True or schema is False or "$schema" not in schema: - return DefaultValidator + return DefaultValidator # type: ignore[return-value] if schema["$schema"] not in _META_SCHEMAS and default is _UNSET: warn( ( From 5544c345f3f217244d37da7ff52be89e14f90ca5 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 21 Oct 2024 23:54:18 -0400 Subject: [PATCH 047/212] Quiet some style false positives. --- .pre-commit-config.yaml | 2 +- jsonschema/tests/test_cli.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c16dc3ecf..689f628a7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.6.9" + rev: "v0.7.0" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/jsonschema/tests/test_cli.py b/jsonschema/tests/test_cli.py index 79d2a1584..592397357 100644 --- a/jsonschema/tests/test_cli.py +++ b/jsonschema/tests/test_cli.py @@ -690,7 +690,7 @@ def test_successful_validation_of_just_the_schema_pretty_output(self): ) def test_successful_validation_via_explicit_base_uri(self): - ref_schema_file = tempfile.NamedTemporaryFile(delete=False) + ref_schema_file = tempfile.NamedTemporaryFile(delete=False) # noqa: SIM115 ref_schema_file.close() self.addCleanup(os.remove, ref_schema_file.name) @@ -711,7 +711,7 @@ def test_successful_validation_via_explicit_base_uri(self): ) def test_unsuccessful_validation_via_explicit_base_uri(self): - ref_schema_file = tempfile.NamedTemporaryFile(delete=False) + ref_schema_file = tempfile.NamedTemporaryFile(delete=False) # noqa: SIM115 ref_schema_file.close() self.addCleanup(os.remove, ref_schema_file.name) From 9f89e6d0a963b6321779cd4933127365d133d908 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 03:56:43 +0000 Subject: [PATCH 048/212] Bump wntrblm/nox from 2024.04.15 to 2024.10.09 Bumps [wntrblm/nox](https://github.com/wntrblm/nox) from 2024.04.15 to 2024.10.09. - [Release notes](https://github.com/wntrblm/nox/releases) - [Changelog](https://github.com/wntrblm/nox/blob/main/CHANGELOG.md) - [Commits](https://github.com/wntrblm/nox/compare/2024.04.15...2024.10.09) --- updated-dependencies: - dependency-name: wntrblm/nox dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37ccb705c..b26540182 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,7 +35,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up nox - uses: wntrblm/nox@2024.04.15 + uses: wntrblm/nox@2024.10.09 - id: noxenvs-matrix run: | echo >>$GITHUB_OUTPUT noxenvs=$( @@ -90,7 +90,7 @@ jobs: pypy3.10 allow-prereleases: true - name: Set up nox - uses: wntrblm/nox@2024.04.15 + uses: wntrblm/nox@2024.10.09 - name: Enable UTF-8 on Windows run: echo "PYTHONUTF8=1" >> $env:GITHUB_ENV if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') From 8ca5a06d9763825b9bbf4c5c92614feb316696ff Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 20:12:53 +0000 Subject: [PATCH 049/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.7.0 → v0.7.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.0...v0.7.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 689f628a7..8470acb2b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.0" + rev: "v0.7.1" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From d6f42d744675e966539edb07b710c0571f69b2f8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 20:08:15 +0000 Subject: [PATCH 050/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.7.1 → v0.7.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.1...v0.7.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8470acb2b..34c2842f8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.1" + rev: "v0.7.2" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From f608cbc6aa961f930a04a0b023791259a1fa3ca2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 19:55:36 +0000 Subject: [PATCH 051/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.7.2 → v0.7.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.2...v0.7.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 34c2842f8..e1ca24264 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.2" + rev: "v0.7.3" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 4e85551aeeb7bee8030dfd8bb92342fdb9c22f55 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 14 Nov 2024 15:04:28 -0500 Subject: [PATCH 052/212] Update docs requirements. --- docs/requirements.txt | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 5267e5a81..c742ce62e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,27 +4,27 @@ # # pip-compile --strip-extras docs/requirements.in # -alabaster==0.7.16 +alabaster==1.0.0 # via sphinx -astroid==3.2.2 +astroid==3.3.5 # via sphinx-autoapi -attrs==23.2.0 +attrs==24.2.0 # via # jsonschema # referencing -babel==2.15.0 +babel==2.16.0 # via sphinx beautifulsoup4==4.12.3 # via furo -certifi==2024.7.4 +certifi==2024.8.30 # via requests -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via requests docutils==0.21.2 # via sphinx -furo==2024.5.6 +furo==2024.8.6 # via -r docs/requirements.in -idna==3.7 +idna==3.10 # via requests imagesize==1.4.1 # via sphinx @@ -34,15 +34,15 @@ jinja2==3.1.4 # sphinx-autoapi file:.#egg=jsonschema # via -r docs/requirements.in -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 # via jsonschema -lxml==5.2.2 +lxml==5.3.0 # via # -r docs/requirements.in # sphinx-json-schema-spec -markupsafe==2.1.5 +markupsafe==3.0.2 # via jinja2 -packaging==24.1 +packaging==24.2 # via sphinx pyenchant==3.3.0rc1 # via @@ -52,7 +52,7 @@ pygments==2.18.0 # via # furo # sphinx -pyyaml==6.0.1 +pyyaml==6.0.2 # via sphinx-autoapi referencing==0.35.1 # via @@ -60,15 +60,15 @@ referencing==0.35.1 # jsonschema-specifications requests==2.32.3 # via sphinx -rpds-py==0.19.0 +rpds-py==0.21.0 # via # jsonschema # referencing snowballstemmer==2.2.0 # via sphinx -soupsieve==2.5 +soupsieve==2.6 # via beautifulsoup4 -sphinx==7.3.7 +sphinx==8.1.3 # via # -r docs/requirements.in # furo @@ -79,9 +79,9 @@ sphinx==7.3.7 # sphinx-json-schema-spec # sphinxcontrib-spelling # sphinxext-opengraph -sphinx-autoapi==3.1.2 +sphinx-autoapi==3.3.3 # via -r docs/requirements.in -sphinx-autodoc-typehints==2.2.2 +sphinx-autodoc-typehints==2.5.0 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo @@ -89,21 +89,21 @@ sphinx-copybutton==0.5.2 # via -r docs/requirements.in sphinx-json-schema-spec==2024.1.1 # via -r docs/requirements.in -sphinxcontrib-applehelp==1.0.8 +sphinxcontrib-applehelp==2.0.0 # via sphinx -sphinxcontrib-devhelp==1.0.6 +sphinxcontrib-devhelp==2.0.0 # via sphinx -sphinxcontrib-htmlhelp==2.0.5 +sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.7 +sphinxcontrib-qthelp==2.0.0 # via sphinx -sphinxcontrib-serializinghtml==1.1.10 +sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphinxcontrib-spelling==8.0.0 # via -r docs/requirements.in sphinxext-opengraph==0.9.1 # via -r docs/requirements.in -urllib3==2.2.2 +urllib3==2.2.3 # via requests From 94265ee7572f85516ab13649097af3586ea8b662 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 19:57:39 +0000 Subject: [PATCH 053/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.7.3 → v0.7.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.3...v0.7.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e1ca24264..086b5972b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.3" + rev: "v0.7.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 467b7880ffd9719be5d283a794447f45907ac79b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 19:55:17 +0000 Subject: [PATCH 054/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.7.4 → v0.8.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.4...v0.8.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 086b5972b..60a780198 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.7.4" + rev: "v0.8.0" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From e3a3ab6189cf3d4bcf54038b37c99769de79dd4d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 19:55:26 +0000 Subject: [PATCH 055/212] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- jsonschema/__init__.py | 4 ++-- jsonschema/_types.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index 79924cf7e..d8dec8cfa 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -106,12 +106,12 @@ def __getattr__(name): __all__ = [ - "Draft201909Validator", - "Draft202012Validator", "Draft3Validator", "Draft4Validator", "Draft6Validator", "Draft7Validator", + "Draft201909Validator", + "Draft202012Validator", "FormatChecker", "SchemaError", "TypeChecker", diff --git a/jsonschema/_types.py b/jsonschema/_types.py index 0cd175aad..d3ce9d667 100644 --- a/jsonschema/_types.py +++ b/jsonschema/_types.py @@ -196,7 +196,7 @@ def remove(self, *types) -> TypeChecker: "integer", lambda checker, instance: ( is_integer(checker, instance) - or isinstance(instance, float) and instance.is_integer() + or (isinstance(instance, float) and instance.is_integer()) ), ) draft7_type_checker = draft6_type_checker From 5108dc6f587fafd5e2d274eb153bd3157dd64c27 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:03:52 +0000 Subject: [PATCH 056/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.8.0 → v0.8.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.0...v0.8.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60a780198..21b06b9dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.0" + rev: "v0.8.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From f064d44245dd57fef42af5fbc6de698f326f12d7 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 28 Dec 2024 15:41:52 -0500 Subject: [PATCH 057/212] Declare license via (the accepted) PEP 639. The License field is deprecated, as is the trove classifier. Note that pip show does not support properly detecting these yet, but it will. Note also that `pip-licenses` does not support PEP 639 (see raimon49/pip-licenses#213) the implications of which are that we are already broken (the `license_check` noxenv fails because of packages already using the newer standard). This doesn't fix that yet. AFAICT no tool exists that does this properly yet/now. So let's see... I guess we reimplement that functionality?! Refs: https://peps.python.org/pep-0639/ Refs: pypa/pip#13112 Refs: pypa/pip#6677 --- jsonschema/tests/test_cli.py | 7 ++----- pyproject.toml | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/jsonschema/tests/test_cli.py b/jsonschema/tests/test_cli.py index 592397357..bed9f3e4c 100644 --- a/jsonschema/tests/test_cli.py +++ b/jsonschema/tests/test_cli.py @@ -881,11 +881,8 @@ def test_useless_error_format(self): class TestCLIIntegration(TestCase): def test_license(self): - output = subprocess.check_output( - [sys.executable, "-m", "pip", "show", "jsonschema"], - stderr=subprocess.STDOUT, - ) - self.assertIn(b"License: MIT", output) + our_metadata = metadata.metadata("jsonschema") + self.assertEqual(our_metadata.get("License-Expression"), "MIT") def test_version(self): version = subprocess.check_output( diff --git a/pyproject.toml b/pyproject.toml index a76862eaf..bd0f00403 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,8 @@ source = "vcs" name = "jsonschema" description = "An implementation of JSON Schema validation for Python" requires-python = ">=3.9" -license = {text = "MIT"} +license = "MIT" +license-files = ["COPYING"] keywords = [ "validation", "data validation", @@ -23,7 +24,6 @@ authors = [ classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.9", From 2fb1d2cbd4cf7cdb41a3c0b3d6beb66f02f9a3e5 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 28 Dec 2024 16:02:28 -0500 Subject: [PATCH 058/212] Update requirements. --- docs/requirements.txt | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index c742ce62e..b329416a9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -6,9 +6,9 @@ # alabaster==1.0.0 # via sphinx -astroid==3.3.5 +astroid==3.3.8 # via sphinx-autoapi -attrs==24.2.0 +attrs==24.3.0 # via # jsonschema # referencing @@ -16,9 +16,9 @@ babel==2.16.0 # via sphinx beautifulsoup4==4.12.3 # via furo -certifi==2024.8.30 +certifi==2024.12.14 # via requests -charset-normalizer==3.4.0 +charset-normalizer==3.4.1 # via requests docutils==0.21.2 # via sphinx @@ -28,7 +28,7 @@ idna==3.10 # via requests imagesize==1.4.1 # via sphinx -jinja2==3.1.4 +jinja2==3.1.5 # via # sphinx # sphinx-autoapi @@ -59,8 +59,10 @@ referencing==0.35.1 # jsonschema # jsonschema-specifications requests==2.32.3 - # via sphinx -rpds-py==0.21.0 + # via + # sphinx + # sphinxcontrib-spelling +rpds-py==0.22.3 # via # jsonschema # referencing @@ -79,7 +81,7 @@ sphinx==8.1.3 # sphinx-json-schema-spec # sphinxcontrib-spelling # sphinxext-opengraph -sphinx-autoapi==3.3.3 +sphinx-autoapi==3.4.0 # via -r docs/requirements.in sphinx-autodoc-typehints==2.5.0 # via -r docs/requirements.in @@ -101,9 +103,9 @@ sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx -sphinxcontrib-spelling==8.0.0 +sphinxcontrib-spelling==8.0.1 # via -r docs/requirements.in sphinxext-opengraph==0.9.1 # via -r docs/requirements.in -urllib3==2.2.3 +urllib3==2.3.0 # via requests From 0696c69225bcbd3623b41ca0bcf001d2c868e871 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 28 Dec 2024 16:04:35 -0500 Subject: [PATCH 059/212] Ignore packages using PEP 639 in license-check until we reimplement it. For now this at least gets CI passing again. --- noxfile.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/noxfile.py b/noxfile.py index c574abca9..163d1ebc6 100644 --- a/noxfile.py +++ b/noxfile.py @@ -115,9 +115,17 @@ def license_check(session): "-m", "piplicenses", "--ignore-packages", + + # because they're not our deps "pip-requirements-parser", "pip_audit", "pip-api", + + # because pip-licenses doesn't yet support PEP 639 :/ + "attrs", + "jsonschema", + "referencing", + "--allow-only", ";".join(NONGPL_LICENSES), ) From 1835a08f612ac37c4c0621f09f9b06a67065b52d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 28 Dec 2024 16:56:28 -0500 Subject: [PATCH 060/212] Run with 3.13 by default in noxenvs. --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 163d1ebc6..21a7faac2 100644 --- a/noxfile.py +++ b/noxfile.py @@ -36,7 +36,7 @@ ] SUPPORTED = ["3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"] -LATEST_STABLE = "3.12" +LATEST_STABLE = SUPPORTED[-1] nox.options.sessions = [] From 84f9dc6538b1ade9adf5251dbeb32f250b1d5b11 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:21:34 +0000 Subject: [PATCH 061/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.8.4 → v0.8.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.4...v0.8.6) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 21b06b9dd..6daac372d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.4" + rev: "v0.8.6" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From f389794cf41dd5bf4457d61c0b53028fab1240e2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:57:05 +0000 Subject: [PATCH 062/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.8.6 → v0.9.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.8.6...v0.9.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6daac372d..bff9fe419 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.8.6" + rev: "v0.9.1" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 51506b97291adac6e3ca926442eb07f787bc98b5 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Thu, 16 Jan 2025 22:14:04 -0600 Subject: [PATCH 063/212] Improve 'format:hostname' to handle "" and "." The `fqdn` library used to provide `"hostname"` format validation (when installed) does not properly handle some known inputs, including `""` and `"."`. On these strings, the library improperly emits `ValueError`. Given that the library no longer appears to be receiving updates, there are two potential workarounds in `jsonschema`: 1. add `ValueError` handling via `raises=...` 2. add explicit handling for known patterns before calling out to `fqdn` This changeset implements (1) only, adding handling for `ValueError`. New test cases are added for `""` and `"."`. resolves #1121 --- json/tests/draft7/optional/format/hostname.json | 10 ++++++++++ jsonschema/_format.py | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/json/tests/draft7/optional/format/hostname.json b/json/tests/draft7/optional/format/hostname.json index a8ecd194f..866a61788 100644 --- a/json/tests/draft7/optional/format/hostname.json +++ b/json/tests/draft7/optional/format/hostname.json @@ -112,6 +112,16 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 789fe4f27..9b4e67b63 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -272,6 +272,10 @@ def is_ipv6(instance: object) -> bool: draft7="hostname", draft201909="hostname", draft202012="hostname", + # fqdn.FQDN("") raises a ValueError due to a bug + # however, it's not clear when or if that will be fixed, so catch it + # here for now + raises=ValueError, ) def is_host_name(instance: object) -> bool: if not isinstance(instance, str): From 4f3a66450481111e0d11c49ca201ba30940a6dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Mon, 20 Jan 2025 10:46:16 +0100 Subject: [PATCH 064/212] docs: add link to check-jsonschema for how to handle generic yaml parsing --- docs/referencing.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/referencing.rst b/docs/referencing.rst index 425cb13a8..223b03363 100644 --- a/docs/referencing.rst +++ b/docs/referencing.rst @@ -220,6 +220,7 @@ Here for instance we retrieve YAML documents in a way similar to the `above `_ file in the check-jsonschema repository. One could similarly imagine a retrieval function which switches on whether to call ``yaml.safe_load`` or ``json.loads`` by file extension (or some more reliable mechanism) and thereby support retrieving references of various different file formats. From 744dbdc5e29dcaacbfddac7dab3a17b73f218fbc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:50:51 +0000 Subject: [PATCH 065/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.1 → v0.9.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.1...v0.9.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bff9fe419..c9b77f112 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.1" + rev: "v0.9.2" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From af86f6f333a6ddf6936875c0affcc7cb97e95b9a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 20:00:33 +0000 Subject: [PATCH 066/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.2 → v0.9.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.2...v0.9.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c9b77f112..bff4927ba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.2" + rev: "v0.9.3" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From b46e6d4d69d298a94b5a9799516eccdd59db88f2 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 30 Jan 2025 08:07:22 -0500 Subject: [PATCH 067/212] Squashed 'json/' changes from 54f3784a..4ba013d5 4ba013d5 Merge pull request #747 from santhosh-tekuri/duration aa500e80 Merge pull request #749 from json-schema-org/gregsdennis/json-everything-update eb8ce976 Merge pull request #757 from ajevans99/main dcdae5c0 Merge pull request #758 from sirosen/hostname-format-check-empty-string db21d21b Merge branch 'main' into hostname-format-check-empty-string 3fd78f04 Merge pull request #1 from ajevans99/swift-json-schema 3cada3a9 Update README.md 82a07749 Merge pull request #753 from json-schema-org/ether/fix-draft-locations a66d23d4 move draft-specific files to the dedicated dir for its draft 8ef15501 Merge pull request #751 from big-andy-coates/format_tests_under_format fe1b1392 All format test cases should be under the `format` directory. b1ee90f6 json-everything moved to an org c00a3f94 test: duration format must start with P 9fc880bf Merge pull request #740 from notEthan/format-pattern-control-char cbd48ea5 Simplify test of \a regex character to test directly against `pattern` schema d6f1010a Merge pull request #746 from json-schema-org/annotations 4aec22c1 Revert the changes to additionalProperties.json. 2dc10671 Move the workflow step title. d9ce71ac May as well also show quotes in the annotation. 1b719a84 Pick the line after the description when attaching spec annotations. 08105151 Markdown is apparently not (yet?) supported in annotations. 81645773 Tidy up the specification annotator a bit. 38628b79 Make the spec URLs structure a bit easier for internal use. 4ebbeaf4 Merge branch 'Era-cell/main' e4bd7554 dumbness2 corrected d8ade402 inside run 57c7c869 changed install location 11f8e511 Added installing command in workflow f2766616 template library, url loads changes c2badb12 Merge pull request #734 from OptimumCode/idn-hostname-arabic-indic-mixed dd9599a5 Merge branch 'main' of github.com:json-schema-org/JSON-Schema-Test-Suite 5b393436 add pr dependencies action 3a509007 Clear existin annotations on same PR 23674123 Cases for rfc and iso written separately 0b780b2c Corected yaml format 2b1ffb74 Best practices followed with optimized code e88a2da6 Works for all OS 7b40efe4 Base path for neighbouring file? 564e6957 Walking through all leaf files 7b84fb44 Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-Suite 891d0265 First workflow2 1c175195 regex correction 96f7683a Final correction2 - file names beautufied 5f050a07 Final correction1 77527b63 Stupidity corrected eb8fd760 Branch name specified 540a269b Log2 f29d090a Wrong location sepcification 582e12be logging logs check df3bdecc path corrected c6b937ca Reading all jsons and spec urls added cbdd1755 change day2 79dc92f1 TOKEN ce52852d Python file location changed 3558c2c6 Fake add to tests eecc7b7a Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-Suite 810d148a First workflow2 4eac02c7 First workflow 40bcb8b3 Corrected replaced unevaluated with additoinalProperties 4ae14268 Add valid first character to avoid Bidi rule violation 202d5625 test: hostname format check fails on empty string git-subtree-dir: json git-subtree-split: 4ba013d58e747ecaf48c8bb7cf248cb0d564afbc --- .github/workflows/pr-dependencies.yml | 12 ++ .../show_specification_annotations.yml | 21 ++++ README.md | 3 +- bin/annotate-specification-links | 115 ++++++++++++++++++ bin/specification_urls.json | 34 ++++++ remotes/{ => draft3}/subSchemas.json | 0 .../locationIndependentIdentifier.json} | 0 remotes/{ => draft4}/name.json | 0 remotes/draft4/subSchemas.json | 10 ++ .../locationIndependentIdentifier.json} | 0 remotes/draft6/name.json | 15 +++ remotes/{ => draft6}/ref-and-definitions.json | 2 +- remotes/draft6/subSchemas.json | 10 ++ .../draft7/locationIndependentIdentifier.json | 11 ++ remotes/draft7/name.json | 15 +++ remotes/draft7/ref-and-definitions.json | 11 ++ remotes/draft7/subSchemas.json | 10 ++ .../draft-next/optional/ecmascript-regex.json | 14 --- .../draft-next/optional/format/duration.json | 5 + .../optional/format/ecmascript-regex.json | 16 +++ .../draft-next/optional/format/hostname.json | 5 + .../optional/format/idn-hostname.json | 7 +- .../optional/format/duration.json | 5 + .../optional/format/hostname.json | 5 + .../optional/format/idn-hostname.json | 7 +- .../optional/ecmascript-regex.json | 14 --- .../optional/format/duration.json | 5 + .../optional/format/ecmascript-regex.json | 16 +++ .../optional/format/hostname.json | 5 + .../optional/format/idn-hostname.json | 7 +- .../{ => format}/ecmascript-regex.json | 0 tests/draft3/optional/format/host-name.json | 5 + tests/draft3/refRemote.json | 4 +- tests/draft4/optional/format/hostname.json | 5 + tests/draft4/refRemote.json | 8 +- tests/draft6/optional/format/hostname.json | 5 + tests/draft6/refRemote.json | 10 +- tests/draft7/optional/format/hostname.json | 5 + .../draft7/optional/format/idn-hostname.json | 7 +- tests/draft7/refRemote.json | 10 +- 40 files changed, 389 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/pr-dependencies.yml create mode 100644 .github/workflows/show_specification_annotations.yml create mode 100755 bin/annotate-specification-links create mode 100644 bin/specification_urls.json rename remotes/{ => draft3}/subSchemas.json (100%) rename remotes/{locationIndependentIdentifierDraft4.json => draft4/locationIndependentIdentifier.json} (100%) rename remotes/{ => draft4}/name.json (100%) create mode 100644 remotes/draft4/subSchemas.json rename remotes/{locationIndependentIdentifierPre2019.json => draft6/locationIndependentIdentifier.json} (100%) create mode 100644 remotes/draft6/name.json rename remotes/{ => draft6}/ref-and-definitions.json (74%) create mode 100644 remotes/draft6/subSchemas.json create mode 100644 remotes/draft7/locationIndependentIdentifier.json create mode 100644 remotes/draft7/name.json create mode 100644 remotes/draft7/ref-and-definitions.json create mode 100644 remotes/draft7/subSchemas.json create mode 100644 tests/draft-next/optional/format/ecmascript-regex.json create mode 100644 tests/draft2020-12/optional/format/ecmascript-regex.json rename tests/draft3/optional/{ => format}/ecmascript-regex.json (100%) diff --git a/.github/workflows/pr-dependencies.yml b/.github/workflows/pr-dependencies.yml new file mode 100644 index 000000000..34a231dcb --- /dev/null +++ b/.github/workflows/pr-dependencies.yml @@ -0,0 +1,12 @@ +name: Check PR Dependencies + +on: pull_request + +jobs: + check_dependencies: + runs-on: ubuntu-latest + name: Check Dependencies + steps: + - uses: gregsdennis/dependencies-action@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/show_specification_annotations.yml b/.github/workflows/show_specification_annotations.yml new file mode 100644 index 000000000..f7d7b398b --- /dev/null +++ b/.github/workflows/show_specification_annotations.yml @@ -0,0 +1,21 @@ +name: Show Specification Annotations + +on: + pull_request: + paths: + - 'tests/**' + +jobs: + annotate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Generate Annotations + run: pip install uritemplate && bin/annotate-specification-links diff --git a/README.md b/README.md index bfdcb501c..0bcad8e52 100644 --- a/README.md +++ b/README.md @@ -293,7 +293,7 @@ Node-specific support is maintained in a [separate repository](https://github.co ### .NET -* [JsonSchema.Net](https://github.com/gregsdennis/json-everything) +* [JsonSchema.Net](https://github.com/json-everything/json-everything) * [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema) ### Perl @@ -339,6 +339,7 @@ Node-specific support is maintained in a [separate repository](https://github.co ### Swift * [JSONSchema](https://github.com/kylef/JSONSchema.swift) +* [swift-json-schema](https://github.com/ajevans99/swift-json-schema) If you use it as well, please fork and send a pull request adding yourself to the list :). diff --git a/bin/annotate-specification-links b/bin/annotate-specification-links new file mode 100755 index 000000000..eebc7e34e --- /dev/null +++ b/bin/annotate-specification-links @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +""" +Annotate pull requests to the GitHub repository with links to specifications. +""" + +from __future__ import annotations + +from pathlib import Path +from typing import Any +import json +import re +import sys + +from uritemplate import URITemplate + + +BIN_DIR = Path(__file__).parent +TESTS = BIN_DIR.parent / "tests" +URLS = json.loads(BIN_DIR.joinpath("specification_urls.json").read_text()) + + +def urls(version: str) -> dict[str, URITemplate]: + """ + Retrieve the version-specific URLs for specifications. + """ + for_version = {**URLS["json-schema"][version], **URLS["external"]} + return {k: URITemplate(v) for k, v in for_version.items()} + + +def annotation( + path: Path, + message: str, + line: int = 1, + level: str = "notice", + **kwargs: Any, +) -> str: + """ + Format a GitHub annotation. + + See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions + for full syntax. + """ + + if kwargs: + additional = "," + ",".join(f"{k}={v}" for k, v in kwargs.items()) + else: + additional = "" + + relative = path.relative_to(TESTS.parent) + return f"::{level} file={relative},line={line}{additional}::{message}\n" + + +def line_number_of(path: Path, case: dict[str, Any]) -> int: + """ + Crudely find the line number of a test case. + """ + with path.open() as file: + description = case["description"] + return next( + (i + 1 for i, line in enumerate(file, 1) if description in line), + 1, + ) + + +def main(): + # Clear annotations which may have been emitted by a previous run. + sys.stdout.write("::remove-matcher owner=me::\n") + + for version in TESTS.iterdir(): + if version.name in {"draft-next", "latest"}: + continue + + version_urls = urls(version.name) + + for path in version.rglob("*.json"): + try: + contents = json.loads(path.read_text()) + except json.JSONDecodeError as error: + error = annotation( + level="error", + path=path, + line=error.lineno, + col=error.pos + 1, + title=str(error), + ) + sys.stdout.write(error) + + for test_case in contents: + specifications = test_case.get("specification") + if specifications is not None: + for each in specifications: + quote = each.pop("quote", "") + (kind, section), = each.items() + + number = re.search(r"\d+", kind) + spec = "" if number is None else number.group(0) + + url = version_urls[kind].expand( + spec=spec, + section=section, + ) + + message = f"{url}\n\n{quote}" if quote else url + sys.stdout.write( + annotation( + path=path, + line=line_number_of(path, test_case), + title="Specification Link", + message=message, + ), + ) + + +if __name__ == "__main__": + main() diff --git a/bin/specification_urls.json b/bin/specification_urls.json new file mode 100644 index 000000000..9b985e97d --- /dev/null +++ b/bin/specification_urls.json @@ -0,0 +1,34 @@ +{ + "json-schema": { + "draft2020-12": { + "core": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-{section}", + "validation": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#section-{section}" + }, + "draft2019-09": { + "core": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.{section}", + "validation": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-validation-02#rfc.section.{section}" + }, + "draft7": { + "core": "https://json-schema.org/draft-07/draft-handrews-json-schema-01#rfc.section.{section}", + "validation": "https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01#rfc.section.{section}" + }, + "draft6": { + "core": "https://json-schema.org/draft-06/draft-wright-json-schema-01#rfc.section.{section}", + "validation": "https://json-schema.org/draft-06/draft-wright-json-schema-validation-01#rfc.section.{section}" + }, + "draft4": { + "core": "https://json-schema.org/draft-04/draft-zyp-json-schema-04#rfc.section.{section}", + "validation": "https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.{section}" + }, + "draft3": { + "core": "https://json-schema.org/draft-03/draft-zyp-json-schema-03.pdf" + } + }, + + "external": { + "ecma262": "https://262.ecma-international.org/{section}", + "perl5": "https://perldoc.perl.org/perlre#{section}", + "rfc": "https://www.rfc-editor.org/rfc/{spec}.txt#{section}", + "iso": "https://www.iso.org/obp/ui" + } +} diff --git a/remotes/subSchemas.json b/remotes/draft3/subSchemas.json similarity index 100% rename from remotes/subSchemas.json rename to remotes/draft3/subSchemas.json diff --git a/remotes/locationIndependentIdentifierDraft4.json b/remotes/draft4/locationIndependentIdentifier.json similarity index 100% rename from remotes/locationIndependentIdentifierDraft4.json rename to remotes/draft4/locationIndependentIdentifier.json diff --git a/remotes/name.json b/remotes/draft4/name.json similarity index 100% rename from remotes/name.json rename to remotes/draft4/name.json diff --git a/remotes/draft4/subSchemas.json b/remotes/draft4/subSchemas.json new file mode 100644 index 000000000..6e9b3de35 --- /dev/null +++ b/remotes/draft4/subSchemas.json @@ -0,0 +1,10 @@ +{ + "definitions": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/definitions/integer" + } + } +} diff --git a/remotes/locationIndependentIdentifierPre2019.json b/remotes/draft6/locationIndependentIdentifier.json similarity index 100% rename from remotes/locationIndependentIdentifierPre2019.json rename to remotes/draft6/locationIndependentIdentifier.json diff --git a/remotes/draft6/name.json b/remotes/draft6/name.json new file mode 100644 index 000000000..fceacb809 --- /dev/null +++ b/remotes/draft6/name.json @@ -0,0 +1,15 @@ +{ + "definitions": { + "orNull": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#" + } + ] + } + }, + "type": "string" +} diff --git a/remotes/ref-and-definitions.json b/remotes/draft6/ref-and-definitions.json similarity index 74% rename from remotes/ref-and-definitions.json rename to remotes/draft6/ref-and-definitions.json index e0ee802a9..b80deeb7b 100644 --- a/remotes/ref-and-definitions.json +++ b/remotes/draft6/ref-and-definitions.json @@ -1,5 +1,5 @@ { - "$id": "http://localhost:1234/ref-and-definitions.json", + "$id": "http://localhost:1234/draft6/ref-and-definitions.json", "definitions": { "inner": { "properties": { diff --git a/remotes/draft6/subSchemas.json b/remotes/draft6/subSchemas.json new file mode 100644 index 000000000..6e9b3de35 --- /dev/null +++ b/remotes/draft6/subSchemas.json @@ -0,0 +1,10 @@ +{ + "definitions": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/definitions/integer" + } + } +} diff --git a/remotes/draft7/locationIndependentIdentifier.json b/remotes/draft7/locationIndependentIdentifier.json new file mode 100644 index 000000000..e72815cd5 --- /dev/null +++ b/remotes/draft7/locationIndependentIdentifier.json @@ -0,0 +1,11 @@ +{ + "definitions": { + "refToInteger": { + "$ref": "#foo" + }, + "A": { + "$id": "#foo", + "type": "integer" + } + } +} diff --git a/remotes/draft7/name.json b/remotes/draft7/name.json new file mode 100644 index 000000000..fceacb809 --- /dev/null +++ b/remotes/draft7/name.json @@ -0,0 +1,15 @@ +{ + "definitions": { + "orNull": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#" + } + ] + } + }, + "type": "string" +} diff --git a/remotes/draft7/ref-and-definitions.json b/remotes/draft7/ref-and-definitions.json new file mode 100644 index 000000000..d5929380c --- /dev/null +++ b/remotes/draft7/ref-and-definitions.json @@ -0,0 +1,11 @@ +{ + "$id": "http://localhost:1234/draft7/ref-and-definitions.json", + "definitions": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "allOf": [ { "$ref": "#/definitions/inner" } ] +} diff --git a/remotes/draft7/subSchemas.json b/remotes/draft7/subSchemas.json new file mode 100644 index 000000000..6e9b3de35 --- /dev/null +++ b/remotes/draft7/subSchemas.json @@ -0,0 +1,10 @@ +{ + "definitions": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/definitions/integer" + } + } +} diff --git a/tests/draft-next/optional/ecmascript-regex.json b/tests/draft-next/optional/ecmascript-regex.json index 272114503..a1a4f9638 100644 --- a/tests/draft-next/optional/ecmascript-regex.json +++ b/tests/draft-next/optional/ecmascript-regex.json @@ -405,20 +405,6 @@ } ] }, - { - "description": "\\a is not an ECMA 262 control escape", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "https://json-schema.org/draft/next/schema" - }, - "tests": [ - { - "description": "when used as a pattern", - "data": { "pattern": "\\a" }, - "valid": false - } - ] - }, { "description": "pattern with non-ASCII digits", "schema": { diff --git a/tests/draft-next/optional/format/duration.json b/tests/draft-next/optional/format/duration.json index d5adca206..c4aa66bae 100644 --- a/tests/draft-next/optional/format/duration.json +++ b/tests/draft-next/optional/format/duration.json @@ -46,6 +46,11 @@ "data": "PT1D", "valid": false }, + { + "description": "must start with P", + "data": "4DT12H30M5S", + "valid": false + }, { "description": "no elements present", "data": "P", diff --git a/tests/draft-next/optional/format/ecmascript-regex.json b/tests/draft-next/optional/format/ecmascript-regex.json new file mode 100644 index 000000000..1e19c2729 --- /dev/null +++ b/tests/draft-next/optional/format/ecmascript-regex.json @@ -0,0 +1,16 @@ +[ + { + "description": "\\a is not an ECMA 262 control escape", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "format": "regex" + }, + "tests": [ + { + "description": "when used as a pattern", + "data": "\\a", + "valid": false + } + ] + } +] diff --git a/tests/draft-next/optional/format/hostname.json b/tests/draft-next/optional/format/hostname.json index bfb306363..f4819efa6 100644 --- a/tests/draft-next/optional/format/hostname.json +++ b/tests/draft-next/optional/format/hostname.json @@ -120,6 +120,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft-next/optional/format/idn-hostname.json b/tests/draft-next/optional/format/idn-hostname.json index 109bf73c9..9abe2d93e 100644 --- a/tests/draft-next/optional/format/idn-hostname.json +++ b/tests/draft-next/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -326,6 +326,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft2019-09/optional/format/duration.json b/tests/draft2019-09/optional/format/duration.json index 00d5f47ae..2d515a64a 100644 --- a/tests/draft2019-09/optional/format/duration.json +++ b/tests/draft2019-09/optional/format/duration.json @@ -46,6 +46,11 @@ "data": "PT1D", "valid": false }, + { + "description": "must start with P", + "data": "4DT12H30M5S", + "valid": false + }, { "description": "no elements present", "data": "P", diff --git a/tests/draft2019-09/optional/format/hostname.json b/tests/draft2019-09/optional/format/hostname.json index f3b7181c8..9db7c9678 100644 --- a/tests/draft2019-09/optional/format/hostname.json +++ b/tests/draft2019-09/optional/format/hostname.json @@ -120,6 +120,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft2019-09/optional/format/idn-hostname.json b/tests/draft2019-09/optional/format/idn-hostname.json index 072a6b08e..05bff0df7 100644 --- a/tests/draft2019-09/optional/format/idn-hostname.json +++ b/tests/draft2019-09/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -326,6 +326,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft2020-12/optional/ecmascript-regex.json b/tests/draft2020-12/optional/ecmascript-regex.json index 23b962e4b..a4d62e0cf 100644 --- a/tests/draft2020-12/optional/ecmascript-regex.json +++ b/tests/draft2020-12/optional/ecmascript-regex.json @@ -405,20 +405,6 @@ } ] }, - { - "description": "\\a is not an ECMA 262 control escape", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, - "tests": [ - { - "description": "when used as a pattern", - "data": { "pattern": "\\a" }, - "valid": false - } - ] - }, { "description": "pattern with non-ASCII digits", "schema": { diff --git a/tests/draft2020-12/optional/format/duration.json b/tests/draft2020-12/optional/format/duration.json index a3af56ef0..a09fec5ef 100644 --- a/tests/draft2020-12/optional/format/duration.json +++ b/tests/draft2020-12/optional/format/duration.json @@ -46,6 +46,11 @@ "data": "PT1D", "valid": false }, + { + "description": "must start with P", + "data": "4DT12H30M5S", + "valid": false + }, { "description": "no elements present", "data": "P", diff --git a/tests/draft2020-12/optional/format/ecmascript-regex.json b/tests/draft2020-12/optional/format/ecmascript-regex.json new file mode 100644 index 000000000..b0648084a --- /dev/null +++ b/tests/draft2020-12/optional/format/ecmascript-regex.json @@ -0,0 +1,16 @@ +[ + { + "description": "\\a is not an ECMA 262 control escape", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "format": "regex" + }, + "tests": [ + { + "description": "when used as a pattern", + "data": "\\a", + "valid": false + } + ] + } +] \ No newline at end of file diff --git a/tests/draft2020-12/optional/format/hostname.json b/tests/draft2020-12/optional/format/hostname.json index 41418dd4a..0e00af2c2 100644 --- a/tests/draft2020-12/optional/format/hostname.json +++ b/tests/draft2020-12/optional/format/hostname.json @@ -120,6 +120,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft2020-12/optional/format/idn-hostname.json b/tests/draft2020-12/optional/format/idn-hostname.json index bc7d92f66..30a0f494c 100644 --- a/tests/draft2020-12/optional/format/idn-hostname.json +++ b/tests/draft2020-12/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -326,6 +326,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft3/optional/ecmascript-regex.json b/tests/draft3/optional/format/ecmascript-regex.json similarity index 100% rename from tests/draft3/optional/ecmascript-regex.json rename to tests/draft3/optional/format/ecmascript-regex.json diff --git a/tests/draft3/optional/format/host-name.json b/tests/draft3/optional/format/host-name.json index d418f3763..9a75c3c20 100644 --- a/tests/draft3/optional/format/host-name.json +++ b/tests/draft3/optional/format/host-name.json @@ -57,6 +57,11 @@ "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft3/refRemote.json b/tests/draft3/refRemote.json index 0e4ab53e0..81a6c5116 100644 --- a/tests/draft3/refRemote.json +++ b/tests/draft3/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft4/optional/format/hostname.json b/tests/draft4/optional/format/hostname.json index a8ecd194f..d7c72a7ff 100644 --- a/tests/draft4/optional/format/hostname.json +++ b/tests/draft4/optional/format/hostname.json @@ -112,6 +112,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft4/refRemote.json b/tests/draft4/refRemote.json index 64a618b89..65e45190c 100644 --- a/tests/draft4/refRemote.json +++ b/tests/draft4/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "name.json#/definitions/orNull"} + "name": {"$ref": "draft4/name.json#/definitions/orNull"} } }, "tests": [ @@ -171,7 +171,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/locationIndependentIdentifierDraft4.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft4/locationIndependentIdentifier.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft6/optional/format/hostname.json b/tests/draft6/optional/format/hostname.json index a8ecd194f..d7c72a7ff 100644 --- a/tests/draft6/optional/format/hostname.json +++ b/tests/draft6/optional/format/hostname.json @@ -112,6 +112,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft6/refRemote.json b/tests/draft6/refRemote.json index 28459c4a0..49ead6d1f 100644 --- a/tests/draft6/refRemote.json +++ b/tests/draft6/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "$id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "name.json#/definitions/orNull"} + "name": {"$ref": "draft6/name.json#/definitions/orNull"} } }, "tests": [ @@ -173,7 +173,7 @@ "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ - { "$ref": "ref-and-definitions.json" } + { "$ref": "draft6/ref-and-definitions.json" } ] }, "tests": [ @@ -196,7 +196,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft6/locationIndependentIdentifier.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft7/optional/format/hostname.json b/tests/draft7/optional/format/hostname.json index a8ecd194f..d7c72a7ff 100644 --- a/tests/draft7/optional/format/hostname.json +++ b/tests/draft7/optional/format/hostname.json @@ -112,6 +112,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft7/optional/format/idn-hostname.json b/tests/draft7/optional/format/idn-hostname.json index dc47f7b5c..068470ead 100644 --- a/tests/draft7/optional/format/idn-hostname.json +++ b/tests/draft7/optional/format/idn-hostname.json @@ -254,7 +254,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -318,6 +318,11 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft7/refRemote.json b/tests/draft7/refRemote.json index 22185d678..450787af6 100644 --- a/tests/draft7/refRemote.json +++ b/tests/draft7/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "$id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "name.json#/definitions/orNull"} + "name": {"$ref": "draft7/name.json#/definitions/orNull"} } }, "tests": [ @@ -173,7 +173,7 @@ "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ - { "$ref": "ref-and-definitions.json" } + { "$ref": "draft7/ref-and-definitions.json" } ] }, "tests": [ @@ -196,7 +196,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft7/locationIndependentIdentifier.json#/definitions/refToInteger" }, "tests": [ { From e9bc018f16c460ee78f9da380d038b7e8af50936 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 30 Jan 2025 10:57:08 -0500 Subject: [PATCH 068/212] Update docs requirements. --- docs/requirements.in | 5 +---- docs/requirements.txt | 26 ++++++++++---------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/docs/requirements.in b/docs/requirements.in index 5a68be72b..ae66984ae 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,4 +1,4 @@ -file:.#egg=jsonschema +file:. furo lxml sphinx!=7.2.5 @@ -8,6 +8,3 @@ sphinx-copybutton sphinx-json-schema-spec sphinxcontrib-spelling sphinxext-opengraph - -# Until pyenchant/pyenchant#302 is released... -pyenchant>=3.3.0rc1 diff --git a/docs/requirements.txt b/docs/requirements.txt index b329416a9..7ca0f1d13 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,14 +1,10 @@ -# -# This file is autogenerated by pip-compile with Python 3.12 -# by the following command: -# -# pip-compile --strip-extras docs/requirements.in -# +# This file was autogenerated by uv via the following command: +# uv pip compile --output-file /Users/julian/Development/jsonschema/docs/requirements.txt docs/requirements.in alabaster==1.0.0 # via sphinx astroid==3.3.8 # via sphinx-autoapi -attrs==24.3.0 +attrs==25.1.0 # via # jsonschema # referencing @@ -32,7 +28,7 @@ jinja2==3.1.5 # via # sphinx # sphinx-autoapi -file:.#egg=jsonschema +jsonschema @ file:. # via -r docs/requirements.in jsonschema-specifications==2024.10.1 # via jsonschema @@ -44,17 +40,15 @@ markupsafe==3.0.2 # via jinja2 packaging==24.2 # via sphinx -pyenchant==3.3.0rc1 - # via - # -r docs/requirements.in - # sphinxcontrib-spelling -pygments==2.18.0 +pyenchant==3.2.2 + # via sphinxcontrib-spelling +pygments==2.19.1 # via # furo # sphinx pyyaml==6.0.2 # via sphinx-autoapi -referencing==0.35.1 +referencing==0.36.2 # via # jsonschema # jsonschema-specifications @@ -83,13 +77,13 @@ sphinx==8.1.3 # sphinxext-opengraph sphinx-autoapi==3.4.0 # via -r docs/requirements.in -sphinx-autodoc-typehints==2.5.0 +sphinx-autodoc-typehints==3.0.1 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo sphinx-copybutton==0.5.2 # via -r docs/requirements.in -sphinx-json-schema-spec==2024.1.1 +sphinx-json-schema-spec==2025.1.1 # via -r docs/requirements.in sphinxcontrib-applehelp==2.0.0 # via sphinx From 2f299b9cd084a99fd04eaa29878a5adeee862c7f Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 30 Jan 2025 11:00:14 -0500 Subject: [PATCH 069/212] Use uv in CI. --- .github/workflows/ci.yml | 53 +++++++++++++++++----------------------- noxfile.py | 33 +++++++++++++++---------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b26540182..4f1d3f24a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,44 +7,32 @@ on: tags: - "v*" pull_request: - release: - types: [published] schedule: # Daily at 3:21 - cron: "21 3 * * *" workflow_dispatch: -env: - PIP_DISABLE_PIP_VERSION_CHECK: "1" - PIP_NO_PYTHON_VERSION_WARNING: "1" - jobs: - pre-commit: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: "3.x" - - uses: pre-commit/action@v3.0.1 - list: runs-on: ubuntu-latest outputs: noxenvs: ${{ steps.noxenvs-matrix.outputs.noxenvs }} steps: - uses: actions/checkout@v4 - - name: Set up nox - uses: wntrblm/nox@2024.10.09 + - name: Set up uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true - id: noxenvs-matrix run: | echo >>$GITHUB_OUTPUT noxenvs=$( - nox --list-sessions --json | jq '[.[].session]' + uvx nox --list-sessions --json | jq '[.[].session]' ) ci: needs: list runs-on: ${{ matrix.os }} + strategy: fail-fast: false matrix: @@ -53,10 +41,10 @@ jobs: posargs: [""] include: - os: ubuntu-latest - noxenv: "tests-3.11(format)" + noxenv: "tests-3.13(format)" posargs: coverage github - os: ubuntu-latest - noxenv: "tests-3.11(no-extras)" + noxenv: "tests-3.13(no-extras)" posargs: coverage github exclude: - os: windows-latest @@ -89,13 +77,17 @@ jobs: 3.13 pypy3.10 allow-prereleases: true - - name: Set up nox - uses: wntrblm/nox@2024.10.09 - name: Enable UTF-8 on Windows run: echo "PYTHONUTF8=1" >> $env:GITHUB_ENV if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') + + - name: Set up uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true + - name: Run nox - run: nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }} + run: uvx nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }} packaging: needs: ci @@ -103,6 +95,7 @@ jobs: environment: name: PyPI url: https://pypi.org/p/jsonschema + permissions: contents: write id-token: write @@ -111,14 +104,14 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v5 + - name: Set up uv + uses: astral-sh/setup-uv@v5 with: - python-version: "3.x" - - name: Install dependencies - run: python -m pip install build - - name: Create packages - run: python -m build . + enable-cache: true + + - name: Build our distributions + run: uv run --with 'build[uv]' -m build --installer=uv + - name: Publish to PyPI if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/noxfile.py b/noxfile.py index 21a7faac2..988012d24 100644 --- a/noxfile.py +++ b/noxfile.py @@ -22,7 +22,7 @@ docs=DOCS / "requirements.txt", ) REQUIREMENTS_IN = [ # this is actually ordered, as files depend on each other - path.parent / f"{path.stem}.in" for path in REQUIREMENTS.values() + (path.parent / f"{path.stem}.in", path) for path in REQUIREMENTS.values() ] NONGPL_LICENSES = [ @@ -38,6 +38,7 @@ SUPPORTED = ["3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"] LATEST_STABLE = SUPPORTED[-1] +nox.options.default_venv_backend = "uv|virtualenv" nox.options.sessions = [] @@ -136,9 +137,15 @@ def build(session): """ Build a distribution suitable for PyPI and check its validity. """ - session.install("build", "docutils", "twine") + session.install("build[uv]", "docutils", "twine") with TemporaryDirectory() as tmpdir: - session.run("python", "-m", "build", ROOT, "--outdir", tmpdir) + session.run( + "pyproject-build", + "--installer=uv", + ROOT, + "--outdir", + tmpdir, + ) session.run("twine", "check", "--strict", tmpdir + "/*") session.run( "python", "-m", "docutils", "--strict", CHANGELOG, os.devnull, @@ -247,13 +254,13 @@ def requirements(session): You should commit the result afterwards. """ - session.install("pip-tools") - for each in REQUIREMENTS_IN: - session.run( - "pip-compile", - "--resolver", - "backtracking", - "--strip-extras", - "-U", - each.relative_to(ROOT), - ) + if session.venv_backend == "uv": + cmd = ["uv", "pip", "compile"] + else: + session.install("pip-tools") + cmd = ["pip-compile", "--resolver", "backtracking", "--strip-extras"] + + for each, out in REQUIREMENTS_IN: + # otherwise output files end up with silly absolute path comments... + relative = each.relative_to(ROOT) + session.run(*cmd, "--upgrade", "--output-file", out, relative) From bdee92d36fd1bc3ce6ceb941ac2eae98e56695ff Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Jan 2025 11:00:37 -0500 Subject: [PATCH 070/212] Cope with the suite permuting of ECMA format tests. Refs: json-schema-org/JSON-Schema-Test-Suite#751 --- .../tests/test_jsonschema_test_suite.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index d1b0ebc05..41c982553 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -26,6 +26,11 @@ def skipper(test): return skipper +def ecmascript_regex(test): + if test.subject == "ecmascript-regex": + return "ECMA regex support will be added in #1142." + + def missing_format(Validator): def missing_format(test): # pragma: no cover schema = test.schema @@ -119,7 +124,8 @@ def leap_second(test): Validator=jsonschema.Draft3Validator, format_checker=jsonschema.Draft3Validator.FORMAT_CHECKER, skip=lambda test: ( - missing_format(jsonschema.Draft3Validator)(test) + ecmascript_regex(test) + or missing_format(jsonschema.Draft3Validator)(test) or complex_email_validation(test) ), ) @@ -136,7 +142,8 @@ def leap_second(test): Validator=jsonschema.Draft4Validator, format_checker=jsonschema.Draft4Validator.FORMAT_CHECKER, skip=lambda test: ( - leap_second(test) + ecmascript_regex(test) + or leap_second(test) or missing_format(jsonschema.Draft4Validator)(test) or complex_email_validation(test) ), @@ -153,7 +160,8 @@ def leap_second(test): Validator=jsonschema.Draft6Validator, format_checker=jsonschema.Draft6Validator.FORMAT_CHECKER, skip=lambda test: ( - leap_second(test) + ecmascript_regex(test) + or leap_second(test) or missing_format(jsonschema.Draft6Validator)(test) or complex_email_validation(test) ), @@ -172,7 +180,8 @@ def leap_second(test): Validator=jsonschema.Draft7Validator, format_checker=jsonschema.Draft7Validator.FORMAT_CHECKER, skip=lambda test: ( - leap_second(test) + ecmascript_regex(test) + or leap_second(test) or missing_format(jsonschema.Draft7Validator)(test) or complex_email_validation(test) ), @@ -208,6 +217,7 @@ def leap_second(test): format_checker=jsonschema.Draft201909Validator.FORMAT_CHECKER, skip=lambda test: ( complex_email_validation(test) + or ecmascript_regex(test) or leap_second(test) or missing_format(jsonschema.Draft201909Validator)(test) or complex_email_validation(test) @@ -244,6 +254,7 @@ def leap_second(test): format_checker=jsonschema.Draft202012Validator.FORMAT_CHECKER, skip=lambda test: ( complex_email_validation(test) + or ecmascript_regex(test) or leap_second(test) or missing_format(jsonschema.Draft202012Validator)(test) or complex_email_validation(test) From e6f4a038886d572fbb5733202b44604837cc1884 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Jan 2025 11:01:29 -0500 Subject: [PATCH 071/212] Cope with the suite permuting of remotes. This new-but-similarly-messy logic comes modified from Bowtie (which itself may need to be modified there, we'll see). `jsonschema_suite remotes` is somewhat semantically broken (as it doesn't really help with not emitting schemas which aren't valid under the version under test), so it's time to give up and use the other filesystem mechanism of walking the remotes directory. Refs: json-schema-org/JSON-Schema-Test-Suite#753 --- jsonschema/tests/_suite.py | 75 +++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/jsonschema/tests/_suite.py b/jsonschema/tests/_suite.py index 0da6503c1..d61d38277 100644 --- a/jsonschema/tests/_suite.py +++ b/jsonschema/tests/_suite.py @@ -10,7 +10,6 @@ import json import os import re -import subprocess import sys import unittest @@ -21,11 +20,14 @@ if TYPE_CHECKING: from collections.abc import Iterable, Mapping, Sequence + from referencing.jsonschema import Schema import pyperf from jsonschema.validators import _VALIDATORS import jsonschema +MAGIC_REMOTE_URL = "http://localhost:1234" + _DELIMITERS = re.compile(r"[\W\- ]+") @@ -51,38 +53,7 @@ def _find_suite(): class Suite: _root: Path = field(factory=_find_suite) - _remotes: referencing.jsonschema.SchemaRegistry = field(init=False) - - def __attrs_post_init__(self): - jsonschema_suite = self._root.joinpath("bin", "jsonschema_suite") - argv = [sys.executable, str(jsonschema_suite), "remotes"] - remotes = subprocess.check_output(argv).decode("utf-8") - - resources = json.loads(remotes) - li = "http://localhost:1234/locationIndependentIdentifierPre2019.json" - li4 = "http://localhost:1234/locationIndependentIdentifierDraft4.json" - - registry = Registry().with_resources( - [ - ( - li, - referencing.jsonschema.DRAFT7.create_resource( - contents=resources.pop(li), - ), - ), - ( - li4, - referencing.jsonschema.DRAFT4.create_resource( - contents=resources.pop(li4), - ), - ), - ], - ).with_contents( - resources.items(), - default_specification=referencing.jsonschema.DRAFT202012, - ) - object.__setattr__(self, "_remotes", registry) def benchmark(self, runner: pyperf.Runner): # pragma: no cover for name, Validator in _VALIDATORS.items(): @@ -92,10 +63,18 @@ def benchmark(self, runner: pyperf.Runner): # pragma: no cover ) def version(self, name) -> Version: + Validator = _VALIDATORS[name] + uri: str = Validator.ID_OF(Validator.META_SCHEMA) # type: ignore[assignment] + specification = referencing.jsonschema.specification_with(uri) + + registry = Registry().with_contents( + remotes_in(root=self._root / "remotes", name=name, uri=uri), + default_specification=specification, + ) return Version( name=name, path=self._root / "tests" / name, - remotes=self._remotes, + remotes=registry, ) @@ -187,6 +166,36 @@ def benchmark(self, runner: pyperf.Runner, **kwargs): # pragma: no cover ) +def remotes_in( + root: Path, + name: str, + uri: str, +) -> Iterable[tuple[str, Schema]]: + # This messy logic is because the test suite is terrible at indicating + # what remotes are needed for what drafts, and mixes in schemas which + # have no $schema and which are invalid under earlier versions, in with + # other schemas which are needed for tests. + + for each in root.rglob("*.json"): + schema = json.loads(each.read_text()) + + relative = str(each.relative_to(root)).replace("\\", "/") + + if ( + ( # invalid boolean schema + name in {"draft3", "draft4"} + and each.stem == "tree" + ) or + ( # draft/*.json + "$schema" not in schema + and relative.startswith("draft") + and not relative.startswith(name) + ) + ): + continue + yield f"{MAGIC_REMOTE_URL}/{relative}", schema + + @frozen(repr=False) class _Test: From 1bbd9c2a9e3b941d57efb498c3c3467b418b2fdc Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Jan 2025 11:06:15 -0500 Subject: [PATCH 072/212] Don't scan the upstream test suite for secrets. --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 988012d24..0485172c4 100644 --- a/noxfile.py +++ b/noxfile.py @@ -158,7 +158,7 @@ def secrets(session): Check for accidentally committed secrets. """ session.install("detect-secrets") - session.run("detect-secrets", "scan", ROOT) + session.run("detect-secrets", "scan", ROOT, "--exclude-files", "json/") @session(tags=["style"]) From 15a9f32831e3e869e2215197f0b4b38d790a3ce4 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Jan 2025 12:00:13 -0500 Subject: [PATCH 073/212] Only run docs builds on Linux. I have no idea why CI is failing to find enchant (possibly a need to set LIBRARY_PATH in GH Actions) but it's fine for now to just run this on one OS. --- .github/workflows/ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f1d3f24a..2349b73a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,18 @@ jobs: noxenv: "tests-3.13(no-extras)" posargs: coverage github exclude: + - os: macos-latest + noxenv: "docs(dirhtml)" + - os: macos-latest + noxenv: "docs(doctest)" + - os: macos-latest + noxenv: "docs(linkcheck)" + - os: macos-latest + noxenv: "docs(man)" + - os: macos-latest + noxenv: "docs(spelling)" + - os: macos-latest + noxenv: "docs(style)" - os: windows-latest noxenv: "docs(dirhtml)" - os: windows-latest From af6b3723b5260b8d1cea427c3f4269106711e3cf Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Jan 2025 12:46:22 -0500 Subject: [PATCH 074/212] Squashed 'json/' changes from 4ba013d5..e524505b e524505b Merge pull request #759 from sirosen/hostname-format-reject-single-dot 4a3efd18 Add negative tests for "." for hostname formats git-subtree-dir: json git-subtree-split: e524505b8ac4a61c5dc162b51d68c2385a134706 --- tests/draft-next/optional/format/hostname.json | 5 +++++ tests/draft-next/optional/format/idn-hostname.json | 5 +++++ tests/draft2019-09/optional/format/hostname.json | 5 +++++ tests/draft2019-09/optional/format/idn-hostname.json | 5 +++++ tests/draft2020-12/optional/format/hostname.json | 5 +++++ tests/draft2020-12/optional/format/idn-hostname.json | 5 +++++ tests/draft4/optional/format/hostname.json | 5 +++++ tests/draft6/optional/format/hostname.json | 5 +++++ tests/draft7/optional/format/hostname.json | 5 +++++ tests/draft7/optional/format/idn-hostname.json | 5 +++++ 10 files changed, 50 insertions(+) diff --git a/tests/draft-next/optional/format/hostname.json b/tests/draft-next/optional/format/hostname.json index f4819efa6..bc3a60dcc 100644 --- a/tests/draft-next/optional/format/hostname.json +++ b/tests/draft-next/optional/format/hostname.json @@ -125,6 +125,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft-next/optional/format/idn-hostname.json b/tests/draft-next/optional/format/idn-hostname.json index 9abe2d93e..fa348fe62 100644 --- a/tests/draft-next/optional/format/idn-hostname.json +++ b/tests/draft-next/optional/format/idn-hostname.json @@ -331,6 +331,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft2019-09/optional/format/hostname.json b/tests/draft2019-09/optional/format/hostname.json index 9db7c9678..24bfdfc5a 100644 --- a/tests/draft2019-09/optional/format/hostname.json +++ b/tests/draft2019-09/optional/format/hostname.json @@ -125,6 +125,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft2019-09/optional/format/idn-hostname.json b/tests/draft2019-09/optional/format/idn-hostname.json index 05bff0df7..3e0b6497f 100644 --- a/tests/draft2019-09/optional/format/idn-hostname.json +++ b/tests/draft2019-09/optional/format/idn-hostname.json @@ -331,6 +331,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft2020-12/optional/format/hostname.json b/tests/draft2020-12/optional/format/hostname.json index 0e00af2c2..57827c4d4 100644 --- a/tests/draft2020-12/optional/format/hostname.json +++ b/tests/draft2020-12/optional/format/hostname.json @@ -125,6 +125,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft2020-12/optional/format/idn-hostname.json b/tests/draft2020-12/optional/format/idn-hostname.json index 30a0f494c..eb91b5a41 100644 --- a/tests/draft2020-12/optional/format/idn-hostname.json +++ b/tests/draft2020-12/optional/format/idn-hostname.json @@ -331,6 +331,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft4/optional/format/hostname.json b/tests/draft4/optional/format/hostname.json index d7c72a7ff..866a61788 100644 --- a/tests/draft4/optional/format/hostname.json +++ b/tests/draft4/optional/format/hostname.json @@ -117,6 +117,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft6/optional/format/hostname.json b/tests/draft6/optional/format/hostname.json index d7c72a7ff..866a61788 100644 --- a/tests/draft6/optional/format/hostname.json +++ b/tests/draft6/optional/format/hostname.json @@ -117,6 +117,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft7/optional/format/hostname.json b/tests/draft7/optional/format/hostname.json index d7c72a7ff..866a61788 100644 --- a/tests/draft7/optional/format/hostname.json +++ b/tests/draft7/optional/format/hostname.json @@ -117,6 +117,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft7/optional/format/idn-hostname.json b/tests/draft7/optional/format/idn-hostname.json index 068470ead..0fe07e1ee 100644 --- a/tests/draft7/optional/format/idn-hostname.json +++ b/tests/draft7/optional/format/idn-hostname.json @@ -323,6 +323,11 @@ "description": "empty string", "data": "", "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } From ed216bc16b57b4fb71ca7ea1727c8e84cd24e623 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 20:20:54 +0000 Subject: [PATCH 075/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.3 → v0.9.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.3...v0.9.4) - [github.com/PyCQA/isort: 5.13.2 → 6.0.0](https://github.com/PyCQA/isort/compare/5.13.2...6.0.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bff4927ba..9d8ff961a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,12 +16,12 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.3" + rev: "v0.9.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/PyCQA/isort - rev: 5.13.2 + rev: 6.0.0 hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-prettier From c4ec521658aefe195769408945b4526620fa4602 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2025 20:03:01 +0000 Subject: [PATCH 076/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.4 → v0.9.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.4...v0.9.6) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9d8ff961a..f085d0719 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.4" + rev: "v0.9.6" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From d1b69fc7c69fca9f04cfdd3ee3b1f156fc97a5f1 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 19 Feb 2025 11:17:58 -0500 Subject: [PATCH 077/212] Squashed 'json/' changes from e524505b..83e866b4 83e866b4 Merge pull request #763 from michaelmior/propertynames-const c5a9703f Merge pull request #760 from OptimumCode/rfc3490-label-separator b4c09b65 Add tests for propertyNames with const/enum 4fa572d8 Move tests for rfc3490#3.1 into a separate test case ce9f68ca Add link to rfc and quote ad94cacc Add test cases for other valid label separators in IDN hostnames 39002ae7 Merge pull request #762 from OptimumCode/rfc-html-link c8780535 Correct section anchor for rfc URL template 5f2ca7d6 Modify rfc url template to use html version 9c5d99b6 Merge pull request #761 from OptimumCode/annotation-script-rfc-support 9563ce7b Correct rfc URL template - incorrect path pattern was used 961bfad0 Correct spec kind extraction from defined key. Continue on unkown URL kind git-subtree-dir: json git-subtree-split: 83e866b46c9f9e7082fd51e83a61c5f2145a1ab7 --- bin/annotate-specification-links | 33 +++++++- bin/specification_urls.json | 2 +- .../optional/format/idn-hostname.json | 49 ++++++++++- .../optional/format/idn-hostname.json | 49 ++++++++++- tests/draft2019-09/propertyNames.json | 53 ++++++++++++ .../optional/format/idn-hostname.json | 49 ++++++++++- tests/draft2020-12/propertyNames.json | 83 +++++++++++++++++++ tests/draft6/propertyNames.json | 47 +++++++++++ .../draft7/optional/format/idn-hostname.json | 46 +++++++++- tests/draft7/propertyNames.json | 47 +++++++++++ 10 files changed, 449 insertions(+), 9 deletions(-) diff --git a/bin/annotate-specification-links b/bin/annotate-specification-links index eebc7e34e..963768b43 100755 --- a/bin/annotate-specification-links +++ b/bin/annotate-specification-links @@ -61,6 +61,18 @@ def line_number_of(path: Path, case: dict[str, Any]) -> int: 1, ) +def extract_kind_and_spec(key: str) -> (str, str): + """ + Extracts specification number and kind from the defined key + """ + can_have_spec = ["rfc", "iso"] + if not any(key.startswith(el) for el in can_have_spec): + return key, "" + number = re.search(r"\d+", key) + spec = "" if number is None else number.group(0) + kind = key.removesuffix(spec) + return kind, spec + def main(): # Clear annotations which may have been emitted by a previous run. @@ -82,20 +94,33 @@ def main(): line=error.lineno, col=error.pos + 1, title=str(error), + message=f"cannot load {path}" ) sys.stdout.write(error) + continue for test_case in contents: specifications = test_case.get("specification") if specifications is not None: for each in specifications: quote = each.pop("quote", "") - (kind, section), = each.items() + (key, section), = each.items() - number = re.search(r"\d+", kind) - spec = "" if number is None else number.group(0) + (kind, spec) = extract_kind_and_spec(key) + + url_template = version_urls[kind] + if url_template is None: + error = annotation( + level="error", + path=path, + line=line_number_of(path, test_case), + title=f"unsupported template '{kind}'", + message=f"cannot find a URL template for '{kind}'" + ) + sys.stdout.write(error) + continue - url = version_urls[kind].expand( + url = url_template.expand( spec=spec, section=section, ) diff --git a/bin/specification_urls.json b/bin/specification_urls.json index 9b985e97d..e1824999a 100644 --- a/bin/specification_urls.json +++ b/bin/specification_urls.json @@ -28,7 +28,7 @@ "external": { "ecma262": "https://262.ecma-international.org/{section}", "perl5": "https://perldoc.perl.org/perlre#{section}", - "rfc": "https://www.rfc-editor.org/rfc/{spec}.txt#{section}", + "rfc": "https://www.rfc-editor.org/rfc/rfc{spec}.html#section-{section}", "iso": "https://www.iso.org/obp/ui" } } diff --git a/tests/draft-next/optional/format/idn-hostname.json b/tests/draft-next/optional/format/idn-hostname.json index fa348fe62..1061f4243 100644 --- a/tests/draft-next/optional/format/idn-hostname.json +++ b/tests/draft-next/optional/format/idn-hostname.json @@ -331,11 +331,58 @@ "description": "empty string", "data": "", "valid": false - }, + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "format": "idn-hostname" + }, + "tests": [ { "description": "single dot", "data": ".", "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft2019-09/optional/format/idn-hostname.json b/tests/draft2019-09/optional/format/idn-hostname.json index 3e0b6497f..348c504c8 100644 --- a/tests/draft2019-09/optional/format/idn-hostname.json +++ b/tests/draft2019-09/optional/format/idn-hostname.json @@ -331,11 +331,58 @@ "description": "empty string", "data": "", "valid": false - }, + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "format": "idn-hostname" + }, + "tests": [ { "description": "single dot", "data": ".", "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft2019-09/propertyNames.json b/tests/draft2019-09/propertyNames.json index b7fecbf71..3b2bb23bb 100644 --- a/tests/draft2019-09/propertyNames.json +++ b/tests/draft2019-09/propertyNames.json @@ -111,5 +111,58 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "propertyNames": {"const": "foo"} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "propertyNames": {"enum": ["foo", "bar"]} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] diff --git a/tests/draft2020-12/optional/format/idn-hostname.json b/tests/draft2020-12/optional/format/idn-hostname.json index eb91b5a41..f42ae969b 100644 --- a/tests/draft2020-12/optional/format/idn-hostname.json +++ b/tests/draft2020-12/optional/format/idn-hostname.json @@ -331,11 +331,58 @@ "description": "empty string", "data": "", "valid": false - }, + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "format": "idn-hostname" + }, + "tests": [ { "description": "single dot", "data": ".", "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft2020-12/propertyNames.json b/tests/draft2020-12/propertyNames.json index 7ecfb7ec3..b4780088a 100644 --- a/tests/draft2020-12/propertyNames.json +++ b/tests/draft2020-12/propertyNames.json @@ -44,6 +44,36 @@ } ] }, + { + "description": "propertyNames validation with pattern", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "propertyNames": { "pattern": "^a+$" } + }, + "tests": [ + { + "description": "matching property names valid", + "data": { + "a": {}, + "aa": {}, + "aaa": {} + }, + "valid": true + }, + { + "description": "non-matching property name is invalid", + "data": { + "aaA": {} + }, + "valid": false + }, + { + "description": "object without properties is valid", + "data": {}, + "valid": true + } + ] + }, { "description": "propertyNames with boolean schema true", "schema": { @@ -81,5 +111,58 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "propertyNames": {"const": "foo"} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "propertyNames": {"enum": ["foo", "bar"]} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] diff --git a/tests/draft6/propertyNames.json b/tests/draft6/propertyNames.json index f0788e649..7c7b80006 100644 --- a/tests/draft6/propertyNames.json +++ b/tests/draft6/propertyNames.json @@ -103,5 +103,52 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": {"propertyNames": {"const": "foo"}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": {"propertyNames": {"enum": ["foo", "bar"]}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] diff --git a/tests/draft7/optional/format/idn-hostname.json b/tests/draft7/optional/format/idn-hostname.json index 0fe07e1ee..5c8cdc77b 100644 --- a/tests/draft7/optional/format/idn-hostname.json +++ b/tests/draft7/optional/format/idn-hostname.json @@ -323,11 +323,55 @@ "description": "empty string", "data": "", "valid": false - }, + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { "format": "idn-hostname" }, + "tests": [ { "description": "single dot", "data": ".", "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft7/propertyNames.json b/tests/draft7/propertyNames.json index f0788e649..7c7b80006 100644 --- a/tests/draft7/propertyNames.json +++ b/tests/draft7/propertyNames.json @@ -103,5 +103,52 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": {"propertyNames": {"const": "foo"}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": {"propertyNames": {"enum": ["foo", "bar"]}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] From 76bd5762d67f45af4501af7c16241f9bf186b700 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 26 Mar 2025 10:55:17 -0400 Subject: [PATCH 078/212] Again twiddle with license checking. --- noxfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/noxfile.py b/noxfile.py index 0485172c4..01a564582 100644 --- a/noxfile.py +++ b/noxfile.py @@ -29,6 +29,7 @@ "Apache Software License", "BSD License", "ISC License (ISCL)", + "MIT", "MIT License", "Mozilla Public License 2.0 (MPL 2.0)", "Python Software Foundation License", From 34dd14cc90d9612cbab978cef0aa45966feb67a9 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 26 Mar 2025 10:55:49 -0400 Subject: [PATCH 079/212] Update docs requirements. --- docs/requirements.txt | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 7ca0f1d13..8d5743117 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,17 +2,17 @@ # uv pip compile --output-file /Users/julian/Development/jsonschema/docs/requirements.txt docs/requirements.in alabaster==1.0.0 # via sphinx -astroid==3.3.8 +astroid==3.3.9 # via sphinx-autoapi -attrs==25.1.0 +attrs==25.3.0 # via # jsonschema # referencing -babel==2.16.0 +babel==2.17.0 # via sphinx -beautifulsoup4==4.12.3 +beautifulsoup4==4.13.3 # via furo -certifi==2024.12.14 +certifi==2025.1.31 # via requests charset-normalizer==3.4.1 # via requests @@ -24,7 +24,7 @@ idna==3.10 # via requests imagesize==1.4.1 # via sphinx -jinja2==3.1.5 +jinja2==3.1.6 # via # sphinx # sphinx-autoapi @@ -32,7 +32,7 @@ jsonschema @ file:. # via -r docs/requirements.in jsonschema-specifications==2024.10.1 # via jsonschema -lxml==5.3.0 +lxml==5.3.1 # via # -r docs/requirements.in # sphinx-json-schema-spec @@ -56,7 +56,9 @@ requests==2.32.3 # via # sphinx # sphinxcontrib-spelling -rpds-py==0.22.3 +roman-numerals-py==3.1.0 + # via sphinx +rpds-py==0.24.0 # via # jsonschema # referencing @@ -64,7 +66,7 @@ snowballstemmer==2.2.0 # via sphinx soupsieve==2.6 # via beautifulsoup4 -sphinx==8.1.3 +sphinx==8.2.3 # via # -r docs/requirements.in # furo @@ -75,9 +77,9 @@ sphinx==8.1.3 # sphinx-json-schema-spec # sphinxcontrib-spelling # sphinxext-opengraph -sphinx-autoapi==3.4.0 +sphinx-autoapi==3.6.0 # via -r docs/requirements.in -sphinx-autodoc-typehints==3.0.1 +sphinx-autodoc-typehints==3.1.0 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo @@ -101,5 +103,7 @@ sphinxcontrib-spelling==8.0.1 # via -r docs/requirements.in sphinxext-opengraph==0.9.1 # via -r docs/requirements.in +typing-extensions==4.13.0 + # via beautifulsoup4 urllib3==2.3.0 # via requests From f3864d46e2f4acf1a202931c7da194f43a0a17b1 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 26 Mar 2025 10:56:47 -0400 Subject: [PATCH 080/212] Update pre-commit hooks. --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f085d0719..6f0182fab 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,12 +16,12 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.9.6" + rev: "v0.11.2" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/PyCQA/isort - rev: 6.0.0 + rev: 6.0.1 hooks: - id: isort - repo: https://github.com/pre-commit/mirrors-prettier From b1ecbfce0af0689d60361842cd49336ba8cc9d40 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 18:12:55 +0000 Subject: [PATCH 081/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.2 → v0.11.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.2...v0.11.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6f0182fab..fb95a5786 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.2" + rev: "v0.11.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 979211c068c3dbdbbd9474a54975dfa28e5cee48 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:59:10 +0000 Subject: [PATCH 082/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.4 → v0.11.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.4...v0.11.5) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fb95a5786..ff1fd05c0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.4" + rev: "v0.11.5" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 391edbbff7573c90fa8a3080036626d31fe9b1f1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Apr 2025 17:54:48 +0000 Subject: [PATCH 083/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.5 → v0.11.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.5...v0.11.6) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ff1fd05c0..6e7a9acb3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.5" + rev: "v0.11.6" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 87b2e340e365d4bbf6e6a81bdbd75d4018974558 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 25 Apr 2025 08:06:30 -0400 Subject: [PATCH 084/212] Fix the license check noxenv again until we rewrite it. --- noxfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/noxfile.py b/noxfile.py index 01a564582..b64d5a8b7 100644 --- a/noxfile.py +++ b/noxfile.py @@ -126,6 +126,7 @@ def license_check(session): # because pip-licenses doesn't yet support PEP 639 :/ "attrs", "jsonschema", + "jsonschema-specifications", "referencing", "--allow-only", From 20f025d740bf69b7d119fa04674e15f377acc6d5 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Tue, 29 Apr 2025 12:01:10 +0200 Subject: [PATCH 085/212] Add helper function --- jsonschema/_utils.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 54d28c041..94830efbe 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -270,6 +270,10 @@ def find_evaluated_property_keys_by_schema(validator, instance, schema): return [] evaluated_keys = [] + def is_valid(errs_it): + """Whether there are no errors in the given iterator.""" + return next(errs_it, None) is None + ref = schema.get("$ref") if ref is not None: resolved = validator._resolver.lookup(ref) @@ -326,13 +330,12 @@ def find_evaluated_property_keys_by_schema(validator, instance, schema): ) for keyword in ["allOf", "oneOf", "anyOf"]: - if keyword in schema: - for subschema in schema[keyword]: - errs = next(validator.descend(instance, subschema), None) - if errs is None: - evaluated_keys += find_evaluated_property_keys_by_schema( - validator, instance, subschema, - ) + for subschema in schema.get(keyword, []): + if not is_valid(validator.descend(instance, subschema)): + continue + evaluated_keys += find_evaluated_property_keys_by_schema( + validator, instance, subschema, + ) if "if" in schema: if validator.evolve(schema=schema["if"]).is_valid(instance): From 75218a4c4632ecafa722724fd338dc3598625764 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Tue, 29 Apr 2025 12:01:10 +0200 Subject: [PATCH 086/212] Add test for unevaluatedProperties --- jsonschema/tests/test_validators.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 28cc40273..309229ee6 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -742,6 +742,14 @@ def test_unevaluated_properties_on_invalid_type(self): message = self.message_for(instance="foo", schema=schema) self.assertEqual(message, "'foo' is not of type 'object'") + def test_unevaluated_properties_with_additional_properties(self): + schema = { + "additionalProperties": {"type": "string"}, + "unevaluatedProperties": False, + } + validator = validators._LATEST_VERSION(schema) + validator.validate(instance={"foo": "foo"}) + def test_single_item(self): schema = {"prefixItems": [{}], "items": False} message = self.message_for( From fb57921bcc37ce969550452e1b30351c476e24e5 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Tue, 29 Apr 2025 12:01:10 +0200 Subject: [PATCH 087/212] Fix calculation of evaluated properties --- jsonschema/_utils.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 94830efbe..61defd303 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -302,18 +302,18 @@ def is_valid(errs_it): ), ) - for keyword in [ - "properties", "additionalProperties", "unevaluatedProperties", - ]: - if keyword in schema: - schema_value = schema[keyword] - if validator.is_type(schema_value, "boolean") and schema_value: - evaluated_keys += instance.keys() - - elif validator.is_type(schema_value, "object"): - for property in schema_value: - if property in instance: - evaluated_keys.append(property) + properties = schema.get("properties") + if validator.is_type(properties, "object"): + evaluated_keys += properties.keys() & instance.keys() + + for keyword in ["additionalProperties", "unevaluatedProperties"]: + if (subschema := schema.get(keyword)) is None: + continue + evaluated_keys += ( + key + for key, value in instance.items() + if is_valid(validator.descend(value, subschema)) + ) if "patternProperties" in schema: for property in instance: From ef71f1be9b59cc7d6e799acdc0598d45c4f1c144 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Tue, 29 Apr 2025 12:01:54 +0200 Subject: [PATCH 088/212] Squashed 'json/' changes from 83e866b4..ab3924a6 REVERT: 83e866b4 Merge pull request #763 from michaelmior/propertynames-const REVERT: c5a9703f Merge pull request #760 from OptimumCode/rfc3490-label-separator REVERT: b4c09b65 Add tests for propertyNames with const/enum REVERT: 4fa572d8 Move tests for rfc3490#3.1 into a separate test case REVERT: ce9f68ca Add link to rfc and quote REVERT: ad94cacc Add test cases for other valid label separators in IDN hostnames REVERT: 39002ae7 Merge pull request #762 from OptimumCode/rfc-html-link REVERT: c8780535 Correct section anchor for rfc URL template REVERT: 5f2ca7d6 Modify rfc url template to use html version REVERT: 9c5d99b6 Merge pull request #761 from OptimumCode/annotation-script-rfc-support REVERT: 9563ce7b Correct rfc URL template - incorrect path pattern was used REVERT: 961bfad0 Correct spec kind extraction from defined key. Continue on unkown URL kind REVERT: e524505b Merge pull request #759 from sirosen/hostname-format-reject-single-dot REVERT: 4a3efd18 Add negative tests for "." for hostname formats REVERT: 4ba013d5 Merge pull request #747 from santhosh-tekuri/duration REVERT: aa500e80 Merge pull request #749 from json-schema-org/gregsdennis/json-everything-update REVERT: eb8ce976 Merge pull request #757 from ajevans99/main REVERT: dcdae5c0 Merge pull request #758 from sirosen/hostname-format-check-empty-string REVERT: db21d21b Merge branch 'main' into hostname-format-check-empty-string REVERT: 3fd78f04 Merge pull request #1 from ajevans99/swift-json-schema REVERT: 3cada3a9 Update README.md REVERT: 82a07749 Merge pull request #753 from json-schema-org/ether/fix-draft-locations REVERT: a66d23d4 move draft-specific files to the dedicated dir for its draft REVERT: 8ef15501 Merge pull request #751 from big-andy-coates/format_tests_under_format REVERT: fe1b1392 All format test cases should be under the `format` directory. REVERT: b1ee90f6 json-everything moved to an org REVERT: c00a3f94 test: duration format must start with P REVERT: 9fc880bf Merge pull request #740 from notEthan/format-pattern-control-char REVERT: cbd48ea5 Simplify test of \a regex character to test directly against `pattern` schema REVERT: d6f1010a Merge pull request #746 from json-schema-org/annotations REVERT: 4aec22c1 Revert the changes to additionalProperties.json. REVERT: 2dc10671 Move the workflow step title. REVERT: d9ce71ac May as well also show quotes in the annotation. REVERT: 1b719a84 Pick the line after the description when attaching spec annotations. REVERT: 08105151 Markdown is apparently not (yet?) supported in annotations. REVERT: 81645773 Tidy up the specification annotator a bit. REVERT: 38628b79 Make the spec URLs structure a bit easier for internal use. REVERT: 4ebbeaf4 Merge branch 'Era-cell/main' REVERT: e4bd7554 dumbness2 corrected REVERT: d8ade402 inside run REVERT: 57c7c869 changed install location REVERT: 11f8e511 Added installing command in workflow REVERT: f2766616 template library, url loads changes REVERT: c2badb12 Merge pull request #734 from OptimumCode/idn-hostname-arabic-indic-mixed REVERT: dd9599a5 Merge branch 'main' of github.com:json-schema-org/JSON-Schema-Test-Suite REVERT: 5b393436 add pr dependencies action REVERT: 3a509007 Clear existin annotations on same PR REVERT: 23674123 Cases for rfc and iso written separately REVERT: 0b780b2c Corected yaml format REVERT: 2b1ffb74 Best practices followed with optimized code REVERT: e88a2da6 Works for all OS REVERT: 7b40efe4 Base path for neighbouring file? REVERT: 564e6957 Walking through all leaf files REVERT: 7b84fb44 Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-Suite REVERT: 891d0265 First workflow2 REVERT: 1c175195 regex correction REVERT: 96f7683a Final correction2 - file names beautufied REVERT: 5f050a07 Final correction1 REVERT: 77527b63 Stupidity corrected REVERT: eb8fd760 Branch name specified REVERT: 540a269b Log2 REVERT: f29d090a Wrong location sepcification REVERT: 582e12be logging logs check REVERT: df3bdecc path corrected REVERT: c6b937ca Reading all jsons and spec urls added REVERT: cbdd1755 change day2 REVERT: 54f3784a Merge pull request #731 from MeastroZI/main REVERT: 79dc92f1 TOKEN REVERT: ce52852d Python file location changed REVERT: 3558c2c6 Fake add to tests REVERT: eecc7b7a Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-Suite REVERT: 810d148a First workflow2 REVERT: 4eac02c7 First workflow REVERT: ff29264c Merge pull request #741 from harrel56/chore/tabs-to-spaces REVERT: 9f39cf73 use spaces instead of tabs REVERT: 2f3b5f7a Corrected replaced unevaluated with additoinalProperties REVERT: 40bcb8b3 Corrected replaced unevaluated with additoinalProperties REVERT: fa9224d7 Merge pull request #732 from MeastroZI/main2 REVERT: 83bedd5c Changing descriptions REVERT: 49f73429 fixing tests REVERT: e6d6a081 adding more test cases REVERT: 7e6c9be6 changing descriptions REVERT: 959aca92 shifting test REVERT: 605d7d78 Update propertyDependencies.json : test must be tests REVERT: deb82824 test for dependentSchema and propertyDependencies with unevaluatedProperties and additionalProperties REVERT: ea485124 Merge branch 'json-schema-org:main' into main REVERT: 64a3e7b3 Merge pull request #721 from json-schema-org/gregsdennis/dynamicref-skips-resources REVERT: b9f14e64 Fix $schema in new new test REVERT: 3d5048e8 Merge pull request #733 from Era-cell/main REVERT: 4ae14268 Add valid first character to avoid Bidi rule violation REVERT: 2480edba Update additionalProperties.json formatting it REVERT: 6aa79c0b Update additionalProperties.json formatting it REVERT: 3e0139a5 Update tests/draft-next/additionalProperties.json REVERT: 616240b0 Update tests/draft-next/additionalProperties.json REVERT: c5f3e4ea Update tests/draft2020-12/propertyNames.json REVERT: 964efb8e propertyNames doesn't affect additionalProperties, tests exist already for unevaluatedProps REVERT: f08b884c Cases go under additional and unevaluated Properties REVERT: 99864ff6 added tests for propertyNames with additionalProperties/unevaluatedProperties, also with specification property REVERT: 3b5782b6 Update ref.json : changing $Ids REVERT: 546b3561 test for $ref with $recursiveAnchor REVERT: 57617f25 Merge pull request #726 from Era-cell/main REVERT: 51fc69cd meta data and property names constraints added, additional Items: string REVERT: 9b169bed specification takes array of objects having section and quote REVERT: 1362a8cc Pattern for para corrected REVERT: 340116ec Schema of specification in much structured REVERT: 003ac021 Test-schema including sub-schema for scpecification REVERT: 50a20280 adding specification enhancement for additionalProperties REVERT: 604f5f99 Drop tests of `$id` and `$anchor` that just test values against meta-schema `pattern` for those properties REVERT: 9cd64ec9 come on man, save all the files REVERT: f494440e use unique $id in optional tests, too REVERT: 468453b0 use unique $id REVERT: 9ec6d17e fix copy/paste error REVERT: b284f423 add tests for $dynamicRef skipping over resources REVERT: bf0360f4 add $recursiveAnchor to 2019-09 meta-schemas REVERT: 0519d1f0 add $dynamicAnchor to meta-schemas REVERT: b41167c7 Merge pull request #714 from json-schema-org/more-not REVERT: 4221a55a Add tests for not: {} schemas for all values. REVERT: c499d1d2 Merge pull request #713 from spacether/patch-1 REVERT: 24a471bd Update README.md REVERT: 544f7c3d Merge pull request #712 from otto-ifak/main REVERT: 9dad3ebe Add tests for enum with array of bool REVERT: 589a0858 Merge pull request #706 from marksparkza/unevaluated-before-ref REVERT: 64d5cab9 Merge pull request #710 from spacether/patch-1 REVERT: 418cdbd6 Removes idea folder REVERT: e0a9e066 Updates all other tests to mention grapheme/graphemes REVERT: 217bf81b Merge pull request #701 from json-schema-org/ether/dynamicRef-boolean REVERT: 7a3d06d7 I remove a test that doesn't make sense. REVERT: e8bf453d Move tests with ids in non-schemas to optional REVERT: 69136952 Update minLength.json REVERT: d545be21 Fix duplidate identifiers in recently added tests REVERT: 4e9640c8 test when $dynamicRef references a boolean schema REVERT: 3dab98ca Merge pull request #705 from json-schema-org/gregsdennis/remove-contains-objects-tests REVERT: 1d3aa495 remove more maxContains REVERT: 4a2c61e8 Test unevaluatedItems|Properties before $ref REVERT: ec553d76 contains no longer applies to objects REVERT: 0433a2bf Merge pull request #704 from big-andy-coates/clarify-format-requirements REVERT: c685195f Merge pull request #703 from big-andy-coates/link-to-creek-validator-comprison-site REVERT: a46174b0 Add more detail around test runner requirements for `format` tests REVERT: bb1de8a9 The site linked to is a data-driven functional and performance benchmark of JVM based validator implementations. REVERT: d38ddd54 Merge pull request #696 from jdesrosiers/unevaluated-dynamicref REVERT: 5d0c05fa Fix copy/paste error REVERT: 95fe6ca2 Merge pull request #694 from json-schema-org/heterogeneous-additionalItems REVERT: 9c88a0be Merge pull request #697 from json-schema-org/gregsdennis/add-ref-into-known-nonapplicator REVERT: 49222046 Add unevaluted with dynamic ref tests to draft-next REVERT: 8ba1c90d Update unevaluted with dynamic ref to be more likely to catch errors REVERT: fea2cf19 add tests for 2019 and 2020 REVERT: 6695ca38 add optional tests for `$ref`ing into known non-applicator keywords REVERT: 2834c630 Add tests for unevaluated with dynamic reference REVERT: cda4281c Merge pull request #695 from json-schema-org/ether/clean-up-subSchemas REVERT: 7b9f45c2 move subSchemas-defs.json to subSchemas.json REVERT: e41ec0ec remove unused definition files REVERT: 349c5a82 Merge pull request #692 from json-schema-org/ether/fix-subSchemas-refs REVERT: 451baca4 Merge pull request #670 from marksparkza/invalid-output-test REVERT: b8da838a Add tests for heterogeneous arrays with additionalItems REVERT: 6d7a44b7 fix subschema locations and their $refs REVERT: a9a1e2e3 Merge pull request #690 from skryukov/add-ipv4-mask-test REVERT: ba52c48a Merge pull request #689 from skryukov/add-schema-keyword-to-required-tests REVERT: 69b53add Add a test case for ipv4 with netmask REVERT: d0c602a7 Add $schema keyword to required tests REVERT: 20f1f52c Merge pull request #688 from spacether/feat_updates_python_exp_impl REVERT: b087b3ca Updates implmentation REVERT: 4ecd01f3 Merge pull request #687 from swaeberle/check-single-label-idn-hostnames REVERT: 732e7275 test single label IDN hostnames REVERT: 202d5625 test: hostname format check fails on empty string REVERT: ea0b63c9 Remove invalid output tests git-subtree-dir: json git-subtree-split: ab3924a663d2f9e6de844f464d185a70d881b9ed --- .github/workflows/pr-dependencies.yml | 12 - .../show_specification_annotations.yml | 21 -- README.md | 16 +- bin/annotate-specification-links | 140 --------- bin/specification_urls.json | 34 -- output-tests/draft2019-09/content/type.json | 26 ++ output-tests/draft2020-12/content/type.json | 26 ++ .../draft-next/format-assertion-false.json | 1 - remotes/draft-next/format-assertion-true.json | 1 - .../draft-next/metaschema-no-validation.json | 1 - .../metaschema-optional-vocabulary.json | 1 - remotes/draft-next/subSchemas-defs.json | 11 + remotes/draft-next/subSchemas.json | 12 +- .../metaschema-no-validation.json | 1 - .../metaschema-optional-vocabulary.json | 1 - remotes/draft2019-09/subSchemas-defs.json | 11 + remotes/draft2019-09/subSchemas.json | 12 +- .../draft2020-12/format-assertion-false.json | 1 - .../draft2020-12/format-assertion-true.json | 1 - .../metaschema-no-validation.json | 1 - .../metaschema-optional-vocabulary.json | 1 - remotes/draft2020-12/subSchemas-defs.json | 11 + remotes/draft2020-12/subSchemas.json | 12 +- remotes/draft4/subSchemas.json | 10 - remotes/draft6/name.json | 15 - remotes/draft6/ref-and-definitions.json | 11 - remotes/draft6/subSchemas.json | 10 - .../draft7/locationIndependentIdentifier.json | 11 - remotes/draft7/name.json | 15 - remotes/draft7/subSchemas.json | 10 - ... locationIndependentIdentifierDraft4.json} | 0 ...locationIndependentIdentifierPre2019.json} | 0 remotes/{draft4 => }/name.json | 0 remotes/{draft7 => }/ref-and-definitions.json | 2 +- .../subSchemas.json => subSchemas-defs.json} | 4 +- remotes/subSchemas.json | 8 + test-schema.json | 63 ---- tests/draft-next/additionalProperties.json | 92 ------ tests/draft-next/anchor.json | 114 +++++++ tests/draft-next/contains.json | 104 ++++++- tests/draft-next/dependentSchemas.json | 1 - tests/draft-next/dynamicRef.json | 85 ----- tests/draft-next/enum.json | 96 ------ tests/draft-next/id.json | 294 ++++++++++++++++++ tests/draft-next/items.json | 20 -- tests/draft-next/maxContains.json | 50 +++ tests/draft-next/maxLength.json | 2 +- tests/draft-next/minLength.json | 2 +- tests/draft-next/oneOf.json | 2 +- tests/draft-next/optional/anchor.json | 60 ---- tests/draft-next/optional/dynamicRef.json | 56 ---- .../draft-next/optional/ecmascript-regex.json | 14 + .../draft-next/optional/format/duration.json | 5 - .../optional/format/ecmascript-regex.json | 16 - .../draft-next/optional/format/hostname.json | 10 - .../optional/format/idn-hostname.json | 84 +---- tests/draft-next/optional/format/ipv4.json | 5 - tests/draft-next/optional/id.json | 53 ---- .../optional/refOfUnknownKeyword.json | 23 -- tests/draft-next/ref.json | 8 - tests/draft-next/refRemote.json | 20 +- tests/draft-next/unevaluatedItems.json | 73 ----- tests/draft-next/unevaluatedProperties.json | 206 +++--------- .../{optional => }/unknownKeyword.json | 0 tests/draft2019-09/additionalItems.json | 20 -- tests/draft2019-09/additionalProperties.json | 57 ---- tests/draft2019-09/anchor.json | 115 +++++++ tests/draft2019-09/dependentSchemas.json | 1 - tests/draft2019-09/enum.json | 96 ------ tests/draft2019-09/id.json | 294 ++++++++++++++++++ tests/draft2019-09/maxLength.json | 2 +- tests/draft2019-09/minLength.json | 2 +- tests/draft2019-09/not.json | 154 +-------- tests/draft2019-09/oneOf.json | 2 +- tests/draft2019-09/optional/anchor.json | 60 ---- .../optional/format/duration.json | 5 - .../optional/format/hostname.json | 10 - .../optional/format/idn-hostname.json | 84 +---- tests/draft2019-09/optional/format/ipv4.json | 5 - tests/draft2019-09/optional/id.json | 53 ---- .../optional/refOfUnknownKeyword.json | 23 -- tests/draft2019-09/propertyNames.json | 53 ---- tests/draft2019-09/ref.json | 63 +--- tests/draft2019-09/refRemote.json | 20 +- tests/draft2019-09/unevaluatedItems.json | 76 ----- tests/draft2019-09/unevaluatedProperties.json | 129 -------- .../{optional => }/unknownKeyword.json | 0 tests/draft2020-12/additionalProperties.json | 67 +--- tests/draft2020-12/anchor.json | 115 +++++++ tests/draft2020-12/dependentSchemas.json | 1 - tests/draft2020-12/dynamicRef.json | 85 ----- tests/draft2020-12/enum.json | 96 ------ tests/draft2020-12/id.json | 294 ++++++++++++++++++ tests/draft2020-12/items.json | 20 -- tests/draft2020-12/maxLength.json | 2 +- tests/draft2020-12/minLength.json | 2 +- tests/draft2020-12/not.json | 154 +-------- tests/draft2020-12/oneOf.json | 2 +- tests/draft2020-12/optional/anchor.json | 60 ---- tests/draft2020-12/optional/dynamicRef.json | 56 ---- .../optional/ecmascript-regex.json | 14 + .../optional/format/duration.json | 5 - .../optional/format/ecmascript-regex.json | 16 - .../optional/format/hostname.json | 10 - .../optional/format/idn-hostname.json | 84 +---- tests/draft2020-12/optional/format/ipv4.json | 5 - tests/draft2020-12/optional/id.json | 53 ---- .../optional/refOfUnknownKeyword.json | 23 -- tests/draft2020-12/propertyNames.json | 83 ----- tests/draft2020-12/ref.json | 23 +- tests/draft2020-12/refRemote.json | 20 +- tests/draft2020-12/unevaluatedItems.json | 81 +---- tests/draft2020-12/unevaluatedProperties.json | 126 -------- .../{optional => }/unknownKeyword.json | 0 tests/draft3/additionalItems.json | 19 -- tests/draft3/maxLength.json | 2 +- tests/draft3/minLength.json | 2 +- .../{format => }/ecmascript-regex.json | 0 tests/draft3/optional/format/host-name.json | 5 - tests/draft3/refRemote.json | 4 +- tests/draft4/additionalItems.json | 19 -- tests/draft4/enum.json | 84 ----- tests/draft4/{optional => }/id.json | 0 tests/draft4/maxLength.json | 2 +- tests/draft4/minLength.json | 2 +- tests/draft4/not.json | 63 +--- tests/draft4/oneOf.json | 2 +- tests/draft4/optional/format/hostname.json | 10 - tests/draft4/optional/format/ipv4.json | 5 - tests/draft4/refRemote.json | 8 +- tests/draft6/additionalItems.json | 19 -- tests/draft6/enum.json | 84 ----- tests/draft6/{optional => }/id.json | 0 tests/draft6/maxLength.json | 2 +- tests/draft6/minLength.json | 2 +- tests/draft6/not.json | 152 +-------- tests/draft6/oneOf.json | 2 +- tests/draft6/optional/format/hostname.json | 10 - tests/draft6/optional/format/ipv4.json | 5 - tests/draft6/propertyNames.json | 47 --- tests/draft6/refRemote.json | 10 +- .../draft6/{optional => }/unknownKeyword.json | 0 tests/draft7/additionalItems.json | 19 -- tests/draft7/enum.json | 84 ----- tests/draft7/{optional => }/id.json | 0 tests/draft7/maxLength.json | 2 +- tests/draft7/minLength.json | 2 +- tests/draft7/not.json | 152 +-------- tests/draft7/oneOf.json | 2 +- tests/draft7/optional/format/hostname.json | 10 - .../draft7/optional/format/idn-hostname.json | 76 +---- tests/draft7/optional/format/ipv4.json | 5 - tests/draft7/propertyNames.json | 47 --- tests/draft7/refRemote.json | 10 +- .../draft7/{optional => }/unknownKeyword.json | 0 155 files changed, 1663 insertions(+), 4135 deletions(-) delete mode 100644 .github/workflows/pr-dependencies.yml delete mode 100644 .github/workflows/show_specification_annotations.yml delete mode 100755 bin/annotate-specification-links delete mode 100644 bin/specification_urls.json create mode 100644 remotes/draft-next/subSchemas-defs.json create mode 100644 remotes/draft2019-09/subSchemas-defs.json create mode 100644 remotes/draft2020-12/subSchemas-defs.json delete mode 100644 remotes/draft4/subSchemas.json delete mode 100644 remotes/draft6/name.json delete mode 100644 remotes/draft6/ref-and-definitions.json delete mode 100644 remotes/draft6/subSchemas.json delete mode 100644 remotes/draft7/locationIndependentIdentifier.json delete mode 100644 remotes/draft7/name.json delete mode 100644 remotes/draft7/subSchemas.json rename remotes/{draft4/locationIndependentIdentifier.json => locationIndependentIdentifierDraft4.json} (100%) rename remotes/{draft6/locationIndependentIdentifier.json => locationIndependentIdentifierPre2019.json} (100%) rename remotes/{draft4 => }/name.json (100%) rename remotes/{draft7 => }/ref-and-definitions.json (74%) rename remotes/{draft3/subSchemas.json => subSchemas-defs.json} (62%) create mode 100644 remotes/subSchemas.json create mode 100644 tests/draft-next/id.json delete mode 100644 tests/draft-next/optional/anchor.json delete mode 100644 tests/draft-next/optional/dynamicRef.json delete mode 100644 tests/draft-next/optional/format/ecmascript-regex.json delete mode 100644 tests/draft-next/optional/id.json rename tests/draft-next/{optional => }/unknownKeyword.json (100%) create mode 100644 tests/draft2019-09/id.json delete mode 100644 tests/draft2019-09/optional/anchor.json delete mode 100644 tests/draft2019-09/optional/id.json rename tests/draft2019-09/{optional => }/unknownKeyword.json (100%) create mode 100644 tests/draft2020-12/id.json delete mode 100644 tests/draft2020-12/optional/anchor.json delete mode 100644 tests/draft2020-12/optional/dynamicRef.json delete mode 100644 tests/draft2020-12/optional/format/ecmascript-regex.json delete mode 100644 tests/draft2020-12/optional/id.json rename tests/draft2020-12/{optional => }/unknownKeyword.json (100%) rename tests/draft3/optional/{format => }/ecmascript-regex.json (100%) rename tests/draft4/{optional => }/id.json (100%) rename tests/draft6/{optional => }/id.json (100%) rename tests/draft6/{optional => }/unknownKeyword.json (100%) rename tests/draft7/{optional => }/id.json (100%) rename tests/draft7/{optional => }/unknownKeyword.json (100%) diff --git a/.github/workflows/pr-dependencies.yml b/.github/workflows/pr-dependencies.yml deleted file mode 100644 index 34a231dcb..000000000 --- a/.github/workflows/pr-dependencies.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Check PR Dependencies - -on: pull_request - -jobs: - check_dependencies: - runs-on: ubuntu-latest - name: Check Dependencies - steps: - - uses: gregsdennis/dependencies-action@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/show_specification_annotations.yml b/.github/workflows/show_specification_annotations.yml deleted file mode 100644 index f7d7b398b..000000000 --- a/.github/workflows/show_specification_annotations.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Show Specification Annotations - -on: - pull_request: - paths: - - 'tests/**' - -jobs: - annotate: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Generate Annotations - run: pip install uritemplate && bin/annotate-specification-links diff --git a/README.md b/README.md index 0bcad8e52..cdd5dc8a4 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ To test a specific version: * For 2019-09 and later published drafts, implementations that are able to detect the draft of each schema via `$schema` SHOULD be configured to do so * For draft-07 and earlier, draft-next, and implementations unable to detect via `$schema`, implementations MUST be configured to expect the draft matching the test directory name -* Load any remote references [described below](#additional-assumptions) and configure your implementation to retrieve them via their URIs +* Load any remote references [described below](additional-assumptions) and configure your implementation to retrieve them via their URIs * Walk the filesystem tree for that version's subdirectory and for each `.json` file found: * if the file is located in the root of the version directory: @@ -159,7 +159,7 @@ If your implementation supports multiple versions, run the above procedure for e ``` 2. Test cases found within [special subdirectories](#subdirectories-within-each-draft) may require additional configuration to run. - In particular, when running tests within the `optional/format` subdirectory, test runners should configure implementations to enable format validation, where the implementation supports it. + In particular, tests within the `optional/format` subdirectory may require implementations to change the way they treat the `"format"`keyword (particularly on older drafts which did not have a notion of vocabularies). ### Invariants & Guarantees @@ -254,14 +254,12 @@ This suite is being used by: ### Java -* [json-schema-validation-comparison](https://www.creekservice.org/json-schema-validation-comparison/functional) (Comparison site for JVM-based validator implementations) * [json-schema-validator](https://github.com/daveclayton/json-schema-validator) * [everit-org/json-schema](https://github.com/everit-org/json-schema) * [networknt/json-schema-validator](https://github.com/networknt/json-schema-validator) * [Justify](https://github.com/leadpony/justify) * [Snow](https://github.com/ssilverman/snowy-json) * [jsonschemafriend](https://github.com/jimblackler/jsonschemafriend) -* [OpenAPI JSON Schema Generator](https://github.com/openapi-json-schema-tools/openapi-json-schema-generator) ### JavaScript @@ -281,10 +279,6 @@ This suite is being used by: * [ajv](https://github.com/epoberezkin/ajv) * [djv](https://github.com/korzio/djv) -### Kotlin - -* [json-schema-validation-comparison](https://www.creekservice.org/json-schema-validation-comparison/functional) (Comparison site for JVM-based validator implementations) - ### Node.js For node.js developers, the suite is also available as an [npm](https://www.npmjs.com/package/@json-schema-org/tests) package. @@ -293,7 +287,7 @@ Node-specific support is maintained in a [separate repository](https://github.co ### .NET -* [JsonSchema.Net](https://github.com/json-everything/json-everything) +* [JsonSchema.Net](https://github.com/gregsdennis/json-everything) * [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema) ### Perl @@ -319,7 +313,7 @@ Node-specific support is maintained in a [separate repository](https://github.co * [fastjsonschema](https://github.com/seznam/python-fastjsonschema) * [hypothesis-jsonschema](https://github.com/Zac-HD/hypothesis-jsonschema) * [jschon](https://github.com/marksparkza/jschon) -* [OpenAPI JSON Schema Generator](https://github.com/openapi-json-schema-tools/openapi-json-schema-generator) +* [python-experimental, OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/python-experimental.md) ### Ruby @@ -333,13 +327,11 @@ Node-specific support is maintained in a [separate repository](https://github.co ### Scala -* [json-schema-validation-comparison](https://www.creekservice.org/json-schema-validation-comparison/functional) (Comparison site for JVM-based validator implementations) * [typed-json](https://github.com/frawa/typed-json) ### Swift * [JSONSchema](https://github.com/kylef/JSONSchema.swift) -* [swift-json-schema](https://github.com/ajevans99/swift-json-schema) If you use it as well, please fork and send a pull request adding yourself to the list :). diff --git a/bin/annotate-specification-links b/bin/annotate-specification-links deleted file mode 100755 index 963768b43..000000000 --- a/bin/annotate-specification-links +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 -""" -Annotate pull requests to the GitHub repository with links to specifications. -""" - -from __future__ import annotations - -from pathlib import Path -from typing import Any -import json -import re -import sys - -from uritemplate import URITemplate - - -BIN_DIR = Path(__file__).parent -TESTS = BIN_DIR.parent / "tests" -URLS = json.loads(BIN_DIR.joinpath("specification_urls.json").read_text()) - - -def urls(version: str) -> dict[str, URITemplate]: - """ - Retrieve the version-specific URLs for specifications. - """ - for_version = {**URLS["json-schema"][version], **URLS["external"]} - return {k: URITemplate(v) for k, v in for_version.items()} - - -def annotation( - path: Path, - message: str, - line: int = 1, - level: str = "notice", - **kwargs: Any, -) -> str: - """ - Format a GitHub annotation. - - See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions - for full syntax. - """ - - if kwargs: - additional = "," + ",".join(f"{k}={v}" for k, v in kwargs.items()) - else: - additional = "" - - relative = path.relative_to(TESTS.parent) - return f"::{level} file={relative},line={line}{additional}::{message}\n" - - -def line_number_of(path: Path, case: dict[str, Any]) -> int: - """ - Crudely find the line number of a test case. - """ - with path.open() as file: - description = case["description"] - return next( - (i + 1 for i, line in enumerate(file, 1) if description in line), - 1, - ) - -def extract_kind_and_spec(key: str) -> (str, str): - """ - Extracts specification number and kind from the defined key - """ - can_have_spec = ["rfc", "iso"] - if not any(key.startswith(el) for el in can_have_spec): - return key, "" - number = re.search(r"\d+", key) - spec = "" if number is None else number.group(0) - kind = key.removesuffix(spec) - return kind, spec - - -def main(): - # Clear annotations which may have been emitted by a previous run. - sys.stdout.write("::remove-matcher owner=me::\n") - - for version in TESTS.iterdir(): - if version.name in {"draft-next", "latest"}: - continue - - version_urls = urls(version.name) - - for path in version.rglob("*.json"): - try: - contents = json.loads(path.read_text()) - except json.JSONDecodeError as error: - error = annotation( - level="error", - path=path, - line=error.lineno, - col=error.pos + 1, - title=str(error), - message=f"cannot load {path}" - ) - sys.stdout.write(error) - continue - - for test_case in contents: - specifications = test_case.get("specification") - if specifications is not None: - for each in specifications: - quote = each.pop("quote", "") - (key, section), = each.items() - - (kind, spec) = extract_kind_and_spec(key) - - url_template = version_urls[kind] - if url_template is None: - error = annotation( - level="error", - path=path, - line=line_number_of(path, test_case), - title=f"unsupported template '{kind}'", - message=f"cannot find a URL template for '{kind}'" - ) - sys.stdout.write(error) - continue - - url = url_template.expand( - spec=spec, - section=section, - ) - - message = f"{url}\n\n{quote}" if quote else url - sys.stdout.write( - annotation( - path=path, - line=line_number_of(path, test_case), - title="Specification Link", - message=message, - ), - ) - - -if __name__ == "__main__": - main() diff --git a/bin/specification_urls.json b/bin/specification_urls.json deleted file mode 100644 index e1824999a..000000000 --- a/bin/specification_urls.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "json-schema": { - "draft2020-12": { - "core": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-{section}", - "validation": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#section-{section}" - }, - "draft2019-09": { - "core": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.{section}", - "validation": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-validation-02#rfc.section.{section}" - }, - "draft7": { - "core": "https://json-schema.org/draft-07/draft-handrews-json-schema-01#rfc.section.{section}", - "validation": "https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01#rfc.section.{section}" - }, - "draft6": { - "core": "https://json-schema.org/draft-06/draft-wright-json-schema-01#rfc.section.{section}", - "validation": "https://json-schema.org/draft-06/draft-wright-json-schema-validation-01#rfc.section.{section}" - }, - "draft4": { - "core": "https://json-schema.org/draft-04/draft-zyp-json-schema-04#rfc.section.{section}", - "validation": "https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.{section}" - }, - "draft3": { - "core": "https://json-schema.org/draft-03/draft-zyp-json-schema-03.pdf" - } - }, - - "external": { - "ecma262": "https://262.ecma-international.org/{section}", - "perl5": "https://perldoc.perl.org/perlre#{section}", - "rfc": "https://www.rfc-editor.org/rfc/rfc{spec}.html#section-{section}", - "iso": "https://www.iso.org/obp/ui" - } -} diff --git a/output-tests/draft2019-09/content/type.json b/output-tests/draft2019-09/content/type.json index 21118fd5f..cff77a740 100644 --- a/output-tests/draft2019-09/content/type.json +++ b/output-tests/draft2019-09/content/type.json @@ -31,6 +31,32 @@ "required": ["errors"] } } + }, + { + "description": "correct type yields an output unit", + "data": "a string", + "output": { + "basic": { + "$id": "https://json-schema.org/tests/content/draft2019-09/type/0/tests/1/basic", + "$ref": "/draft/2019-09/output/schema", + "properties": { + "annotations": { + "contains": { + "properties": { + "valid": {"const": true}, + "keywordLocation": {"const": "/type"}, + "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2019-09/type/0#/type"}, + "instanceLocation": {"const": ""}, + "annotation": false, + "error": false + }, + "required": ["keywordLocation", "instanceLocation"] + } + } + }, + "required": ["annotations"] + } + } } ] } diff --git a/output-tests/draft2020-12/content/type.json b/output-tests/draft2020-12/content/type.json index 2949a6052..710475b2b 100644 --- a/output-tests/draft2020-12/content/type.json +++ b/output-tests/draft2020-12/content/type.json @@ -31,6 +31,32 @@ "required": ["errors"] } } + }, + { + "description": "correct type yields an output unit", + "data": "a string", + "output": { + "basic": { + "$id": "https://json-schema.org/tests/content/draft2020-12/type/0/tests/1/basic", + "$ref": "/draft/2020-12/output/schema", + "properties": { + "annotations": { + "contains": { + "properties": { + "valid": {"const": true}, + "keywordLocation": {"const": "/type"}, + "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2020-12/type/0#/type"}, + "instanceLocation": {"const": ""}, + "annotation": false, + "error": false + }, + "required": ["keywordLocation", "instanceLocation"] + } + } + }, + "required": ["annotations"] + } + } } ] } diff --git a/remotes/draft-next/format-assertion-false.json b/remotes/draft-next/format-assertion-false.json index 9cbd2a1de..91c866996 100644 --- a/remotes/draft-next/format-assertion-false.json +++ b/remotes/draft-next/format-assertion-false.json @@ -5,7 +5,6 @@ "https://json-schema.org/draft/next/vocab/core": true, "https://json-schema.org/draft/next/vocab/format-assertion": false }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/core" }, { "$ref": "https://json-schema.org/draft/next/meta/format-assertion" } diff --git a/remotes/draft-next/format-assertion-true.json b/remotes/draft-next/format-assertion-true.json index b3ff69f3a..a33d1435f 100644 --- a/remotes/draft-next/format-assertion-true.json +++ b/remotes/draft-next/format-assertion-true.json @@ -5,7 +5,6 @@ "https://json-schema.org/draft/next/vocab/core": true, "https://json-schema.org/draft/next/vocab/format-assertion": true }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/core" }, { "$ref": "https://json-schema.org/draft/next/meta/format-assertion" } diff --git a/remotes/draft-next/metaschema-no-validation.json b/remotes/draft-next/metaschema-no-validation.json index 90e32a672..c19c9e8a7 100644 --- a/remotes/draft-next/metaschema-no-validation.json +++ b/remotes/draft-next/metaschema-no-validation.json @@ -5,7 +5,6 @@ "https://json-schema.org/draft/next/vocab/applicator": true, "https://json-schema.org/draft/next/vocab/core": true }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/applicator" }, { "$ref": "https://json-schema.org/draft/next/meta/core" } diff --git a/remotes/draft-next/metaschema-optional-vocabulary.json b/remotes/draft-next/metaschema-optional-vocabulary.json index 1af0cad4c..e78e531d4 100644 --- a/remotes/draft-next/metaschema-optional-vocabulary.json +++ b/remotes/draft-next/metaschema-optional-vocabulary.json @@ -6,7 +6,6 @@ "https://json-schema.org/draft/next/vocab/core": true, "http://localhost:1234/draft/next/vocab/custom": false }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/validation" }, { "$ref": "https://json-schema.org/draft/next/meta/core" } diff --git a/remotes/draft-next/subSchemas-defs.json b/remotes/draft-next/subSchemas-defs.json new file mode 100644 index 000000000..75b7583ca --- /dev/null +++ b/remotes/draft-next/subSchemas-defs.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/$defs/integer" + } + } +} diff --git a/remotes/draft-next/subSchemas.json b/remotes/draft-next/subSchemas.json index 75b7583ca..575dd00c2 100644 --- a/remotes/draft-next/subSchemas.json +++ b/remotes/draft-next/subSchemas.json @@ -1,11 +1,9 @@ { "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/$defs/integer" - } + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/integer" } } diff --git a/remotes/draft2019-09/metaschema-no-validation.json b/remotes/draft2019-09/metaschema-no-validation.json index 859006c27..494f0abff 100644 --- a/remotes/draft2019-09/metaschema-no-validation.json +++ b/remotes/draft2019-09/metaschema-no-validation.json @@ -5,7 +5,6 @@ "https://json-schema.org/draft/2019-09/vocab/applicator": true, "https://json-schema.org/draft/2019-09/vocab/core": true }, - "$recursiveAnchor": true, "allOf": [ { "$ref": "https://json-schema.org/draft/2019-09/meta/applicator" }, { "$ref": "https://json-schema.org/draft/2019-09/meta/core" } diff --git a/remotes/draft2019-09/metaschema-optional-vocabulary.json b/remotes/draft2019-09/metaschema-optional-vocabulary.json index 3a7502a21..968597c45 100644 --- a/remotes/draft2019-09/metaschema-optional-vocabulary.json +++ b/remotes/draft2019-09/metaschema-optional-vocabulary.json @@ -6,7 +6,6 @@ "https://json-schema.org/draft/2019-09/vocab/core": true, "http://localhost:1234/draft/2019-09/vocab/custom": false }, - "$recursiveAnchor": true, "allOf": [ { "$ref": "https://json-schema.org/draft/2019-09/meta/validation" }, { "$ref": "https://json-schema.org/draft/2019-09/meta/core" } diff --git a/remotes/draft2019-09/subSchemas-defs.json b/remotes/draft2019-09/subSchemas-defs.json new file mode 100644 index 000000000..fdfee68d9 --- /dev/null +++ b/remotes/draft2019-09/subSchemas-defs.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$defs": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/$defs/integer" + } + } +} diff --git a/remotes/draft2019-09/subSchemas.json b/remotes/draft2019-09/subSchemas.json index fdfee68d9..6dea22525 100644 --- a/remotes/draft2019-09/subSchemas.json +++ b/remotes/draft2019-09/subSchemas.json @@ -1,11 +1,9 @@ { "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/$defs/integer" - } + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/integer" } } diff --git a/remotes/draft2020-12/format-assertion-false.json b/remotes/draft2020-12/format-assertion-false.json index 43a711c9d..d6dd645b6 100644 --- a/remotes/draft2020-12/format-assertion-false.json +++ b/remotes/draft2020-12/format-assertion-false.json @@ -5,7 +5,6 @@ "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/format-assertion": false }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/core" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/format-assertion" } diff --git a/remotes/draft2020-12/format-assertion-true.json b/remotes/draft2020-12/format-assertion-true.json index 39c6b0abf..bb16d5864 100644 --- a/remotes/draft2020-12/format-assertion-true.json +++ b/remotes/draft2020-12/format-assertion-true.json @@ -5,7 +5,6 @@ "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/format-assertion": true }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/core" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/format-assertion" } diff --git a/remotes/draft2020-12/metaschema-no-validation.json b/remotes/draft2020-12/metaschema-no-validation.json index 71be8b5da..85d74b213 100644 --- a/remotes/draft2020-12/metaschema-no-validation.json +++ b/remotes/draft2020-12/metaschema-no-validation.json @@ -5,7 +5,6 @@ "https://json-schema.org/draft/2020-12/vocab/applicator": true, "https://json-schema.org/draft/2020-12/vocab/core": true }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/applicator" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/core" } diff --git a/remotes/draft2020-12/metaschema-optional-vocabulary.json b/remotes/draft2020-12/metaschema-optional-vocabulary.json index a6963e548..f38ec281d 100644 --- a/remotes/draft2020-12/metaschema-optional-vocabulary.json +++ b/remotes/draft2020-12/metaschema-optional-vocabulary.json @@ -6,7 +6,6 @@ "https://json-schema.org/draft/2020-12/vocab/core": true, "http://localhost:1234/draft/2020-12/vocab/custom": false }, - "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/validation" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/core" } diff --git a/remotes/draft2020-12/subSchemas-defs.json b/remotes/draft2020-12/subSchemas-defs.json new file mode 100644 index 000000000..1bb4846d7 --- /dev/null +++ b/remotes/draft2020-12/subSchemas-defs.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/$defs/integer" + } + } +} diff --git a/remotes/draft2020-12/subSchemas.json b/remotes/draft2020-12/subSchemas.json index 1bb4846d7..5fca21d82 100644 --- a/remotes/draft2020-12/subSchemas.json +++ b/remotes/draft2020-12/subSchemas.json @@ -1,11 +1,9 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/$defs/integer" - } + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/integer" } } diff --git a/remotes/draft4/subSchemas.json b/remotes/draft4/subSchemas.json deleted file mode 100644 index 6e9b3de35..000000000 --- a/remotes/draft4/subSchemas.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "definitions": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/definitions/integer" - } - } -} diff --git a/remotes/draft6/name.json b/remotes/draft6/name.json deleted file mode 100644 index fceacb809..000000000 --- a/remotes/draft6/name.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "definitions": { - "orNull": { - "anyOf": [ - { - "type": "null" - }, - { - "$ref": "#" - } - ] - } - }, - "type": "string" -} diff --git a/remotes/draft6/ref-and-definitions.json b/remotes/draft6/ref-and-definitions.json deleted file mode 100644 index b80deeb7b..000000000 --- a/remotes/draft6/ref-and-definitions.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$id": "http://localhost:1234/draft6/ref-and-definitions.json", - "definitions": { - "inner": { - "properties": { - "bar": { "type": "string" } - } - } - }, - "allOf": [ { "$ref": "#/definitions/inner" } ] -} diff --git a/remotes/draft6/subSchemas.json b/remotes/draft6/subSchemas.json deleted file mode 100644 index 6e9b3de35..000000000 --- a/remotes/draft6/subSchemas.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "definitions": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/definitions/integer" - } - } -} diff --git a/remotes/draft7/locationIndependentIdentifier.json b/remotes/draft7/locationIndependentIdentifier.json deleted file mode 100644 index e72815cd5..000000000 --- a/remotes/draft7/locationIndependentIdentifier.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "definitions": { - "refToInteger": { - "$ref": "#foo" - }, - "A": { - "$id": "#foo", - "type": "integer" - } - } -} diff --git a/remotes/draft7/name.json b/remotes/draft7/name.json deleted file mode 100644 index fceacb809..000000000 --- a/remotes/draft7/name.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "definitions": { - "orNull": { - "anyOf": [ - { - "type": "null" - }, - { - "$ref": "#" - } - ] - } - }, - "type": "string" -} diff --git a/remotes/draft7/subSchemas.json b/remotes/draft7/subSchemas.json deleted file mode 100644 index 6e9b3de35..000000000 --- a/remotes/draft7/subSchemas.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "definitions": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/definitions/integer" - } - } -} diff --git a/remotes/draft4/locationIndependentIdentifier.json b/remotes/locationIndependentIdentifierDraft4.json similarity index 100% rename from remotes/draft4/locationIndependentIdentifier.json rename to remotes/locationIndependentIdentifierDraft4.json diff --git a/remotes/draft6/locationIndependentIdentifier.json b/remotes/locationIndependentIdentifierPre2019.json similarity index 100% rename from remotes/draft6/locationIndependentIdentifier.json rename to remotes/locationIndependentIdentifierPre2019.json diff --git a/remotes/draft4/name.json b/remotes/name.json similarity index 100% rename from remotes/draft4/name.json rename to remotes/name.json diff --git a/remotes/draft7/ref-and-definitions.json b/remotes/ref-and-definitions.json similarity index 74% rename from remotes/draft7/ref-and-definitions.json rename to remotes/ref-and-definitions.json index d5929380c..e0ee802a9 100644 --- a/remotes/draft7/ref-and-definitions.json +++ b/remotes/ref-and-definitions.json @@ -1,5 +1,5 @@ { - "$id": "http://localhost:1234/draft7/ref-and-definitions.json", + "$id": "http://localhost:1234/ref-and-definitions.json", "definitions": { "inner": { "properties": { diff --git a/remotes/draft3/subSchemas.json b/remotes/subSchemas-defs.json similarity index 62% rename from remotes/draft3/subSchemas.json rename to remotes/subSchemas-defs.json index 6e9b3de35..50b7b6dc4 100644 --- a/remotes/draft3/subSchemas.json +++ b/remotes/subSchemas-defs.json @@ -1,10 +1,10 @@ { - "definitions": { + "$defs": { "integer": { "type": "integer" }, "refToInteger": { - "$ref": "#/definitions/integer" + "$ref": "#/$defs/integer" } } } diff --git a/remotes/subSchemas.json b/remotes/subSchemas.json new file mode 100644 index 000000000..9f8030bce --- /dev/null +++ b/remotes/subSchemas.json @@ -0,0 +1,8 @@ +{ + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/integer" + } +} diff --git a/test-schema.json b/test-schema.json index 0087c5e3d..833931620 100644 --- a/test-schema.json +++ b/test-schema.json @@ -27,69 +27,6 @@ "type": "array", "items": { "$ref": "#/$defs/test" }, "minItems": 1 - }, - "specification":{ - "description": "A reference to a specification document which defines the behavior tested by this test case. Typically this should be a JSON Schema specification document, though in cases where the JSON Schema specification points to another RFC it should contain *both* the portion of the JSON Schema specification which indicates what RFC (and section) to follow as *well* as information on where in that specification the behavior is specified.", - - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items":{ - "properties": { - "core": { - "description": "A section in official JSON Schema core drafts", - "url": "https://json-schema.org/specification-links", - "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", - "type":"string" - }, - "validation": { - "description": "A section in official JSON Schema validation drafts", - "url": "https://json-schema.org/specification-links", - "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", - "type":"string" - }, - "ecma262": { - "description": "A section in official ECMA 262 specification for defining regular expressions", - "url": "https://262.ecma-international.org/", - "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", - "type":"string" - }, - "perl5": { - "description": "A section name in Perl documentation for defining regular expressions", - "url": "https://perldoc.perl.org/perlre", - "type":"string" - }, - "quote": { - "description": "Quote describing the test case", - "type":"string" - } - }, - "patternProperties": { - "^rfc\\d+$": { - "description": "A section in official RFC for the given rfc number", - "url": "https://www.rfc-editor.org/", - "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", - "type":"string" - }, - "^iso\\d+$": { - "description": "A section in official ISO for the given iso number", - "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", - "type": "string" - } - }, - "additionalProperties": { "type": "string" }, - "minProperties": 1, - "propertyNames": { - "oneOf": [ - { - "pattern": "^((iso)|(rfc))[0-9]+$" - }, - { - "enum": [ "core", "validation", "ecma262", "perl5", "quote" ] - } - ] - } - } } }, "additionalProperties": false diff --git a/tests/draft-next/additionalProperties.json b/tests/draft-next/additionalProperties.json index 51b0edada..7859fbbf1 100644 --- a/tests/draft-next/additionalProperties.json +++ b/tests/draft-next/additionalProperties.json @@ -152,97 +152,5 @@ "valid": true } ] - }, - { - "description": "additionalProperties with propertyNames", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "propertyNames": { - "maxLength": 5 - }, - "additionalProperties": { - "type": "number" - } - }, - "tests": [ - { - "description": "Valid against both keywords", - "data": { "apple": 4 }, - "valid": true - }, - { - "description": "Valid against propertyNames, but not additionalProperties", - "data": { "fig": 2, "pear": "available" }, - "valid": false - } - ] - }, - { - "description": "propertyDependencies with additionalProperties", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "properties" : {"foo2" : {}}, - "propertyDependencies": { - "foo" : {}, - "foo2": { - "bar": { - "properties": { - "buz": {} - } - } - } - }, - "additionalProperties": false - }, - "tests": [ - { - "description": "additionalProperties doesn't consider propertyDependencies properties" , - "data": {"foo": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see buz even when foo2 is present", - "data": {"foo2": "bar", "buz": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see buz", - "data": {"buz": ""}, - "valid": false - } - ] - }, - { - "description": "dependentSchemas with additionalProperties", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "properties": {"foo2": {}}, - "dependentSchemas": { - "foo": {}, - "foo2": { - "properties": { - "bar": {} - } - } - }, - "additionalProperties": false - }, - "tests": [ - { - "description": "additionalProperties doesn't consider dependentSchemas", - "data": {"foo": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see bar", - "data": {"bar": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see bar even when foo2 is present", - "data": {"foo2": "", "bar": ""}, - "valid": false - } - ] } ] diff --git a/tests/draft-next/anchor.json b/tests/draft-next/anchor.json index 84d4851ca..321d84461 100644 --- a/tests/draft-next/anchor.json +++ b/tests/draft-next/anchor.json @@ -81,6 +81,64 @@ } ] }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + }, { "description": "same $anchor with different base uri", "schema": { @@ -116,5 +174,61 @@ "valid": false } ] + }, + { + "description": "non-schema object containing an $anchor property", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "const_not_anchor": { + "const": { + "$anchor": "not_a_real_anchor" + } + } + }, + "if": { + "const": "skip not_a_real_anchor" + }, + "then": true, + "else" : { + "$ref": "#/$defs/const_not_anchor" + } + }, + "tests": [ + { + "description": "skip traversing definition for a valid result", + "data": "skip not_a_real_anchor", + "valid": true + }, + { + "description": "const at const_not_anchor does not match", + "data": 1, + "valid": false + } + ] + }, + { + "description": "invalid anchors", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "MUST start with a letter (and not #)", + "data": { "$anchor" : "#foo" }, + "valid": false + }, + { + "description": "JSON pointers are not valid", + "data": { "$anchor" : "/a/b" }, + "valid": false + }, + { + "description": "invalid with valid beginning", + "data": { "$anchor" : "foo#something" }, + "valid": false + } + ] } ] diff --git a/tests/draft-next/contains.json b/tests/draft-next/contains.json index 8539a531d..c17f55ee7 100644 --- a/tests/draft-next/contains.json +++ b/tests/draft-next/contains.json @@ -31,6 +31,31 @@ "data": [], "valid": false }, + { + "description": "object with property matching schema (5) is valid", + "data": { "a": 3, "b": 4, "c": 5 }, + "valid": true + }, + { + "description": "object with property matching schema (6) is valid", + "data": { "a": 3, "b": 4, "c": 6 }, + "valid": true + }, + { + "description": "object with two properties matching schema (5, 6) is valid", + "data": { "a": 3, "b": 4, "c": 5, "d": 6 }, + "valid": true + }, + { + "description": "object without properties matching schema is invalid", + "data": { "a": 2, "b": 3, "c": 4 }, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, { "description": "not array or object is valid", "data": 42, @@ -59,6 +84,21 @@ "description": "array without item 5 is invalid", "data": [1, 2, 3, 4], "valid": false + }, + { + "description": "object with property 5 is valid", + "data": { "a": 3, "b": 4, "c": 5 }, + "valid": true + }, + { + "description": "object with two properties 5 is valid", + "data": { "a": 3, "b": 4, "c": 5, "d": 5 }, + "valid": true + }, + { + "description": "object without property 5 is invalid", + "data": { "a": 1, "b": 2, "c": 3, "d": 4 }, + "valid": false } ] }, @@ -78,6 +118,16 @@ "description": "empty array is invalid", "data": [], "valid": false + }, + { + "description": "any non-empty object is valid", + "data": { "a": "foo" }, + "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false } ] }, @@ -99,28 +149,18 @@ "valid": false }, { - "description": "non-arrays are valid - string", - "data": "contains does not apply to strings", - "valid": true + "description": "any non-empty object is invalid", + "data": ["foo"], + "valid": false }, { - "description": "non-arrays are valid - object", + "description": "empty object is invalid", "data": {}, - "valid": true - }, - { - "description": "non-arrays are valid - number", - "data": 42, - "valid": true - }, - { - "description": "non-arrays are valid - boolean", - "data": false, - "valid": true + "valid": false }, { - "description": "non-arrays are valid - null", - "data": null, + "description": "non-arrays/objects are valid", + "data": "contains does not apply to strings", "valid": true } ] @@ -153,6 +193,26 @@ "description": "matches neither items nor contains", "data": [1, 5], "valid": false + }, + { + "description": "matches additionalProperties, does not match contains", + "data": { "a": 2, "b": 4, "c": 8 }, + "valid": false + }, + { + "description": "does not match additionalProperties, matches contains", + "data": { "a": 3, "b": 6, "c": 9 }, + "valid": false + }, + { + "description": "matches both additionalProperties and contains", + "data": { "a": 6, "b": 12 }, + "valid": true + }, + { + "description": "matches neither additionalProperties nor contains", + "data": { "a": 1, "b": 5 }, + "valid": false } ] }, @@ -175,6 +235,16 @@ "description": "empty array is invalid", "data": [], "valid": false + }, + { + "description": "any non-empty object is valid", + "data": { "a": "foo" }, + "valid": true + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false } ] }, diff --git a/tests/draft-next/dependentSchemas.json b/tests/draft-next/dependentSchemas.json index 86079c34c..8a8477591 100644 --- a/tests/draft-next/dependentSchemas.json +++ b/tests/draft-next/dependentSchemas.json @@ -132,7 +132,6 @@ { "description": "dependent subschema incompatible with root", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {} }, diff --git a/tests/draft-next/dynamicRef.json b/tests/draft-next/dynamicRef.json index 30821c5b1..428c83b34 100644 --- a/tests/draft-next/dynamicRef.json +++ b/tests/draft-next/dynamicRef.json @@ -612,90 +612,5 @@ "valid": false } ] - }, - { - "description": "$dynamicRef points to a boolean schema", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "true": true, - "false": false - }, - "properties": { - "true": { - "$dynamicRef": "#/$defs/true" - }, - "false": { - "$dynamicRef": "#/$defs/false" - } - } - }, - "tests": [ - { - "description": "follow $dynamicRef to a true schema", - "data": { "true": 1 }, - "valid": true - }, - { - "description": "follow $dynamicRef to a false schema", - "data": { "false": 1 }, - "valid": false - } - ] - }, - { - "description": "$dynamicRef skips over intermediate resources - direct reference", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/main", - "type": "object", - "properties": { - "bar-item": { - "$ref": "item" - } - }, - "$defs": { - "bar": { - "$id": "bar", - "type": "array", - "items": { - "$ref": "item" - }, - "$defs": { - "item": { - "$id": "item", - "type": "object", - "properties": { - "content": { - "$dynamicRef": "#content" - } - }, - "$defs": { - "defaultContent": { - "$dynamicAnchor": "content", - "type": "integer" - } - } - }, - "content": { - "$dynamicAnchor": "content", - "type": "string" - } - } - } - } - }, - "tests": [ - { - "description": "integer property passes", - "data": { "bar-item": { "content": 42 } }, - "valid": true - }, - { - "description": "string property fails", - "data": { "bar-item": { "content": "value" } }, - "valid": false - } - ] } ] diff --git a/tests/draft-next/enum.json b/tests/draft-next/enum.json index e263f3901..32e5af01b 100644 --- a/tests/draft-next/enum.json +++ b/tests/draft-next/enum.json @@ -168,30 +168,6 @@ } ] }, - { - "description": "enum with [false] does not match [0]", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "enum": [[false]] - }, - "tests": [ - { - "description": "[false] is valid", - "data": [false], - "valid": true - }, - { - "description": "[0] is invalid", - "data": [0], - "valid": false - }, - { - "description": "[0.0] is invalid", - "data": [0.0], - "valid": false - } - ] - }, { "description": "enum with true does not match 1", "schema": { @@ -216,30 +192,6 @@ } ] }, - { - "description": "enum with [true] does not match [1]", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "enum": [[true]] - }, - "tests": [ - { - "description": "[true] is valid", - "data": [true], - "valid": true - }, - { - "description": "[1] is invalid", - "data": [1], - "valid": false - }, - { - "description": "[1.0] is invalid", - "data": [1.0], - "valid": false - } - ] - }, { "description": "enum with 0 does not match false", "schema": { @@ -264,30 +216,6 @@ } ] }, - { - "description": "enum with [0] does not match [false]", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "enum": [[0]] - }, - "tests": [ - { - "description": "[false] is invalid", - "data": [false], - "valid": false - }, - { - "description": "[0] is valid", - "data": [0], - "valid": true - }, - { - "description": "[0.0] is valid", - "data": [0.0], - "valid": true - } - ] - }, { "description": "enum with 1 does not match true", "schema": { @@ -312,30 +240,6 @@ } ] }, - { - "description": "enum with [1] does not match [true]", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "enum": [[1]] - }, - "tests": [ - { - "description": "[true] is invalid", - "data": [true], - "valid": false - }, - { - "description": "[1] is valid", - "data": [1], - "valid": true - }, - { - "description": "[1.0] is valid", - "data": [1.0], - "valid": true - } - ] - }, { "description": "nul characters in strings", "schema": { diff --git a/tests/draft-next/id.json b/tests/draft-next/id.json new file mode 100644 index 000000000..9b3a591f0 --- /dev/null +++ b/tests/draft-next/id.json @@ -0,0 +1,294 @@ +[ + { + "description": "Invalid use of fragments in location-independent $id", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "Identifier name", + "data": { + "$ref": "#foo", + "$defs": { + "A": { + "$id": "#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name and no ref", + "data": { + "$defs": { + "A": { "$id": "#foo" } + } + }, + "valid": false + }, + { + "description": "Identifier path", + "data": { + "$ref": "#/a/b", + "$defs": { + "A": { + "$id": "#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft-next/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft-next/bar#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier path with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft-next/bar#/a/b", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft-next/bar#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft-next/root", + "$ref": "http://localhost:1234/draft-next/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#foo", + "type": "integer" + } + } + } + } + }, + "valid": false + }, + { + "description": "Identifier path with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft-next/root", + "$ref": "http://localhost:1234/draft-next/nested.json#/a/b", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#/a/b", + "type": "integer" + } + } + } + } + }, + "valid": false + } + ] + }, + { + "description": "Valid use of empty fragments in location-independent $id", + "comment": "These are allowed but discouraged", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft-next/bar", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft-next/bar#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft-next/root", + "$ref": "http://localhost:1234/draft-next/nested.json#/$defs/B", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#", + "type": "integer" + } + } + } + } + }, + "valid": true + } + ] + }, + { + "description": "Unnormalized $ids are allowed but discouraged", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "Unnormalized identifier", + "data": { + "$ref": "http://localhost:1234/draft-next/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft-next/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/draft-next/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment", + "data": { + "$ref": "http://localhost:1234/draft-next/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft-next/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/draft-next/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + } + ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/draft-next/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + }, + { + "description": "non-schema object containing an $id property", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "const_not_id": { + "const": { + "$id": "not_a_real_id" + } + } + }, + "if": { + "const": "skip not_a_real_id" + }, + "then": true, + "else" : { + "$ref": "#/$defs/const_not_id" + } + }, + "tests": [ + { + "description": "skip traversing definition for a valid result", + "data": "skip not_a_real_id", + "valid": true + }, + { + "description": "const at const_not_id does not match", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft-next/items.json b/tests/draft-next/items.json index dfb79af2f..459943bef 100644 --- a/tests/draft-next/items.json +++ b/tests/draft-next/items.json @@ -265,26 +265,6 @@ } ] }, - { - "description": "items with heterogeneous array", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "prefixItems": [{}], - "items": false - }, - "tests": [ - { - "description": "heterogeneous invalid instance", - "data": [ "foo", "bar", 37 ], - "valid": false - }, - { - "description": "valid instance", - "data": [ null ], - "valid": true - } - ] - }, { "description": "items with null instance elements", "schema": { diff --git a/tests/draft-next/maxContains.json b/tests/draft-next/maxContains.json index 5af6e4c13..7c1515753 100644 --- a/tests/draft-next/maxContains.json +++ b/tests/draft-next/maxContains.json @@ -15,6 +15,16 @@ "description": "two items still valid against lone maxContains", "data": [1, 2], "valid": true + }, + { + "description": "one property valid against lone maxContains", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "two properties still valid against lone maxContains", + "data": { "a": 1, "b": 2 }, + "valid": true } ] }, @@ -50,6 +60,31 @@ "description": "some elements match, invalid maxContains", "data": [1, 2, 1], "valid": false + }, + { + "description": "empty object", + "data": {}, + "valid": false + }, + { + "description": "all properties match, valid maxContains", + "data": { "a": 1 }, + "valid": true + }, + { + "description": "all properties match, invalid maxContains", + "data": { "a": 1, "b": 1 }, + "valid": false + }, + { + "description": "some properties match, valid maxContains", + "data": { "a": 1, "b": 2 }, + "valid": true + }, + { + "description": "some properties match, invalid maxContains", + "data": { "a": 1, "b": 2, "c": 1 }, + "valid": false } ] }, @@ -96,6 +131,21 @@ "description": "array with minContains < maxContains < actual", "data": [1, 1, 1, 1], "valid": false + }, + { + "description": "object with actual < minContains < maxContains", + "data": {}, + "valid": false + }, + { + "description": "object with minContains < actual < maxContains", + "data": { "a": 1, "b": 1 }, + "valid": true + }, + { + "description": "object with minContains < maxContains < actual", + "data": { "a": 1, "b": 1, "c": 1, "d": 1 }, + "valid": false } ] } diff --git a/tests/draft-next/maxLength.json b/tests/draft-next/maxLength.json index c88f604ef..e09e44ad8 100644 --- a/tests/draft-next/maxLength.json +++ b/tests/draft-next/maxLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "two graphemes is long enough", + "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft-next/minLength.json b/tests/draft-next/minLength.json index 52c9c9a14..16022acb5 100644 --- a/tests/draft-next/minLength.json +++ b/tests/draft-next/minLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "one grapheme is not long enough", + "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft-next/oneOf.json b/tests/draft-next/oneOf.json index 840d1579d..e8c077131 100644 --- a/tests/draft-next/oneOf.json +++ b/tests/draft-next/oneOf.json @@ -220,7 +220,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/next/schema", diff --git a/tests/draft-next/optional/anchor.json b/tests/draft-next/optional/anchor.json deleted file mode 100644 index 1de0b7a70..000000000 --- a/tests/draft-next/optional/anchor.json +++ /dev/null @@ -1,60 +0,0 @@ -[ - { - "description": "$anchor inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $anchor buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "anchor_in_enum": { - "enum": [ - { - "$anchor": "my_anchor", - "type": "null" - } - ] - }, - "real_identifier_in_schema": { - "$anchor": "my_anchor", - "type": "string" - }, - "zzz_anchor_in_const": { - "const": { - "$anchor": "my_anchor", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/anchor_in_enum" }, - { "$ref": "#my_anchor" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$anchor": "my_anchor", - "type": "null" - }, - "valid": true - }, - { - "description": "in implementations that strip $anchor, this may match either $def", - "data": { - "type": "null" - }, - "valid": false - }, - { - "description": "match $ref to $anchor", - "data": "a string to match #/$defs/anchor_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $anchor", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft-next/optional/dynamicRef.json b/tests/draft-next/optional/dynamicRef.json deleted file mode 100644 index dcace154e..000000000 --- a/tests/draft-next/optional/dynamicRef.json +++ /dev/null @@ -1,56 +0,0 @@ -[ - { - "description": "$dynamicRef skips over intermediate resources - pointer reference across resource boundary", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/optional/main", - "type": "object", - "properties": { - "bar-item": { - "$ref": "bar#/$defs/item" - } - }, - "$defs": { - "bar": { - "$id": "bar", - "type": "array", - "items": { - "$ref": "item" - }, - "$defs": { - "item": { - "$id": "item", - "type": "object", - "properties": { - "content": { - "$dynamicRef": "#content" - } - }, - "$defs": { - "defaultContent": { - "$dynamicAnchor": "content", - "type": "integer" - } - } - }, - "content": { - "$dynamicAnchor": "content", - "type": "string" - } - } - } - } - }, - "tests": [ - { - "description": "integer property passes", - "data": { "bar-item": { "content": 42 } }, - "valid": true - }, - { - "description": "string property fails", - "data": { "bar-item": { "content": "value" } }, - "valid": false - } - ] - }] \ No newline at end of file diff --git a/tests/draft-next/optional/ecmascript-regex.json b/tests/draft-next/optional/ecmascript-regex.json index a1a4f9638..272114503 100644 --- a/tests/draft-next/optional/ecmascript-regex.json +++ b/tests/draft-next/optional/ecmascript-regex.json @@ -405,6 +405,20 @@ } ] }, + { + "description": "\\a is not an ECMA 262 control escape", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "https://json-schema.org/draft/next/schema" + }, + "tests": [ + { + "description": "when used as a pattern", + "data": { "pattern": "\\a" }, + "valid": false + } + ] + }, { "description": "pattern with non-ASCII digits", "schema": { diff --git a/tests/draft-next/optional/format/duration.json b/tests/draft-next/optional/format/duration.json index c4aa66bae..d5adca206 100644 --- a/tests/draft-next/optional/format/duration.json +++ b/tests/draft-next/optional/format/duration.json @@ -46,11 +46,6 @@ "data": "PT1D", "valid": false }, - { - "description": "must start with P", - "data": "4DT12H30M5S", - "valid": false - }, { "description": "no elements present", "data": "P", diff --git a/tests/draft-next/optional/format/ecmascript-regex.json b/tests/draft-next/optional/format/ecmascript-regex.json deleted file mode 100644 index 1e19c2729..000000000 --- a/tests/draft-next/optional/format/ecmascript-regex.json +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - "description": "\\a is not an ECMA 262 control escape", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "format": "regex" - }, - "tests": [ - { - "description": "when used as a pattern", - "data": "\\a", - "valid": false - } - ] - } -] diff --git a/tests/draft-next/optional/format/hostname.json b/tests/draft-next/optional/format/hostname.json index bc3a60dcc..bfb306363 100644 --- a/tests/draft-next/optional/format/hostname.json +++ b/tests/draft-next/optional/format/hostname.json @@ -120,16 +120,6 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - }, - { - "description": "single dot", - "data": ".", - "valid": false } ] } diff --git a/tests/draft-next/optional/format/idn-hostname.json b/tests/draft-next/optional/format/idn-hostname.json index 1061f4243..ee2e792fa 100644 --- a/tests/draft-next/optional/format/idn-hostname.json +++ b/tests/draft-next/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0628\u0660\u06f0", + "data": "\u0660\u06f0", "valid": false }, { @@ -301,88 +301,6 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true - }, - { - "description": "single label", - "data": "hostname", - "valid": true - }, - { - "description": "single label with hyphen", - "data": "host-name", - "valid": true - }, - { - "description": "single label with digits", - "data": "h0stn4me", - "valid": true - }, - { - "description": "single label starting with digit", - "data": "1host", - "valid": true - }, - { - "description": "single label ending with digit", - "data": "hostnam3", - "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - } - ] - }, - { - "description": "validation of separators in internationalized host names", - "specification": [ - {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} - ], - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "format": "idn-hostname" - }, - "tests": [ - { - "description": "single dot", - "data": ".", - "valid": false - }, - { - "description": "single ideographic full stop", - "data": "\u3002", - "valid": false - }, - { - "description": "single fullwidth full stop", - "data": "\uff0e", - "valid": false - }, - { - "description": "single halfwidth ideographic full stop", - "data": "\uff61", - "valid": false - }, - { - "description": "dot as label separator", - "data": "a.b", - "valid": true - }, - { - "description": "ideographic full stop as label separator", - "data": "a\u3002b", - "valid": true - }, - { - "description": "fullwidth full stop as label separator", - "data": "a\uff0eb", - "valid": true - }, - { - "description": "halfwidth ideographic full stop as label separator", - "data": "a\uff61b", - "valid": true } ] } diff --git a/tests/draft-next/optional/format/ipv4.json b/tests/draft-next/optional/format/ipv4.json index 2a4bc2b2f..e3e944015 100644 --- a/tests/draft-next/optional/format/ipv4.json +++ b/tests/draft-next/optional/format/ipv4.json @@ -81,11 +81,6 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false - }, - { - "description": "netmask is not a part of ipv4 address", - "data": "192.168.1.0/24", - "valid": false } ] } diff --git a/tests/draft-next/optional/id.json b/tests/draft-next/optional/id.json deleted file mode 100644 index fc26f26c2..000000000 --- a/tests/draft-next/optional/id.json +++ /dev/null @@ -1,53 +0,0 @@ -[ - { - "description": "$id inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $id buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "id_in_enum": { - "enum": [ - { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "null" - } - ] - }, - "real_id_in_schema": { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "string" - }, - "zzz_id_in_const": { - "const": { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "https://localhost:1234/draft-next/id/my_identifier.json" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "null" - }, - "valid": true - }, - { - "description": "match $ref to $id", - "data": "a string to match #/$defs/id_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $id", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft-next/optional/refOfUnknownKeyword.json b/tests/draft-next/optional/refOfUnknownKeyword.json index c832e09f6..489701cd2 100644 --- a/tests/draft-next/optional/refOfUnknownKeyword.json +++ b/tests/draft-next/optional/refOfUnknownKeyword.json @@ -42,28 +42,5 @@ "valid": false } ] - }, - { - "description": "reference internals of known non-applicator", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$id": "/base", - "examples": [ - { "type": "string" } - ], - "$ref": "#/examples/0" - }, - "tests": [ - { - "description": "match", - "data": "a string", - "valid": true - }, - { - "description": "mismatch", - "data": 42, - "valid": false - } - ] } ] diff --git a/tests/draft-next/ref.json b/tests/draft-next/ref.json index 8417ce299..1d5f25613 100644 --- a/tests/draft-next/ref.json +++ b/tests/draft-next/ref.json @@ -862,7 +862,6 @@ { "description": "URN ref with nested pointer ref", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { @@ -888,7 +887,6 @@ { "description": "ref to if", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", @@ -911,7 +909,6 @@ { "description": "ref to then", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", @@ -934,7 +931,6 @@ { "description": "ref to else", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", @@ -957,7 +953,6 @@ { "description": "ref with absolute-path-reference", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { @@ -987,7 +982,6 @@ { "description": "$id with file URI still resolves pointers - *nix", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { @@ -1012,7 +1006,6 @@ { "description": "$id with file URI still resolves pointers - windows", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { @@ -1037,7 +1030,6 @@ { "description": "empty tokens in $ref json-pointer", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "": { "$defs": { diff --git a/tests/draft-next/refRemote.json b/tests/draft-next/refRemote.json index 647fb9f19..9befceb25 100644 --- a/tests/draft-next/refRemote.json +++ b/tests/draft-next/refRemote.json @@ -22,7 +22,7 @@ "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "http://localhost:1234/draft-next/subSchemas.json#/$defs/integer" + "$ref": "http://localhost:1234/draft-next/subSchemas-defs.json#/$defs/integer" }, "tests": [ { @@ -60,7 +60,7 @@ "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "http://localhost:1234/draft-next/subSchemas.json#/$defs/refToInteger" + "$ref": "http://localhost:1234/draft-next/subSchemas-defs.json#/$defs/refToInteger" }, "tests": [ { @@ -265,10 +265,7 @@ }, { "description": "remote HTTP ref with different $id", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "http://localhost:1234/different-id-ref-string.json" - }, + "schema": {"$ref": "http://localhost:1234/different-id-ref-string.json"}, "tests": [ { "description": "number is invalid", @@ -284,10 +281,7 @@ }, { "description": "remote HTTP ref with different URN $id", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "http://localhost:1234/urn-ref-string.json" - }, + "schema": {"$ref": "http://localhost:1234/urn-ref-string.json"}, "tests": [ { "description": "number is invalid", @@ -303,10 +297,7 @@ }, { "description": "remote HTTP ref with nested absolute ref", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" - }, + "schema": {"$ref": "http://localhost:1234/nested-absolute-ref-to-string.json"}, "tests": [ { "description": "number is invalid", @@ -323,7 +314,6 @@ { "description": "$ref to $ref finds detached $anchor", "schema": { - "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/detached-ref.json#/$defs/foo" }, "tests": [ diff --git a/tests/draft-next/unevaluatedItems.json b/tests/draft-next/unevaluatedItems.json index 08f6ef128..7379afb41 100644 --- a/tests/draft-next/unevaluatedItems.json +++ b/tests/draft-next/unevaluatedItems.json @@ -461,79 +461,6 @@ } ] }, - { - "description": "unevaluatedItems before $ref", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "unevaluatedItems": false, - "prefixItems": [ - { "type": "string" } - ], - "$ref": "#/$defs/bar", - "$defs": { - "bar": { - "prefixItems": [ - true, - { "type": "string" } - ] - } - } - }, - "tests": [ - { - "description": "with no unevaluated items", - "data": ["foo", "bar"], - "valid": true - }, - { - "description": "with unevaluated items", - "data": ["foo", "bar", "baz"], - "valid": false - } - ] - }, - { - "description": "unevaluatedItems with $dynamicRef", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$id": "https://example.com/unevaluated-items-with-dynamic-ref/derived", - - "$ref": "./baseSchema", - - "$defs": { - "derived": { - "$dynamicAnchor": "addons", - "prefixItems": [ - true, - { "type": "string" } - ] - }, - "baseSchema": { - "$id": "./baseSchema", - - "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", - "unevaluatedItems": false, - "type": "array", - "prefixItems": [ - { "type": "string" } - ], - "$dynamicRef": "#addons" - } - } - }, - "tests": [ - { - "description": "with no unevaluated items", - "data": ["foo", "bar"], - "valid": true - }, - { - "description": "with unevaluated items", - "data": ["foo", "bar", "baz"], - "valid": false - } - ] - }, { "description": "unevaluatedItems can't see inside cousins", "schema": { diff --git a/tests/draft-next/unevaluatedProperties.json b/tests/draft-next/unevaluatedProperties.json index 13fe6e03a..69fe8a00c 100644 --- a/tests/draft-next/unevaluatedProperties.json +++ b/tests/draft-next/unevaluatedProperties.json @@ -715,92 +715,6 @@ } ] }, - { - "description": "unevaluatedProperties before $ref", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "type": "object", - "unevaluatedProperties": false, - "properties": { - "foo": { "type": "string" } - }, - "$ref": "#/$defs/bar", - "$defs": { - "bar": { - "properties": { - "bar": { "type": "string" } - } - } - } - }, - "tests": [ - { - "description": "with no unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar" - }, - "valid": true - }, - { - "description": "with unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar", - "baz": "baz" - }, - "valid": false - } - ] - }, - { - "description": "unevaluatedProperties with $dynamicRef", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$id": "https://example.com/unevaluated-properties-with-dynamic-ref/derived", - - "$ref": "./baseSchema", - - "$defs": { - "derived": { - "$dynamicAnchor": "addons", - "properties": { - "bar": { "type": "string" } - } - }, - "baseSchema": { - "$id": "./baseSchema", - - "$comment": "unevaluatedProperties comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", - "unevaluatedProperties": false, - "type": "object", - "properties": { - "foo": { "type": "string" } - }, - "$dynamicRef": "#addons" - } - } - }, - "tests": [ - { - "description": "with no unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar" - }, - "valid": true - }, - { - "description": "with unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar", - "baz": "baz" - }, - "valid": false - } - ] - }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { @@ -1451,6 +1365,57 @@ } ] }, + { + "description": "unevaluatedProperties depends on adjacent contains", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "properties": { + "foo": { "type": "number" } + }, + "contains": { "type": "string" }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "bar is evaluated by contains", + "data": { "foo": 1, "bar": "foo" }, + "valid": true + }, + { + "description": "contains fails, bar is not evaluated", + "data": { "foo": 1, "bar": 2 }, + "valid": false + }, + { + "description": "contains passes, bar is not evaluated", + "data": { "foo": 1, "bar": 2, "baz": "foo" }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties depends on multiple nested contains", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "allOf": [ + { "contains": { "multipleOf": 2 } }, + { "contains": { "multipleOf": 3 } } + ], + "unevaluatedProperties": { "multipleOf": 5 } + }, + "tests": [ + { + "description": "5 not evaluated, passes unevaluatedItems", + "data": { "a": 2, "b": 3, "c": 4, "d": 5, "e": 6 }, + "valid": true + }, + { + "description": "7 not evaluated, fails unevaluatedItems", + "data": { "a": 2, "b": 3, "c": 4, "d": 7, "e": 8 }, + "valid": false + } + ] + }, { "description": "non-object instances are valid", "schema": { @@ -1603,74 +1568,5 @@ "valid": false } ] - }, - { - "description": "propertyDependencies with unevaluatedProperties" , - "schema" : { - "$schema": "https://json-schema.org/draft/next/schema", - "properties" : {"foo2" : {}}, - "propertyDependencies": { - "foo" : {}, - "foo2": { - "bar": { - "properties": { - "buz": {} - } - } - } - }, - "unevaluatedProperties": false - }, - - "tests": [ - { - "description": "unevaluatedProperties doesn't consider propertyDependencies" , - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "unevaluatedProperties sees buz when foo2 is present", - "data": {"foo2": "bar", "buz": ""}, - "valid": true - }, - { - "description": "unevaluatedProperties doesn't see buz when foo2 is absent", - "data": {"buz": ""}, - "valid": false - } - ] - }, - { - "description": "dependentSchemas with unevaluatedProperties", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "properties": {"foo2": {}}, - "dependentSchemas": { - "foo" : {}, - "foo2": { - "properties": { - "bar":{} - } - } - }, - "unevaluatedProperties": false - }, - "tests": [ - { - "description": "unevaluatedProperties doesn't consider dependentSchemas", - "data": {"foo": ""}, - "valid": false - }, - { - "description": "unevaluatedProperties doesn't see bar when foo2 is absent", - "data": {"bar": ""}, - "valid": false - }, - { - "description": "unevaluatedProperties sees bar when foo2 is present", - "data": {"foo2": "", "bar": ""}, - "valid": true - } - ] } ] diff --git a/tests/draft-next/optional/unknownKeyword.json b/tests/draft-next/unknownKeyword.json similarity index 100% rename from tests/draft-next/optional/unknownKeyword.json rename to tests/draft-next/unknownKeyword.json diff --git a/tests/draft2019-09/additionalItems.json b/tests/draft2019-09/additionalItems.json index 9a7ae4f8a..aa44bcb76 100644 --- a/tests/draft2019-09/additionalItems.json +++ b/tests/draft2019-09/additionalItems.json @@ -182,26 +182,6 @@ } ] }, - { - "description": "additionalItems with heterogeneous array", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "items": [{}], - "additionalItems": false - }, - "tests": [ - { - "description": "heterogeneous invalid instance", - "data": [ "foo", "bar", 37 ], - "valid": false - }, - { - "description": "valid instance", - "data": [ null ], - "valid": true - } - ] - }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft2019-09/additionalProperties.json b/tests/draft2019-09/additionalProperties.json index 73f9b909e..f9f03bb04 100644 --- a/tests/draft2019-09/additionalProperties.json +++ b/tests/draft2019-09/additionalProperties.json @@ -152,62 +152,5 @@ "valid": true } ] - }, - { - "description": "additionalProperties with propertyNames", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "propertyNames": { - "maxLength": 5 - }, - "additionalProperties": { - "type": "number" - } - }, - "tests": [ - { - "description": "Valid against both keywords", - "data": { "apple": 4 }, - "valid": true - }, - { - "description": "Valid against propertyNames, but not additionalProperties", - "data": { "fig": 2, "pear": "available" }, - "valid": false - } - ] - }, - { - "description": "dependentSchemas with additionalProperties", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "properties": {"foo2": {}}, - "dependentSchemas": { - "foo" : {}, - "foo2": { - "properties": { - "bar":{} - } - } - }, - "additionalProperties": false - }, - "tests": [ - { - "description": "additionalProperties doesn't consider dependentSchemas", - "data": {"foo": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see bar", - "data": {"bar": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see bar even when foo2 is present", - "data": { "foo2": "", "bar": ""}, - "valid": false - } - ] } ] diff --git a/tests/draft2019-09/anchor.json b/tests/draft2019-09/anchor.json index bce05e800..5d8c86f11 100644 --- a/tests/draft2019-09/anchor.json +++ b/tests/draft2019-09/anchor.json @@ -81,6 +81,64 @@ } ] }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + }, { "description": "same $anchor with different base uri", "schema": { @@ -116,5 +174,62 @@ "valid": false } ] + }, + { + "description": "non-schema object containing an $anchor property", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$defs": { + "const_not_anchor": { + "const": { + "$anchor": "not_a_real_anchor" + } + } + }, + "if": { + "const": "skip not_a_real_anchor" + }, + "then": true, + "else" : { + "$ref": "#/$defs/const_not_anchor" + } + }, + "tests": [ + { + "description": "skip traversing definition for a valid result", + "data": "skip not_a_real_anchor", + "valid": true + }, + { + "description": "const at const_not_anchor does not match", + "data": 1, + "valid": false + } + ] + }, + { + "description": "invalid anchors", + "comment": "Section 8.2.3", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "https://json-schema.org/draft/2019-09/schema" + }, + "tests": [ + { + "description": "MUST start with a letter (and not #)", + "data": { "$anchor" : "#foo" }, + "valid": false + }, + { + "description": "JSON pointers are not valid", + "data": { "$anchor" : "/a/b" }, + "valid": false + }, + { + "description": "invalid with valid beginning", + "data": { "$anchor" : "foo#something" }, + "valid": false + } + ] } ] diff --git a/tests/draft2019-09/dependentSchemas.json b/tests/draft2019-09/dependentSchemas.json index c5b8ea05f..3577efdf4 100644 --- a/tests/draft2019-09/dependentSchemas.json +++ b/tests/draft2019-09/dependentSchemas.json @@ -132,7 +132,6 @@ { "description": "dependent subschema incompatible with root", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {} }, diff --git a/tests/draft2019-09/enum.json b/tests/draft2019-09/enum.json index 1315211ea..f9a44a61d 100644 --- a/tests/draft2019-09/enum.json +++ b/tests/draft2019-09/enum.json @@ -168,30 +168,6 @@ } ] }, - { - "description": "enum with [false] does not match [0]", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "enum": [[false]] - }, - "tests": [ - { - "description": "[false] is valid", - "data": [false], - "valid": true - }, - { - "description": "[0] is invalid", - "data": [0], - "valid": false - }, - { - "description": "[0.0] is invalid", - "data": [0.0], - "valid": false - } - ] - }, { "description": "enum with true does not match 1", "schema": { @@ -216,30 +192,6 @@ } ] }, - { - "description": "enum with [true] does not match [1]", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "enum": [[true]] - }, - "tests": [ - { - "description": "[true] is valid", - "data": [true], - "valid": true - }, - { - "description": "[1] is invalid", - "data": [1], - "valid": false - }, - { - "description": "[1.0] is invalid", - "data": [1.0], - "valid": false - } - ] - }, { "description": "enum with 0 does not match false", "schema": { @@ -264,30 +216,6 @@ } ] }, - { - "description": "enum with [0] does not match [false]", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "enum": [[0]] - }, - "tests": [ - { - "description": "[false] is invalid", - "data": [false], - "valid": false - }, - { - "description": "[0] is valid", - "data": [0], - "valid": true - }, - { - "description": "[0.0] is valid", - "data": [0.0], - "valid": true - } - ] - }, { "description": "enum with 1 does not match true", "schema": { @@ -312,30 +240,6 @@ } ] }, - { - "description": "enum with [1] does not match [true]", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "enum": [[1]] - }, - "tests": [ - { - "description": "[true] is invalid", - "data": [true], - "valid": false - }, - { - "description": "[1] is valid", - "data": [1], - "valid": true - }, - { - "description": "[1.0] is valid", - "data": [1.0], - "valid": true - } - ] - }, { "description": "nul characters in strings", "schema": { diff --git a/tests/draft2019-09/id.json b/tests/draft2019-09/id.json new file mode 100644 index 000000000..e2e403f0b --- /dev/null +++ b/tests/draft2019-09/id.json @@ -0,0 +1,294 @@ +[ + { + "description": "Invalid use of fragments in location-independent $id", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "https://json-schema.org/draft/2019-09/schema" + }, + "tests": [ + { + "description": "Identifier name", + "data": { + "$ref": "#foo", + "$defs": { + "A": { + "$id": "#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name and no ref", + "data": { + "$defs": { + "A": { "$id": "#foo" } + } + }, + "valid": false + }, + { + "description": "Identifier path", + "data": { + "$ref": "#/a/b", + "$defs": { + "A": { + "$id": "#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft2019-09/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2019-09/bar#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier path with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft2019-09/bar#/a/b", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2019-09/bar#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft2019-09/root", + "$ref": "http://localhost:1234/draft2019-09/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#foo", + "type": "integer" + } + } + } + } + }, + "valid": false + }, + { + "description": "Identifier path with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft2019-09/root", + "$ref": "http://localhost:1234/draft2019-09/nested.json#/a/b", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#/a/b", + "type": "integer" + } + } + } + } + }, + "valid": false + } + ] + }, + { + "description": "Valid use of empty fragments in location-independent $id", + "comment": "These are allowed but discouraged", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "https://json-schema.org/draft/2019-09/schema" + }, + "tests": [ + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft2019-09/bar", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2019-09/bar#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft2019-09/root", + "$ref": "http://localhost:1234/draft2019-09/nested.json#/$defs/B", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#", + "type": "integer" + } + } + } + } + }, + "valid": true + } + ] + }, + { + "description": "Unnormalized $ids are allowed but discouraged", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "https://json-schema.org/draft/2019-09/schema" + }, + "tests": [ + { + "description": "Unnormalized identifier", + "data": { + "$ref": "http://localhost:1234/draft2019-09/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment", + "data": { + "$ref": "http://localhost:1234/draft2019-09/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + } + ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/draft2019-09/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + }, + { + "description": "non-schema object containing an $id property", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$defs": { + "const_not_id": { + "const": { + "$id": "not_a_real_id" + } + } + }, + "if": { + "const": "skip not_a_real_id" + }, + "then": true, + "else" : { + "$ref": "#/$defs/const_not_id" + } + }, + "tests": [ + { + "description": "skip traversing definition for a valid result", + "data": "skip not_a_real_id", + "valid": true + }, + { + "description": "const at const_not_id does not match", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft2019-09/maxLength.json b/tests/draft2019-09/maxLength.json index a0cc7d9b8..f242c3eff 100644 --- a/tests/draft2019-09/maxLength.json +++ b/tests/draft2019-09/maxLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "two graphemes is long enough", + "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft2019-09/minLength.json b/tests/draft2019-09/minLength.json index 12782660c..19dec2cac 100644 --- a/tests/draft2019-09/minLength.json +++ b/tests/draft2019-09/minLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "one grapheme is not long enough", + "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft2019-09/not.json b/tests/draft2019-09/not.json index d90728c7b..62c9af9de 100644 --- a/tests/draft2019-09/not.json +++ b/tests/draft2019-09/not.json @@ -97,173 +97,25 @@ ] }, { - "description": "forbid everything with empty schema", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "not": {} - }, - "tests": [ - { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", - "data": "foo", - "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false - } - ] - }, - { - "description": "forbid everything with boolean schema true", + "description": "not with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": true }, "tests": [ { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", + "description": "any value is invalid", "data": "foo", "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false } ] }, { - "description": "allow everything with boolean schema false", + "description": "not with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": false }, - "tests": [ - { - "description": "number is valid", - "data": 1, - "valid": true - }, - { - "description": "string is valid", - "data": "foo", - "valid": true - }, - { - "description": "boolean true is valid", - "data": true, - "valid": true - }, - { - "description": "boolean false is valid", - "data": false, - "valid": true - }, - { - "description": "null is valid", - "data": null, - "valid": true - }, - { - "description": "object is valid", - "data": {"foo": "bar"}, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "array is valid", - "data": ["foo"], - "valid": true - }, - { - "description": "empty array is valid", - "data": [], - "valid": true - } - ] - }, - { - "description": "double negation", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "not": { "not": {} } - }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft2019-09/oneOf.json b/tests/draft2019-09/oneOf.json index c27d4865c..9b7a2204e 100644 --- a/tests/draft2019-09/oneOf.json +++ b/tests/draft2019-09/oneOf.json @@ -220,7 +220,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", diff --git a/tests/draft2019-09/optional/anchor.json b/tests/draft2019-09/optional/anchor.json deleted file mode 100644 index 45951d0a3..000000000 --- a/tests/draft2019-09/optional/anchor.json +++ /dev/null @@ -1,60 +0,0 @@ -[ - { - "description": "$anchor inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $anchor buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "anchor_in_enum": { - "enum": [ - { - "$anchor": "my_anchor", - "type": "null" - } - ] - }, - "real_identifier_in_schema": { - "$anchor": "my_anchor", - "type": "string" - }, - "zzz_anchor_in_const": { - "const": { - "$anchor": "my_anchor", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/anchor_in_enum" }, - { "$ref": "#my_anchor" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$anchor": "my_anchor", - "type": "null" - }, - "valid": true - }, - { - "description": "in implementations that strip $anchor, this may match either $def", - "data": { - "type": "null" - }, - "valid": false - }, - { - "description": "match $ref to $anchor", - "data": "a string to match #/$defs/anchor_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $anchor", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft2019-09/optional/format/duration.json b/tests/draft2019-09/optional/format/duration.json index 2d515a64a..00d5f47ae 100644 --- a/tests/draft2019-09/optional/format/duration.json +++ b/tests/draft2019-09/optional/format/duration.json @@ -46,11 +46,6 @@ "data": "PT1D", "valid": false }, - { - "description": "must start with P", - "data": "4DT12H30M5S", - "valid": false - }, { "description": "no elements present", "data": "P", diff --git a/tests/draft2019-09/optional/format/hostname.json b/tests/draft2019-09/optional/format/hostname.json index 24bfdfc5a..f3b7181c8 100644 --- a/tests/draft2019-09/optional/format/hostname.json +++ b/tests/draft2019-09/optional/format/hostname.json @@ -120,16 +120,6 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - }, - { - "description": "single dot", - "data": ".", - "valid": false } ] } diff --git a/tests/draft2019-09/optional/format/idn-hostname.json b/tests/draft2019-09/optional/format/idn-hostname.json index 348c504c8..72f179751 100644 --- a/tests/draft2019-09/optional/format/idn-hostname.json +++ b/tests/draft2019-09/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0628\u0660\u06f0", + "data": "\u0660\u06f0", "valid": false }, { @@ -301,88 +301,6 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true - }, - { - "description": "single label", - "data": "hostname", - "valid": true - }, - { - "description": "single label with hyphen", - "data": "host-name", - "valid": true - }, - { - "description": "single label with digits", - "data": "h0stn4me", - "valid": true - }, - { - "description": "single label starting with digit", - "data": "1host", - "valid": true - }, - { - "description": "single label ending with digit", - "data": "hostnam3", - "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - } - ] - }, - { - "description": "validation of separators in internationalized host names", - "specification": [ - {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} - ], - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "format": "idn-hostname" - }, - "tests": [ - { - "description": "single dot", - "data": ".", - "valid": false - }, - { - "description": "single ideographic full stop", - "data": "\u3002", - "valid": false - }, - { - "description": "single fullwidth full stop", - "data": "\uff0e", - "valid": false - }, - { - "description": "single halfwidth ideographic full stop", - "data": "\uff61", - "valid": false - }, - { - "description": "dot as label separator", - "data": "a.b", - "valid": true - }, - { - "description": "ideographic full stop as label separator", - "data": "a\u3002b", - "valid": true - }, - { - "description": "fullwidth full stop as label separator", - "data": "a\uff0eb", - "valid": true - }, - { - "description": "halfwidth ideographic full stop as label separator", - "data": "a\uff61b", - "valid": true } ] } diff --git a/tests/draft2019-09/optional/format/ipv4.json b/tests/draft2019-09/optional/format/ipv4.json index efe42471b..ac1e14c68 100644 --- a/tests/draft2019-09/optional/format/ipv4.json +++ b/tests/draft2019-09/optional/format/ipv4.json @@ -81,11 +81,6 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false - }, - { - "description": "netmask is not a part of ipv4 address", - "data": "192.168.1.0/24", - "valid": false } ] } diff --git a/tests/draft2019-09/optional/id.json b/tests/draft2019-09/optional/id.json deleted file mode 100644 index 4daa8f51f..000000000 --- a/tests/draft2019-09/optional/id.json +++ /dev/null @@ -1,53 +0,0 @@ -[ - { - "description": "$id inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $id buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "id_in_enum": { - "enum": [ - { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "null" - } - ] - }, - "real_id_in_schema": { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "string" - }, - "zzz_id_in_const": { - "const": { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "https://localhost:1234/draft2019-09/id/my_identifier.json" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "null" - }, - "valid": true - }, - { - "description": "match $ref to $id", - "data": "a string to match #/$defs/id_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $id", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft2019-09/optional/refOfUnknownKeyword.json b/tests/draft2019-09/optional/refOfUnknownKeyword.json index e9a75dd1e..eee1c33ed 100644 --- a/tests/draft2019-09/optional/refOfUnknownKeyword.json +++ b/tests/draft2019-09/optional/refOfUnknownKeyword.json @@ -42,28 +42,5 @@ "valid": false } ] - }, - { - "description": "reference internals of known non-applicator", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "/base", - "examples": [ - { "type": "string" } - ], - "$ref": "#/examples/0" - }, - "tests": [ - { - "description": "match", - "data": "a string", - "valid": true - }, - { - "description": "mismatch", - "data": 42, - "valid": false - } - ] } ] diff --git a/tests/draft2019-09/propertyNames.json b/tests/draft2019-09/propertyNames.json index 3b2bb23bb..b7fecbf71 100644 --- a/tests/draft2019-09/propertyNames.json +++ b/tests/draft2019-09/propertyNames.json @@ -111,58 +111,5 @@ "valid": true } ] - }, - { - "description": "propertyNames with const", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "propertyNames": {"const": "foo"} - }, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"bar": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] - }, - { - "description": "propertyNames with enum", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "propertyNames": {"enum": ["foo", "bar"]} - }, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with property foo and bar is valid", - "data": {"foo": 1, "bar": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"baz": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] } ] diff --git a/tests/draft2019-09/ref.json b/tests/draft2019-09/ref.json index eff5305c3..7d850414d 100644 --- a/tests/draft2019-09/ref.json +++ b/tests/draft2019-09/ref.json @@ -791,6 +791,21 @@ } ] }, + { + "description": "URN base URI with f-component", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$comment": "RFC 8141 §2.3.3, but we don't allow fragments", + "$ref": "https://json-schema.org/draft/2019-09/schema" + }, + "tests": [ + { + "description": "is invalid", + "data": {"$id": "urn:example:foo-bar-baz-qux#somepart"}, + "valid": false + } + ] + }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { @@ -847,7 +862,6 @@ { "description": "URN ref with nested pointer ref", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { @@ -873,7 +887,6 @@ { "description": "ref to if", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", @@ -896,7 +909,6 @@ { "description": "ref to then", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", @@ -919,7 +931,6 @@ { "description": "ref to else", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", @@ -942,7 +953,6 @@ { "description": "ref with absolute-path-reference", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { @@ -972,7 +982,6 @@ { "description": "$id with file URI still resolves pointers - *nix", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { @@ -997,7 +1006,6 @@ { "description": "$id with file URI still resolves pointers - windows", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { @@ -1022,7 +1030,6 @@ { "description": "empty tokens in $ref json-pointer", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "": { "$defs": { @@ -1048,43 +1055,5 @@ "valid": false } ] - }, - { - "description": "$ref with $recursiveAnchor", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://example.com/schemas/unevaluated-items-are-disallowed", - "$ref": "/schemas/unevaluated-items-are-allowed", - "$recursiveAnchor": true, - "unevaluatedItems": false, - "$defs": { - "/schemas/unevaluated-items-are-allowed": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "/schemas/unevaluated-items-are-allowed", - "$recursiveAnchor": true, - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#" - } - ] - } - } - }, - "tests": [ - { - "description": "extra items allowed for inner arrays", - "data" : ["foo",["bar" , [] , 8]], - "valid": true - }, - { - "description": "extra items disallowed for root", - "data" : ["foo",["bar" , [] , 8], 8], - "valid": false - } - ] - } + } ] diff --git a/tests/draft2019-09/refRemote.json b/tests/draft2019-09/refRemote.json index 072894cf2..0bacbfc2e 100644 --- a/tests/draft2019-09/refRemote.json +++ b/tests/draft2019-09/refRemote.json @@ -22,7 +22,7 @@ "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "http://localhost:1234/draft2019-09/subSchemas.json#/$defs/integer" + "$ref": "http://localhost:1234/draft2019-09/subSchemas-defs.json#/$defs/integer" }, "tests": [ { @@ -60,7 +60,7 @@ "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "http://localhost:1234/draft2019-09/subSchemas.json#/$defs/refToInteger" + "$ref": "http://localhost:1234/draft2019-09/subSchemas-defs.json#/$defs/refToInteger" }, "tests": [ { @@ -265,10 +265,7 @@ }, { "description": "remote HTTP ref with different $id", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "http://localhost:1234/different-id-ref-string.json" - }, + "schema": {"$ref": "http://localhost:1234/different-id-ref-string.json"}, "tests": [ { "description": "number is invalid", @@ -284,10 +281,7 @@ }, { "description": "remote HTTP ref with different URN $id", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "http://localhost:1234/urn-ref-string.json" - }, + "schema": {"$ref": "http://localhost:1234/urn-ref-string.json"}, "tests": [ { "description": "number is invalid", @@ -303,10 +297,7 @@ }, { "description": "remote HTTP ref with nested absolute ref", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" - }, + "schema": {"$ref": "http://localhost:1234/nested-absolute-ref-to-string.json"}, "tests": [ { "description": "number is invalid", @@ -323,7 +314,6 @@ { "description": "$ref to $ref finds detached $anchor", "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/detached-ref.json#/$defs/foo" }, "tests": [ diff --git a/tests/draft2019-09/unevaluatedItems.json b/tests/draft2019-09/unevaluatedItems.json index 8e2ee4b11..53565a0b9 100644 --- a/tests/draft2019-09/unevaluatedItems.json +++ b/tests/draft2019-09/unevaluatedItems.json @@ -480,82 +480,6 @@ } ] }, - { - "description": "unevaluatedItems before $ref", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "unevaluatedItems": false, - "items": [ - { "type": "string" } - ], - "$ref": "#/$defs/bar", - "$defs": { - "bar": { - "items": [ - true, - { "type": "string" } - ] - } - } - }, - "tests": [ - { - "description": "with no unevaluated items", - "data": ["foo", "bar"], - "valid": true - }, - { - "description": "with unevaluated items", - "data": ["foo", "bar", "baz"], - "valid": false - } - ] - }, - { - "description": "unevaluatedItems with $recursiveRef", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://example.com/unevaluated-items-with-recursive-ref/extended-tree", - - "$recursiveAnchor": true, - - "$ref": "./tree", - "items": [ - true, - true, - { "type": "string" } - ], - - "$defs": { - "tree": { - "$id": "./tree", - "$recursiveAnchor": true, - - "type": "array", - "items": [ - { "type": "number" }, - { - "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", - "unevaluatedItems": false, - "$recursiveRef": "#" - } - ] - } - } - }, - "tests": [ - { - "description": "with no unevaluated items", - "data": [1, [2, [], "b"], "a"], - "valid": true - }, - { - "description": "with unevaluated items", - "data": [1, [2, [], "b", "too many"], "a"], - "valid": false - } - ] - }, { "description": "unevaluatedItems can't see inside cousins", "schema": { diff --git a/tests/draft2019-09/unevaluatedProperties.json b/tests/draft2019-09/unevaluatedProperties.json index e8765112c..a6cce8bb6 100644 --- a/tests/draft2019-09/unevaluatedProperties.json +++ b/tests/draft2019-09/unevaluatedProperties.json @@ -715,102 +715,6 @@ } ] }, - { - "description": "unevaluatedProperties before $ref", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "type": "object", - "unevaluatedProperties": false, - "properties": { - "foo": { "type": "string" } - }, - "$ref": "#/$defs/bar", - "$defs": { - "bar": { - "properties": { - "bar": { "type": "string" } - } - } - } - }, - "tests": [ - { - "description": "with no unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar" - }, - "valid": true - }, - { - "description": "with unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar", - "baz": "baz" - }, - "valid": false - } - ] - }, - { - "description": "unevaluatedProperties with $recursiveRef", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$id": "https://example.com/unevaluated-properties-with-recursive-ref/extended-tree", - - "$recursiveAnchor": true, - - "$ref": "./tree", - "properties": { - "name": { "type": "string" } - }, - - "$defs": { - "tree": { - "$id": "./tree", - "$recursiveAnchor": true, - - "type": "object", - "properties": { - "node": true, - "branches": { - "$comment": "unevaluatedProperties comes first so it's more likely to bugs errors with implementations that are sensitive to keyword ordering", - "unevaluatedProperties": false, - "$recursiveRef": "#" - } - }, - "required": ["node"] - } - } - }, - "tests": [ - { - "description": "with no unevaluated properties", - "data": { - "name": "a", - "node": 1, - "branches": { - "name": "b", - "node": 2 - } - }, - "valid": true - }, - { - "description": "with unevaluated properties", - "data": { - "name": "a", - "node": 1, - "branches": { - "foo": "b", - "node": 2 - } - }, - "valid": false - } - ] - }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { @@ -1567,38 +1471,5 @@ "valid": false } ] - }, - { - "description": "dependentSchemas with unevaluatedProperties", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "properties": {"foo2": {}}, - "dependentSchemas": { - "foo" : {}, - "foo2": { - "properties": { - "bar":{} - } - } - }, - "unevaluatedProperties": false - }, - "tests": [ - { - "description": "unevaluatedProperties doesn't consider dependentSchemas", - "data": {"foo": ""}, - "valid": false - }, - { - "description": "unevaluatedProperties doesn't see bar when foo2 is absent", - "data": {"bar": ""}, - "valid": false - }, - { - "description": "unevaluatedProperties sees bar when foo2 is present", - "data": { "foo2": "", "bar": ""}, - "valid": true - } - ] } ] diff --git a/tests/draft2019-09/optional/unknownKeyword.json b/tests/draft2019-09/unknownKeyword.json similarity index 100% rename from tests/draft2019-09/optional/unknownKeyword.json rename to tests/draft2019-09/unknownKeyword.json diff --git a/tests/draft2020-12/additionalProperties.json b/tests/draft2020-12/additionalProperties.json index 9618575e2..29e69c135 100644 --- a/tests/draft2020-12/additionalProperties.json +++ b/tests/draft2020-12/additionalProperties.json @@ -2,7 +2,6 @@ { "description": "additionalProperties being false does not allow other properties", - "specification": [ { "core":"10.3.2.3", "quote": "The value of \"additionalProperties\" MUST be a valid JSON Schema. Boolean \"false\" forbids everything." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}}, @@ -44,7 +43,6 @@ }, { "description": "non-ASCII pattern with additionalProperties", - "specification": [ { "core":"10.3.2.3"} ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": {"^á": {}}, @@ -65,7 +63,6 @@ }, { "description": "additionalProperties with schema", - "specification": [ { "core":"10.3.2.3", "quote": "The value of \"additionalProperties\" MUST be a valid JSON Schema." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}}, @@ -90,8 +87,8 @@ ] }, { - "description": "additionalProperties can exist by itself", - "specification": [ { "core":"10.3.2.3", "quote": "With no other applicator applying to object instances. This validates all the instance values irrespective of their property names" } ], + "description": + "additionalProperties can exist by itself", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": {"type": "boolean"} @@ -111,7 +108,6 @@ }, { "description": "additionalProperties are allowed by default", - "specification": [ { "core":"10.3.2.3", "quote": "Omitting this keyword has the same assertion behavior as an empty schema." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}} @@ -126,7 +122,6 @@ }, { "description": "additionalProperties does not look in applicators", - "specification":[ { "core": "10.2", "quote": "Subschemas of applicator keywords evaluate the instance completely independently such that the results of one such subschema MUST NOT impact the results of sibling subschemas." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ @@ -144,7 +139,6 @@ }, { "description": "additionalProperties with null valued instance properties", - "specification": [ { "core":"10.3.2.3" } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": { @@ -158,62 +152,5 @@ "valid": true } ] - }, - { - "description": "additionalProperties with propertyNames", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "propertyNames": { - "maxLength": 5 - }, - "additionalProperties": { - "type": "number" - } - }, - "tests": [ - { - "description": "Valid against both keywords", - "data": { "apple": 4 }, - "valid": true - }, - { - "description": "Valid against propertyNames, but not additionalProperties", - "data": { "fig": 2, "pear": "available" }, - "valid": false - } - ] - }, - { - "description": "dependentSchemas with additionalProperties", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": {"foo2": {}}, - "dependentSchemas": { - "foo" : {}, - "foo2": { - "properties": { - "bar": {} - } - } - }, - "additionalProperties": false - }, - "tests": [ - { - "description": "additionalProperties doesn't consider dependentSchemas", - "data": {"foo": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see bar", - "data": {"bar": ""}, - "valid": false - }, - { - "description": "additionalProperties can't see bar even when foo2 is present", - "data": {"foo2": "", "bar": ""}, - "valid": false - } - ] } ] diff --git a/tests/draft2020-12/anchor.json b/tests/draft2020-12/anchor.json index 99143fa11..423835dac 100644 --- a/tests/draft2020-12/anchor.json +++ b/tests/draft2020-12/anchor.json @@ -81,6 +81,64 @@ } ] }, + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + }, { "description": "same $anchor with different base uri", "schema": { @@ -116,5 +174,62 @@ "valid": false } ] + }, + { + "description": "non-schema object containing an $anchor property", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "const_not_anchor": { + "const": { + "$anchor": "not_a_real_anchor" + } + } + }, + "if": { + "const": "skip not_a_real_anchor" + }, + "then": true, + "else" : { + "$ref": "#/$defs/const_not_anchor" + } + }, + "tests": [ + { + "description": "skip traversing definition for a valid result", + "data": "skip not_a_real_anchor", + "valid": true + }, + { + "description": "const at const_not_anchor does not match", + "data": 1, + "valid": false + } + ] + }, + { + "description": "invalid anchors", + "comment": "Section 8.2.2", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "MUST start with a letter (and not #)", + "data": { "$anchor" : "#foo" }, + "valid": false + }, + { + "description": "JSON pointers are not valid", + "data": { "$anchor" : "/a/b" }, + "valid": false + }, + { + "description": "invalid with valid beginning", + "data": { "$anchor" : "foo#something" }, + "valid": false + } + ] } ] diff --git a/tests/draft2020-12/dependentSchemas.json b/tests/draft2020-12/dependentSchemas.json index 1c5f0574a..66ac0eb43 100644 --- a/tests/draft2020-12/dependentSchemas.json +++ b/tests/draft2020-12/dependentSchemas.json @@ -132,7 +132,6 @@ { "description": "dependent subschema incompatible with root", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {} }, diff --git a/tests/draft2020-12/dynamicRef.json b/tests/draft2020-12/dynamicRef.json index ffa211ba2..c1c56cb8a 100644 --- a/tests/draft2020-12/dynamicRef.json +++ b/tests/draft2020-12/dynamicRef.json @@ -726,90 +726,5 @@ "valid": false } ] - }, - { - "description": "$dynamicRef points to a boolean schema", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "true": true, - "false": false - }, - "properties": { - "true": { - "$dynamicRef": "#/$defs/true" - }, - "false": { - "$dynamicRef": "#/$defs/false" - } - } - }, - "tests": [ - { - "description": "follow $dynamicRef to a true schema", - "data": { "true": 1 }, - "valid": true - }, - { - "description": "follow $dynamicRef to a false schema", - "data": { "false": 1 }, - "valid": false - } - ] - }, - { - "description": "$dynamicRef skips over intermediate resources - direct reference", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/main", - "type": "object", - "properties": { - "bar-item": { - "$ref": "item" - } - }, - "$defs": { - "bar": { - "$id": "bar", - "type": "array", - "items": { - "$ref": "item" - }, - "$defs": { - "item": { - "$id": "item", - "type": "object", - "properties": { - "content": { - "$dynamicRef": "#content" - } - }, - "$defs": { - "defaultContent": { - "$dynamicAnchor": "content", - "type": "integer" - } - } - }, - "content": { - "$dynamicAnchor": "content", - "type": "string" - } - } - } - } - }, - "tests": [ - { - "description": "integer property passes", - "data": { "bar-item": { "content": 42 } }, - "valid": true - }, - { - "description": "string property fails", - "data": { "bar-item": { "content": "value" } }, - "valid": false - } - ] } ] diff --git a/tests/draft2020-12/enum.json b/tests/draft2020-12/enum.json index c8f35eacf..0d780b2ac 100644 --- a/tests/draft2020-12/enum.json +++ b/tests/draft2020-12/enum.json @@ -168,30 +168,6 @@ } ] }, - { - "description": "enum with [false] does not match [0]", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "enum": [[false]] - }, - "tests": [ - { - "description": "[false] is valid", - "data": [false], - "valid": true - }, - { - "description": "[0] is invalid", - "data": [0], - "valid": false - }, - { - "description": "[0.0] is invalid", - "data": [0.0], - "valid": false - } - ] - }, { "description": "enum with true does not match 1", "schema": { @@ -216,30 +192,6 @@ } ] }, - { - "description": "enum with [true] does not match [1]", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "enum": [[true]] - }, - "tests": [ - { - "description": "[true] is valid", - "data": [true], - "valid": true - }, - { - "description": "[1] is invalid", - "data": [1], - "valid": false - }, - { - "description": "[1.0] is invalid", - "data": [1.0], - "valid": false - } - ] - }, { "description": "enum with 0 does not match false", "schema": { @@ -264,30 +216,6 @@ } ] }, - { - "description": "enum with [0] does not match [false]", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "enum": [[0]] - }, - "tests": [ - { - "description": "[false] is invalid", - "data": [false], - "valid": false - }, - { - "description": "[0] is valid", - "data": [0], - "valid": true - }, - { - "description": "[0.0] is valid", - "data": [0.0], - "valid": true - } - ] - }, { "description": "enum with 1 does not match true", "schema": { @@ -312,30 +240,6 @@ } ] }, - { - "description": "enum with [1] does not match [true]", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "enum": [[1]] - }, - "tests": [ - { - "description": "[true] is invalid", - "data": [true], - "valid": false - }, - { - "description": "[1] is valid", - "data": [1], - "valid": true - }, - { - "description": "[1.0] is valid", - "data": [1.0], - "valid": true - } - ] - }, { "description": "nul characters in strings", "schema": { diff --git a/tests/draft2020-12/id.json b/tests/draft2020-12/id.json new file mode 100644 index 000000000..0ae5fe68a --- /dev/null +++ b/tests/draft2020-12/id.json @@ -0,0 +1,294 @@ +[ + { + "description": "Invalid use of fragments in location-independent $id", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Identifier name", + "data": { + "$ref": "#foo", + "$defs": { + "A": { + "$id": "#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name and no ref", + "data": { + "$defs": { + "A": { "$id": "#foo" } + } + }, + "valid": false + }, + { + "description": "Identifier path", + "data": { + "$ref": "#/a/b", + "$defs": { + "A": { + "$id": "#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft2020-12/bar#foo", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2020-12/bar#foo", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier path with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft2020-12/bar#/a/b", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2020-12/bar#/a/b", + "type": "integer" + } + } + }, + "valid": false + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft2020-12/root", + "$ref": "http://localhost:1234/draft2020-12/nested.json#foo", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#foo", + "type": "integer" + } + } + } + } + }, + "valid": false + }, + { + "description": "Identifier path with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft2020-12/root", + "$ref": "http://localhost:1234/draft2020-12/nested.json#/a/b", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#/a/b", + "type": "integer" + } + } + } + } + }, + "valid": false + } + ] + }, + { + "description": "Valid use of empty fragments in location-independent $id", + "comment": "These are allowed but discouraged", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Identifier name with absolute URI", + "data": { + "$ref": "http://localhost:1234/draft2020-12/bar", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2020-12/bar#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Identifier name with base URI change in subschema", + "data": { + "$id": "http://localhost:1234/draft2020-12/root", + "$ref": "http://localhost:1234/draft2020-12/nested.json#/$defs/B", + "$defs": { + "A": { + "$id": "nested.json", + "$defs": { + "B": { + "$id": "#", + "type": "integer" + } + } + } + } + }, + "valid": true + } + ] + }, + { + "description": "Unnormalized $ids are allowed but discouraged", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "Unnormalized identifier", + "data": { + "$ref": "http://localhost:1234/draft2020-12/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment", + "data": { + "$ref": "http://localhost:1234/draft2020-12/foo/baz", + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + }, + { + "description": "Unnormalized identifier with empty fragment and no ref", + "data": { + "$defs": { + "A": { + "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz#", + "type": "integer" + } + } + }, + "valid": true + } + ] + }, + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/draft2020-12/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + }, + { + "description": "non-schema object containing an $id property", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "const_not_id": { + "const": { + "$id": "not_a_real_id" + } + } + }, + "if": { + "const": "skip not_a_real_id" + }, + "then": true, + "else" : { + "$ref": "#/$defs/const_not_id" + } + }, + "tests": [ + { + "description": "skip traversing definition for a valid result", + "data": "skip not_a_real_id", + "valid": true + }, + { + "description": "const at const_not_id does not match", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft2020-12/items.json b/tests/draft2020-12/items.json index 6a3e1cf26..1ef18bdd0 100644 --- a/tests/draft2020-12/items.json +++ b/tests/draft2020-12/items.json @@ -265,26 +265,6 @@ } ] }, - { - "description": "items with heterogeneous array", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "prefixItems": [{}], - "items": false - }, - "tests": [ - { - "description": "heterogeneous invalid instance", - "data": [ "foo", "bar", 37 ], - "valid": false - }, - { - "description": "valid instance", - "data": [ null ], - "valid": true - } - ] - }, { "description": "items with null instance elements", "schema": { diff --git a/tests/draft2020-12/maxLength.json b/tests/draft2020-12/maxLength.json index 7462726d7..b6eb03401 100644 --- a/tests/draft2020-12/maxLength.json +++ b/tests/draft2020-12/maxLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "two graphemes is long enough", + "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft2020-12/minLength.json b/tests/draft2020-12/minLength.json index 5076c5a92..e0930b6fb 100644 --- a/tests/draft2020-12/minLength.json +++ b/tests/draft2020-12/minLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "one grapheme is not long enough", + "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft2020-12/not.json b/tests/draft2020-12/not.json index d0f2b6e84..57e45ba39 100644 --- a/tests/draft2020-12/not.json +++ b/tests/draft2020-12/not.json @@ -97,173 +97,25 @@ ] }, { - "description": "forbid everything with empty schema", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "not": {} - }, - "tests": [ - { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", - "data": "foo", - "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false - } - ] - }, - { - "description": "forbid everything with boolean schema true", + "description": "not with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": true }, "tests": [ { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", + "description": "any value is invalid", "data": "foo", "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false } ] }, { - "description": "allow everything with boolean schema false", + "description": "not with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": false }, - "tests": [ - { - "description": "number is valid", - "data": 1, - "valid": true - }, - { - "description": "string is valid", - "data": "foo", - "valid": true - }, - { - "description": "boolean true is valid", - "data": true, - "valid": true - }, - { - "description": "boolean false is valid", - "data": false, - "valid": true - }, - { - "description": "null is valid", - "data": null, - "valid": true - }, - { - "description": "object is valid", - "data": {"foo": "bar"}, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "array is valid", - "data": ["foo"], - "valid": true - }, - { - "description": "empty array is valid", - "data": [], - "valid": true - } - ] - }, - { - "description": "double negation", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "not": { "not": {} } - }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft2020-12/oneOf.json b/tests/draft2020-12/oneOf.json index 7a7c7ffe3..416c8e570 100644 --- a/tests/draft2020-12/oneOf.json +++ b/tests/draft2020-12/oneOf.json @@ -220,7 +220,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", diff --git a/tests/draft2020-12/optional/anchor.json b/tests/draft2020-12/optional/anchor.json deleted file mode 100644 index 6d6713be5..000000000 --- a/tests/draft2020-12/optional/anchor.json +++ /dev/null @@ -1,60 +0,0 @@ -[ - { - "description": "$anchor inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $anchor buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "anchor_in_enum": { - "enum": [ - { - "$anchor": "my_anchor", - "type": "null" - } - ] - }, - "real_identifier_in_schema": { - "$anchor": "my_anchor", - "type": "string" - }, - "zzz_anchor_in_const": { - "const": { - "$anchor": "my_anchor", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/anchor_in_enum" }, - { "$ref": "#my_anchor" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$anchor": "my_anchor", - "type": "null" - }, - "valid": true - }, - { - "description": "in implementations that strip $anchor, this may match either $def", - "data": { - "type": "null" - }, - "valid": false - }, - { - "description": "match $ref to $anchor", - "data": "a string to match #/$defs/anchor_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $anchor", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft2020-12/optional/dynamicRef.json b/tests/draft2020-12/optional/dynamicRef.json deleted file mode 100644 index 7e63f209a..000000000 --- a/tests/draft2020-12/optional/dynamicRef.json +++ /dev/null @@ -1,56 +0,0 @@ -[ - { - "description": "$dynamicRef skips over intermediate resources - pointer reference across resource boundary", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/optional/main", - "type": "object", - "properties": { - "bar-item": { - "$ref": "bar#/$defs/item" - } - }, - "$defs": { - "bar": { - "$id": "bar", - "type": "array", - "items": { - "$ref": "item" - }, - "$defs": { - "item": { - "$id": "item", - "type": "object", - "properties": { - "content": { - "$dynamicRef": "#content" - } - }, - "$defs": { - "defaultContent": { - "$dynamicAnchor": "content", - "type": "integer" - } - } - }, - "content": { - "$dynamicAnchor": "content", - "type": "string" - } - } - } - } - }, - "tests": [ - { - "description": "integer property passes", - "data": { "bar-item": { "content": 42 } }, - "valid": true - }, - { - "description": "string property fails", - "data": { "bar-item": { "content": "value" } }, - "valid": false - } - ] - }] \ No newline at end of file diff --git a/tests/draft2020-12/optional/ecmascript-regex.json b/tests/draft2020-12/optional/ecmascript-regex.json index a4d62e0cf..23b962e4b 100644 --- a/tests/draft2020-12/optional/ecmascript-regex.json +++ b/tests/draft2020-12/optional/ecmascript-regex.json @@ -405,6 +405,20 @@ } ] }, + { + "description": "\\a is not an ECMA 262 control escape", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "when used as a pattern", + "data": { "pattern": "\\a" }, + "valid": false + } + ] + }, { "description": "pattern with non-ASCII digits", "schema": { diff --git a/tests/draft2020-12/optional/format/duration.json b/tests/draft2020-12/optional/format/duration.json index a09fec5ef..a3af56ef0 100644 --- a/tests/draft2020-12/optional/format/duration.json +++ b/tests/draft2020-12/optional/format/duration.json @@ -46,11 +46,6 @@ "data": "PT1D", "valid": false }, - { - "description": "must start with P", - "data": "4DT12H30M5S", - "valid": false - }, { "description": "no elements present", "data": "P", diff --git a/tests/draft2020-12/optional/format/ecmascript-regex.json b/tests/draft2020-12/optional/format/ecmascript-regex.json deleted file mode 100644 index b0648084a..000000000 --- a/tests/draft2020-12/optional/format/ecmascript-regex.json +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - "description": "\\a is not an ECMA 262 control escape", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "format": "regex" - }, - "tests": [ - { - "description": "when used as a pattern", - "data": "\\a", - "valid": false - } - ] - } -] \ No newline at end of file diff --git a/tests/draft2020-12/optional/format/hostname.json b/tests/draft2020-12/optional/format/hostname.json index 57827c4d4..41418dd4a 100644 --- a/tests/draft2020-12/optional/format/hostname.json +++ b/tests/draft2020-12/optional/format/hostname.json @@ -120,16 +120,6 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - }, - { - "description": "single dot", - "data": ".", - "valid": false } ] } diff --git a/tests/draft2020-12/optional/format/idn-hostname.json b/tests/draft2020-12/optional/format/idn-hostname.json index f42ae969b..5549c0550 100644 --- a/tests/draft2020-12/optional/format/idn-hostname.json +++ b/tests/draft2020-12/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0628\u0660\u06f0", + "data": "\u0660\u06f0", "valid": false }, { @@ -301,88 +301,6 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true - }, - { - "description": "single label", - "data": "hostname", - "valid": true - }, - { - "description": "single label with hyphen", - "data": "host-name", - "valid": true - }, - { - "description": "single label with digits", - "data": "h0stn4me", - "valid": true - }, - { - "description": "single label starting with digit", - "data": "1host", - "valid": true - }, - { - "description": "single label ending with digit", - "data": "hostnam3", - "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - } - ] - }, - { - "description": "validation of separators in internationalized host names", - "specification": [ - {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} - ], - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "format": "idn-hostname" - }, - "tests": [ - { - "description": "single dot", - "data": ".", - "valid": false - }, - { - "description": "single ideographic full stop", - "data": "\u3002", - "valid": false - }, - { - "description": "single fullwidth full stop", - "data": "\uff0e", - "valid": false - }, - { - "description": "single halfwidth ideographic full stop", - "data": "\uff61", - "valid": false - }, - { - "description": "dot as label separator", - "data": "a.b", - "valid": true - }, - { - "description": "ideographic full stop as label separator", - "data": "a\u3002b", - "valid": true - }, - { - "description": "fullwidth full stop as label separator", - "data": "a\uff0eb", - "valid": true - }, - { - "description": "halfwidth ideographic full stop as label separator", - "data": "a\uff61b", - "valid": true } ] } diff --git a/tests/draft2020-12/optional/format/ipv4.json b/tests/draft2020-12/optional/format/ipv4.json index 86d27bdb7..c72b6fc22 100644 --- a/tests/draft2020-12/optional/format/ipv4.json +++ b/tests/draft2020-12/optional/format/ipv4.json @@ -81,11 +81,6 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false - }, - { - "description": "netmask is not a part of ipv4 address", - "data": "192.168.1.0/24", - "valid": false } ] } diff --git a/tests/draft2020-12/optional/id.json b/tests/draft2020-12/optional/id.json deleted file mode 100644 index 0b7df4e80..000000000 --- a/tests/draft2020-12/optional/id.json +++ /dev/null @@ -1,53 +0,0 @@ -[ - { - "description": "$id inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $id buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "id_in_enum": { - "enum": [ - { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "null" - } - ] - }, - "real_id_in_schema": { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "string" - }, - "zzz_id_in_const": { - "const": { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "https://localhost:1234/draft2020-12/id/my_identifier.json" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "null" - }, - "valid": true - }, - { - "description": "match $ref to $id", - "data": "a string to match #/$defs/id_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $id", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft2020-12/optional/refOfUnknownKeyword.json b/tests/draft2020-12/optional/refOfUnknownKeyword.json index c2b080a1e..f91c18884 100644 --- a/tests/draft2020-12/optional/refOfUnknownKeyword.json +++ b/tests/draft2020-12/optional/refOfUnknownKeyword.json @@ -42,28 +42,5 @@ "valid": false } ] - }, - { - "description": "reference internals of known non-applicator", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "/base", - "examples": [ - { "type": "string" } - ], - "$ref": "#/examples/0" - }, - "tests": [ - { - "description": "match", - "data": "a string", - "valid": true - }, - { - "description": "mismatch", - "data": 42, - "valid": false - } - ] } ] diff --git a/tests/draft2020-12/propertyNames.json b/tests/draft2020-12/propertyNames.json index b4780088a..7ecfb7ec3 100644 --- a/tests/draft2020-12/propertyNames.json +++ b/tests/draft2020-12/propertyNames.json @@ -44,36 +44,6 @@ } ] }, - { - "description": "propertyNames validation with pattern", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "propertyNames": { "pattern": "^a+$" } - }, - "tests": [ - { - "description": "matching property names valid", - "data": { - "a": {}, - "aa": {}, - "aaa": {} - }, - "valid": true - }, - { - "description": "non-matching property name is invalid", - "data": { - "aaA": {} - }, - "valid": false - }, - { - "description": "object without properties is valid", - "data": {}, - "valid": true - } - ] - }, { "description": "propertyNames with boolean schema true", "schema": { @@ -111,58 +81,5 @@ "valid": true } ] - }, - { - "description": "propertyNames with const", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "propertyNames": {"const": "foo"} - }, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"bar": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] - }, - { - "description": "propertyNames with enum", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "propertyNames": {"enum": ["foo", "bar"]} - }, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with property foo and bar is valid", - "data": {"foo": 1, "bar": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"baz": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] } ] diff --git a/tests/draft2020-12/ref.json b/tests/draft2020-12/ref.json index a1d3efaf7..5f6be8c20 100644 --- a/tests/draft2020-12/ref.json +++ b/tests/draft2020-12/ref.json @@ -791,6 +791,21 @@ } ] }, + { + "description": "URN base URI with f-component", + "schema": { + "$comment": "RFC 8141 §2.3.3, but we don't allow fragments", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "https://json-schema.org/draft/2020-12/schema" + }, + "tests": [ + { + "description": "is invalid", + "data": {"$id": "urn:example:foo-bar-baz-qux#somepart"}, + "valid": false + } + ] + }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { @@ -847,7 +862,6 @@ { "description": "URN ref with nested pointer ref", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { @@ -873,7 +887,6 @@ { "description": "ref to if", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", @@ -896,7 +909,6 @@ { "description": "ref to then", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", @@ -919,7 +931,6 @@ { "description": "ref to else", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", @@ -942,7 +953,6 @@ { "description": "ref with absolute-path-reference", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { @@ -972,7 +982,6 @@ { "description": "$id with file URI still resolves pointers - *nix", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { @@ -997,7 +1006,6 @@ { "description": "$id with file URI still resolves pointers - windows", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { @@ -1022,7 +1030,6 @@ { "description": "empty tokens in $ref json-pointer", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "": { "$defs": { diff --git a/tests/draft2020-12/refRemote.json b/tests/draft2020-12/refRemote.json index 047ac74ca..ea4177f0a 100644 --- a/tests/draft2020-12/refRemote.json +++ b/tests/draft2020-12/refRemote.json @@ -22,7 +22,7 @@ "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/integer" + "$ref": "http://localhost:1234/draft2020-12/subSchemas-defs.json#/$defs/integer" }, "tests": [ { @@ -60,7 +60,7 @@ "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/refToInteger" + "$ref": "http://localhost:1234/draft2020-12/subSchemas-defs.json#/$defs/refToInteger" }, "tests": [ { @@ -265,10 +265,7 @@ }, { "description": "remote HTTP ref with different $id", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "http://localhost:1234/different-id-ref-string.json" - }, + "schema": {"$ref": "http://localhost:1234/different-id-ref-string.json"}, "tests": [ { "description": "number is invalid", @@ -284,10 +281,7 @@ }, { "description": "remote HTTP ref with different URN $id", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "http://localhost:1234/urn-ref-string.json" - }, + "schema": {"$ref": "http://localhost:1234/urn-ref-string.json"}, "tests": [ { "description": "number is invalid", @@ -303,10 +297,7 @@ }, { "description": "remote HTTP ref with nested absolute ref", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" - }, + "schema": {"$ref": "http://localhost:1234/nested-absolute-ref-to-string.json"}, "tests": [ { "description": "number is invalid", @@ -323,7 +314,6 @@ { "description": "$ref to $ref finds detached $anchor", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/detached-ref.json#/$defs/foo" }, "tests": [ diff --git a/tests/draft2020-12/unevaluatedItems.json b/tests/draft2020-12/unevaluatedItems.json index f861cefad..2615c4c41 100644 --- a/tests/draft2020-12/unevaluatedItems.json +++ b/tests/draft2020-12/unevaluatedItems.json @@ -461,86 +461,6 @@ } ] }, - { - "description": "unevaluatedItems before $ref", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "unevaluatedItems": false, - "prefixItems": [ - { "type": "string" } - ], - "$ref": "#/$defs/bar", - "$defs": { - "bar": { - "prefixItems": [ - true, - { "type": "string" } - ] - } - } - }, - "tests": [ - { - "description": "with no unevaluated items", - "data": ["foo", "bar"], - "valid": true - }, - { - "description": "with unevaluated items", - "data": ["foo", "bar", "baz"], - "valid": false - } - ] - }, - { - "description": "unevaluatedItems with $dynamicRef", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://example.com/unevaluated-items-with-dynamic-ref/derived", - - "$ref": "./baseSchema", - - "$defs": { - "derived": { - "$dynamicAnchor": "addons", - "prefixItems": [ - true, - { "type": "string" } - ] - }, - "baseSchema": { - "$id": "./baseSchema", - - "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", - "unevaluatedItems": false, - "type": "array", - "prefixItems": [ - { "type": "string" } - ], - "$dynamicRef": "#addons", - - "$defs": { - "defaultAddons": { - "$comment": "Needed to satisfy the bookending requirement", - "$dynamicAnchor": "addons" - } - } - } - } - }, - "tests": [ - { - "description": "with no unevaluated items", - "data": ["foo", "bar"], - "valid": true - }, - { - "description": "with unevaluated items", - "data": ["foo", "bar", "baz"], - "valid": false - } - ] - }, { "description": "unevaluatedItems can't see inside cousins", "schema": { @@ -793,6 +713,7 @@ "data": [ "b" ], "valid": false } + ] } ] diff --git a/tests/draft2020-12/unevaluatedProperties.json b/tests/draft2020-12/unevaluatedProperties.json index ae29c9eb3..f7fb420ff 100644 --- a/tests/draft2020-12/unevaluatedProperties.json +++ b/tests/draft2020-12/unevaluatedProperties.json @@ -715,99 +715,6 @@ } ] }, - { - "description": "unevaluatedProperties before $ref", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "unevaluatedProperties": false, - "properties": { - "foo": { "type": "string" } - }, - "$ref": "#/$defs/bar", - "$defs": { - "bar": { - "properties": { - "bar": { "type": "string" } - } - } - } - }, - "tests": [ - { - "description": "with no unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar" - }, - "valid": true - }, - { - "description": "with unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar", - "baz": "baz" - }, - "valid": false - } - ] - }, - { - "description": "unevaluatedProperties with $dynamicRef", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://example.com/unevaluated-properties-with-dynamic-ref/derived", - - "$ref": "./baseSchema", - - "$defs": { - "derived": { - "$dynamicAnchor": "addons", - "properties": { - "bar": { "type": "string" } - } - }, - "baseSchema": { - "$id": "./baseSchema", - - "$comment": "unevaluatedProperties comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", - "unevaluatedProperties": false, - "type": "object", - "properties": { - "foo": { "type": "string" } - }, - "$dynamicRef": "#addons", - - "$defs": { - "defaultAddons": { - "$comment": "Needed to satisfy the bookending requirement", - "$dynamicAnchor": "addons" - } - } - } - } - }, - "tests": [ - { - "description": "with no unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar" - }, - "valid": true - }, - { - "description": "with unevaluated properties", - "data": { - "foo": "foo", - "bar": "bar", - "baz": "baz" - }, - "valid": false - } - ] - }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { @@ -1564,38 +1471,5 @@ "valid": false } ] - }, - { - "description": "dependentSchemas with unevaluatedProperties", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "properties": {"foo2": {}}, - "dependentSchemas": { - "foo" : {}, - "foo2": { - "properties": { - "bar":{} - } - } - }, - "unevaluatedProperties": false - }, - "tests": [ - { - "description": "unevaluatedProperties doesn't consider dependentSchemas", - "data": {"foo": ""}, - "valid": false - }, - { - "description": "unevaluatedProperties doesn't see bar when foo2 is absent", - "data": {"bar": ""}, - "valid": false - }, - { - "description": "unevaluatedProperties sees bar when foo2 is present", - "data": { "foo2": "", "bar": ""}, - "valid": true - } - ] } ] diff --git a/tests/draft2020-12/optional/unknownKeyword.json b/tests/draft2020-12/unknownKeyword.json similarity index 100% rename from tests/draft2020-12/optional/unknownKeyword.json rename to tests/draft2020-12/unknownKeyword.json diff --git a/tests/draft3/additionalItems.json b/tests/draft3/additionalItems.json index ab44a2eb3..0cb668701 100644 --- a/tests/draft3/additionalItems.json +++ b/tests/draft3/additionalItems.json @@ -110,25 +110,6 @@ } ] }, - { - "description": "additionalItems with heterogeneous array", - "schema": { - "items": [{}], - "additionalItems": false - }, - "tests": [ - { - "description": "heterogeneous invalid instance", - "data": [ "foo", "bar", 37 ], - "valid": false - }, - { - "description": "valid instance", - "data": [ null ], - "valid": true - } - ] - }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft3/maxLength.json b/tests/draft3/maxLength.json index b0a9ea5be..4de42bcab 100644 --- a/tests/draft3/maxLength.json +++ b/tests/draft3/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two graphemes is long enough", + "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft3/minLength.json b/tests/draft3/minLength.json index 6652c7509..3f09158de 100644 --- a/tests/draft3/minLength.json +++ b/tests/draft3/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one grapheme is not long enough", + "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft3/optional/format/ecmascript-regex.json b/tests/draft3/optional/ecmascript-regex.json similarity index 100% rename from tests/draft3/optional/format/ecmascript-regex.json rename to tests/draft3/optional/ecmascript-regex.json diff --git a/tests/draft3/optional/format/host-name.json b/tests/draft3/optional/format/host-name.json index 9a75c3c20..d418f3763 100644 --- a/tests/draft3/optional/format/host-name.json +++ b/tests/draft3/optional/format/host-name.json @@ -57,11 +57,6 @@ "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false - }, - { - "description": "empty string", - "data": "", - "valid": false } ] } diff --git a/tests/draft3/refRemote.json b/tests/draft3/refRemote.json index 81a6c5116..de0cb43a5 100644 --- a/tests/draft3/refRemote.json +++ b/tests/draft3/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" }, "tests": [ { diff --git a/tests/draft4/additionalItems.json b/tests/draft4/additionalItems.json index c9e681549..deb44fd31 100644 --- a/tests/draft4/additionalItems.json +++ b/tests/draft4/additionalItems.json @@ -146,25 +146,6 @@ } ] }, - { - "description": "additionalItems with heterogeneous array", - "schema": { - "items": [{}], - "additionalItems": false - }, - "tests": [ - { - "description": "heterogeneous invalid instance", - "data": [ "foo", "bar", 37 ], - "valid": false - }, - { - "description": "valid instance", - "data": [ null ], - "valid": true - } - ] - }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft4/enum.json b/tests/draft4/enum.json index ce43acc02..f085097be 100644 --- a/tests/draft4/enum.json +++ b/tests/draft4/enum.json @@ -154,27 +154,6 @@ } ] }, - { - "description": "enum with [false] does not match [0]", - "schema": {"enum": [[false]]}, - "tests": [ - { - "description": "[false] is valid", - "data": [false], - "valid": true - }, - { - "description": "[0] is invalid", - "data": [0], - "valid": false - }, - { - "description": "[0.0] is invalid", - "data": [0.0], - "valid": false - } - ] - }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, @@ -196,27 +175,6 @@ } ] }, - { - "description": "enum with [true] does not match [1]", - "schema": {"enum": [[true]]}, - "tests": [ - { - "description": "[true] is valid", - "data": [true], - "valid": true - }, - { - "description": "[1] is invalid", - "data": [1], - "valid": false - }, - { - "description": "[1.0] is invalid", - "data": [1.0], - "valid": false - } - ] - }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, @@ -238,27 +196,6 @@ } ] }, - { - "description": "enum with [0] does not match [false]", - "schema": {"enum": [[0]]}, - "tests": [ - { - "description": "[false] is invalid", - "data": [false], - "valid": false - }, - { - "description": "[0] is valid", - "data": [0], - "valid": true - }, - { - "description": "[0.0] is valid", - "data": [0.0], - "valid": true - } - ] - }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, @@ -280,27 +217,6 @@ } ] }, - { - "description": "enum with [1] does not match [true]", - "schema": {"enum": [[1]]}, - "tests": [ - { - "description": "[true] is invalid", - "data": [true], - "valid": false - }, - { - "description": "[1] is valid", - "data": [1], - "valid": true - }, - { - "description": "[1.0] is valid", - "data": [1.0], - "valid": true - } - ] - }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, diff --git a/tests/draft4/optional/id.json b/tests/draft4/id.json similarity index 100% rename from tests/draft4/optional/id.json rename to tests/draft4/id.json diff --git a/tests/draft4/maxLength.json b/tests/draft4/maxLength.json index 338795943..811d35b25 100644 --- a/tests/draft4/maxLength.json +++ b/tests/draft4/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two graphemes is long enough", + "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft4/minLength.json b/tests/draft4/minLength.json index 6652c7509..3f09158de 100644 --- a/tests/draft4/minLength.json +++ b/tests/draft4/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one grapheme is not long enough", + "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft4/not.json b/tests/draft4/not.json index 525219cf2..cbb7f46bf 100644 --- a/tests/draft4/not.json +++ b/tests/draft4/not.json @@ -91,67 +91,6 @@ "valid": true } ] - }, - { - "description": "forbid everything with empty schema", - "schema": { "not": {} }, - "tests": [ - { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", - "data": "foo", - "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false - } - ] - }, - { - "description": "double negation", - "schema": { "not": { "not": {} } }, - "tests": [ - { - "description": "any value is valid", - "data": "foo", - "valid": true - } - ] } + ] diff --git a/tests/draft4/oneOf.json b/tests/draft4/oneOf.json index 2487f0e38..fb63b0898 100644 --- a/tests/draft4/oneOf.json +++ b/tests/draft4/oneOf.json @@ -159,7 +159,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "oneOf": [ diff --git a/tests/draft4/optional/format/hostname.json b/tests/draft4/optional/format/hostname.json index 866a61788..a8ecd194f 100644 --- a/tests/draft4/optional/format/hostname.json +++ b/tests/draft4/optional/format/hostname.json @@ -112,16 +112,6 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - }, - { - "description": "single dot", - "data": ".", - "valid": false } ] } diff --git a/tests/draft4/optional/format/ipv4.json b/tests/draft4/optional/format/ipv4.json index 9680fe620..4706581f2 100644 --- a/tests/draft4/optional/format/ipv4.json +++ b/tests/draft4/optional/format/ipv4.json @@ -78,11 +78,6 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false - }, - { - "description": "netmask is not a part of ipv4 address", - "data": "192.168.1.0/24", - "valid": false } ] } diff --git a/tests/draft4/refRemote.json b/tests/draft4/refRemote.json index 65e45190c..412c9ff83 100644 --- a/tests/draft4/refRemote.json +++ b/tests/draft4/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "draft4/name.json#/definitions/orNull"} + "name": {"$ref": "name.json#/definitions/orNull"} } }, "tests": [ @@ -171,7 +171,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/draft4/locationIndependentIdentifier.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/locationIndependentIdentifierDraft4.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft6/additionalItems.json b/tests/draft6/additionalItems.json index 2c7d15582..cae72361c 100644 --- a/tests/draft6/additionalItems.json +++ b/tests/draft6/additionalItems.json @@ -169,25 +169,6 @@ } ] }, - { - "description": "additionalItems with heterogeneous array", - "schema": { - "items": [{}], - "additionalItems": false - }, - "tests": [ - { - "description": "heterogeneous invalid instance", - "data": [ "foo", "bar", 37 ], - "valid": false - }, - { - "description": "valid instance", - "data": [ null ], - "valid": true - } - ] - }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft6/enum.json b/tests/draft6/enum.json index ce43acc02..f085097be 100644 --- a/tests/draft6/enum.json +++ b/tests/draft6/enum.json @@ -154,27 +154,6 @@ } ] }, - { - "description": "enum with [false] does not match [0]", - "schema": {"enum": [[false]]}, - "tests": [ - { - "description": "[false] is valid", - "data": [false], - "valid": true - }, - { - "description": "[0] is invalid", - "data": [0], - "valid": false - }, - { - "description": "[0.0] is invalid", - "data": [0.0], - "valid": false - } - ] - }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, @@ -196,27 +175,6 @@ } ] }, - { - "description": "enum with [true] does not match [1]", - "schema": {"enum": [[true]]}, - "tests": [ - { - "description": "[true] is valid", - "data": [true], - "valid": true - }, - { - "description": "[1] is invalid", - "data": [1], - "valid": false - }, - { - "description": "[1.0] is invalid", - "data": [1.0], - "valid": false - } - ] - }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, @@ -238,27 +196,6 @@ } ] }, - { - "description": "enum with [0] does not match [false]", - "schema": {"enum": [[0]]}, - "tests": [ - { - "description": "[false] is invalid", - "data": [false], - "valid": false - }, - { - "description": "[0] is valid", - "data": [0], - "valid": true - }, - { - "description": "[0.0] is valid", - "data": [0.0], - "valid": true - } - ] - }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, @@ -280,27 +217,6 @@ } ] }, - { - "description": "enum with [1] does not match [true]", - "schema": {"enum": [[1]]}, - "tests": [ - { - "description": "[true] is invalid", - "data": [true], - "valid": false - }, - { - "description": "[1] is valid", - "data": [1], - "valid": true - }, - { - "description": "[1.0] is valid", - "data": [1.0], - "valid": true - } - ] - }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, diff --git a/tests/draft6/optional/id.json b/tests/draft6/id.json similarity index 100% rename from tests/draft6/optional/id.json rename to tests/draft6/id.json diff --git a/tests/draft6/maxLength.json b/tests/draft6/maxLength.json index be60c5407..748b4daaf 100644 --- a/tests/draft6/maxLength.json +++ b/tests/draft6/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two graphemes is long enough", + "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft6/minLength.json b/tests/draft6/minLength.json index 23c68fe3f..64db94805 100644 --- a/tests/draft6/minLength.json +++ b/tests/draft6/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one grapheme is not long enough", + "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft6/not.json b/tests/draft6/not.json index b46c4ed05..98de0eda8 100644 --- a/tests/draft6/not.json +++ b/tests/draft6/not.json @@ -93,161 +93,19 @@ ] }, { - "description": "forbid everything with empty schema", - "schema": { "not": {} }, + "description": "not with boolean schema true", + "schema": {"not": true}, "tests": [ { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", + "description": "any value is invalid", "data": "foo", "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false - } - ] - }, - { - "description": "forbid everything with boolean schema true", - "schema": { "not": true }, - "tests": [ - { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", - "data": "foo", - "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false - } - ] - }, - { - "description": "allow everything with boolean schema false", - "schema": { "not": false }, - "tests": [ - { - "description": "number is valid", - "data": 1, - "valid": true - }, - { - "description": "string is valid", - "data": "foo", - "valid": true - }, - { - "description": "boolean true is valid", - "data": true, - "valid": true - }, - { - "description": "boolean false is valid", - "data": false, - "valid": true - }, - { - "description": "null is valid", - "data": null, - "valid": true - }, - { - "description": "object is valid", - "data": {"foo": "bar"}, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "array is valid", - "data": ["foo"], - "valid": true - }, - { - "description": "empty array is valid", - "data": [], - "valid": true } ] }, { - "description": "double negation", - "schema": { "not": { "not": {} } }, + "description": "not with boolean schema false", + "schema": {"not": false}, "tests": [ { "description": "any value is valid", diff --git a/tests/draft6/oneOf.json b/tests/draft6/oneOf.json index c30a65c0d..eeb7ae866 100644 --- a/tests/draft6/oneOf.json +++ b/tests/draft6/oneOf.json @@ -203,7 +203,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "oneOf": [ diff --git a/tests/draft6/optional/format/hostname.json b/tests/draft6/optional/format/hostname.json index 866a61788..a8ecd194f 100644 --- a/tests/draft6/optional/format/hostname.json +++ b/tests/draft6/optional/format/hostname.json @@ -112,16 +112,6 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - }, - { - "description": "single dot", - "data": ".", - "valid": false } ] } diff --git a/tests/draft6/optional/format/ipv4.json b/tests/draft6/optional/format/ipv4.json index 9680fe620..4706581f2 100644 --- a/tests/draft6/optional/format/ipv4.json +++ b/tests/draft6/optional/format/ipv4.json @@ -78,11 +78,6 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false - }, - { - "description": "netmask is not a part of ipv4 address", - "data": "192.168.1.0/24", - "valid": false } ] } diff --git a/tests/draft6/propertyNames.json b/tests/draft6/propertyNames.json index 7c7b80006..f0788e649 100644 --- a/tests/draft6/propertyNames.json +++ b/tests/draft6/propertyNames.json @@ -103,52 +103,5 @@ "valid": true } ] - }, - { - "description": "propertyNames with const", - "schema": {"propertyNames": {"const": "foo"}}, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"bar": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] - }, - { - "description": "propertyNames with enum", - "schema": {"propertyNames": {"enum": ["foo", "bar"]}}, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with property foo and bar is valid", - "data": {"foo": 1, "bar": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"baz": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] } ] diff --git a/tests/draft6/refRemote.json b/tests/draft6/refRemote.json index 49ead6d1f..5d60fae11 100644 --- a/tests/draft6/refRemote.json +++ b/tests/draft6/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "$id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "draft6/name.json#/definitions/orNull"} + "name": {"$ref": "name.json#/definitions/orNull"} } }, "tests": [ @@ -173,7 +173,7 @@ "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ - { "$ref": "draft6/ref-and-definitions.json" } + { "$ref": "ref-and-definitions.json" } ] }, "tests": [ @@ -196,7 +196,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/draft6/locationIndependentIdentifier.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft6/optional/unknownKeyword.json b/tests/draft6/unknownKeyword.json similarity index 100% rename from tests/draft6/optional/unknownKeyword.json rename to tests/draft6/unknownKeyword.json diff --git a/tests/draft7/additionalItems.json b/tests/draft7/additionalItems.json index 2c7d15582..cae72361c 100644 --- a/tests/draft7/additionalItems.json +++ b/tests/draft7/additionalItems.json @@ -169,25 +169,6 @@ } ] }, - { - "description": "additionalItems with heterogeneous array", - "schema": { - "items": [{}], - "additionalItems": false - }, - "tests": [ - { - "description": "heterogeneous invalid instance", - "data": [ "foo", "bar", 37 ], - "valid": false - }, - { - "description": "valid instance", - "data": [ null ], - "valid": true - } - ] - }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft7/enum.json b/tests/draft7/enum.json index ce43acc02..f085097be 100644 --- a/tests/draft7/enum.json +++ b/tests/draft7/enum.json @@ -154,27 +154,6 @@ } ] }, - { - "description": "enum with [false] does not match [0]", - "schema": {"enum": [[false]]}, - "tests": [ - { - "description": "[false] is valid", - "data": [false], - "valid": true - }, - { - "description": "[0] is invalid", - "data": [0], - "valid": false - }, - { - "description": "[0.0] is invalid", - "data": [0.0], - "valid": false - } - ] - }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, @@ -196,27 +175,6 @@ } ] }, - { - "description": "enum with [true] does not match [1]", - "schema": {"enum": [[true]]}, - "tests": [ - { - "description": "[true] is valid", - "data": [true], - "valid": true - }, - { - "description": "[1] is invalid", - "data": [1], - "valid": false - }, - { - "description": "[1.0] is invalid", - "data": [1.0], - "valid": false - } - ] - }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, @@ -238,27 +196,6 @@ } ] }, - { - "description": "enum with [0] does not match [false]", - "schema": {"enum": [[0]]}, - "tests": [ - { - "description": "[false] is invalid", - "data": [false], - "valid": false - }, - { - "description": "[0] is valid", - "data": [0], - "valid": true - }, - { - "description": "[0.0] is valid", - "data": [0.0], - "valid": true - } - ] - }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, @@ -280,27 +217,6 @@ } ] }, - { - "description": "enum with [1] does not match [true]", - "schema": {"enum": [[1]]}, - "tests": [ - { - "description": "[true] is invalid", - "data": [true], - "valid": false - }, - { - "description": "[1] is valid", - "data": [1], - "valid": true - }, - { - "description": "[1.0] is valid", - "data": [1.0], - "valid": true - } - ] - }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, diff --git a/tests/draft7/optional/id.json b/tests/draft7/id.json similarity index 100% rename from tests/draft7/optional/id.json rename to tests/draft7/id.json diff --git a/tests/draft7/maxLength.json b/tests/draft7/maxLength.json index be60c5407..748b4daaf 100644 --- a/tests/draft7/maxLength.json +++ b/tests/draft7/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two graphemes is long enough", + "description": "two supplementary Unicode code points is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft7/minLength.json b/tests/draft7/minLength.json index 23c68fe3f..64db94805 100644 --- a/tests/draft7/minLength.json +++ b/tests/draft7/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one grapheme is not long enough", + "description": "one supplementary Unicode code point is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft7/not.json b/tests/draft7/not.json index b46c4ed05..98de0eda8 100644 --- a/tests/draft7/not.json +++ b/tests/draft7/not.json @@ -93,161 +93,19 @@ ] }, { - "description": "forbid everything with empty schema", - "schema": { "not": {} }, + "description": "not with boolean schema true", + "schema": {"not": true}, "tests": [ { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", + "description": "any value is invalid", "data": "foo", "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false - } - ] - }, - { - "description": "forbid everything with boolean schema true", - "schema": { "not": true }, - "tests": [ - { - "description": "number is invalid", - "data": 1, - "valid": false - }, - { - "description": "string is invalid", - "data": "foo", - "valid": false - }, - { - "description": "boolean true is invalid", - "data": true, - "valid": false - }, - { - "description": "boolean false is invalid", - "data": false, - "valid": false - }, - { - "description": "null is invalid", - "data": null, - "valid": false - }, - { - "description": "object is invalid", - "data": {"foo": "bar"}, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, - { - "description": "array is invalid", - "data": ["foo"], - "valid": false - }, - { - "description": "empty array is invalid", - "data": [], - "valid": false - } - ] - }, - { - "description": "allow everything with boolean schema false", - "schema": { "not": false }, - "tests": [ - { - "description": "number is valid", - "data": 1, - "valid": true - }, - { - "description": "string is valid", - "data": "foo", - "valid": true - }, - { - "description": "boolean true is valid", - "data": true, - "valid": true - }, - { - "description": "boolean false is valid", - "data": false, - "valid": true - }, - { - "description": "null is valid", - "data": null, - "valid": true - }, - { - "description": "object is valid", - "data": {"foo": "bar"}, - "valid": true - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - }, - { - "description": "array is valid", - "data": ["foo"], - "valid": true - }, - { - "description": "empty array is valid", - "data": [], - "valid": true } ] }, { - "description": "double negation", - "schema": { "not": { "not": {} } }, + "description": "not with boolean schema false", + "schema": {"not": false}, "tests": [ { "description": "any value is valid", diff --git a/tests/draft7/oneOf.json b/tests/draft7/oneOf.json index c30a65c0d..eeb7ae866 100644 --- a/tests/draft7/oneOf.json +++ b/tests/draft7/oneOf.json @@ -203,7 +203,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "oneOf": [ diff --git a/tests/draft7/optional/format/hostname.json b/tests/draft7/optional/format/hostname.json index 866a61788..a8ecd194f 100644 --- a/tests/draft7/optional/format/hostname.json +++ b/tests/draft7/optional/format/hostname.json @@ -112,16 +112,6 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - }, - { - "description": "single dot", - "data": ".", - "valid": false } ] } diff --git a/tests/draft7/optional/format/idn-hostname.json b/tests/draft7/optional/format/idn-hostname.json index 5c8cdc77b..6c8f86a3a 100644 --- a/tests/draft7/optional/format/idn-hostname.json +++ b/tests/draft7/optional/format/idn-hostname.json @@ -254,7 +254,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0628\u0660\u06f0", + "data": "\u0660\u06f0", "valid": false }, { @@ -298,80 +298,6 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true - }, - { - "description": "single label", - "data": "hostname", - "valid": true - }, - { - "description": "single label with hyphen", - "data": "host-name", - "valid": true - }, - { - "description": "single label with digits", - "data": "h0stn4me", - "valid": true - }, - { - "description": "single label ending with digit", - "data": "hostnam3", - "valid": true - }, - { - "description": "empty string", - "data": "", - "valid": false - } - ] - }, - { - "description": "validation of separators in internationalized host names", - "specification": [ - {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} - ], - "schema": { "format": "idn-hostname" }, - "tests": [ - { - "description": "single dot", - "data": ".", - "valid": false - }, - { - "description": "single ideographic full stop", - "data": "\u3002", - "valid": false - }, - { - "description": "single fullwidth full stop", - "data": "\uff0e", - "valid": false - }, - { - "description": "single halfwidth ideographic full stop", - "data": "\uff61", - "valid": false - }, - { - "description": "dot as label separator", - "data": "a.b", - "valid": true - }, - { - "description": "ideographic full stop as label separator", - "data": "a\u3002b", - "valid": true - }, - { - "description": "fullwidth full stop as label separator", - "data": "a\uff0eb", - "valid": true - }, - { - "description": "halfwidth ideographic full stop as label separator", - "data": "a\uff61b", - "valid": true } ] } diff --git a/tests/draft7/optional/format/ipv4.json b/tests/draft7/optional/format/ipv4.json index 9680fe620..4706581f2 100644 --- a/tests/draft7/optional/format/ipv4.json +++ b/tests/draft7/optional/format/ipv4.json @@ -78,11 +78,6 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false - }, - { - "description": "netmask is not a part of ipv4 address", - "data": "192.168.1.0/24", - "valid": false } ] } diff --git a/tests/draft7/propertyNames.json b/tests/draft7/propertyNames.json index 7c7b80006..f0788e649 100644 --- a/tests/draft7/propertyNames.json +++ b/tests/draft7/propertyNames.json @@ -103,52 +103,5 @@ "valid": true } ] - }, - { - "description": "propertyNames with const", - "schema": {"propertyNames": {"const": "foo"}}, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"bar": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] - }, - { - "description": "propertyNames with enum", - "schema": {"propertyNames": {"enum": ["foo", "bar"]}}, - "tests": [ - { - "description": "object with property foo is valid", - "data": {"foo": 1}, - "valid": true - }, - { - "description": "object with property foo and bar is valid", - "data": {"foo": 1, "bar": 1}, - "valid": true - }, - { - "description": "object with any other property is invalid", - "data": {"baz": 1}, - "valid": false - }, - { - "description": "empty object is valid", - "data": {}, - "valid": true - } - ] } ] diff --git a/tests/draft7/refRemote.json b/tests/draft7/refRemote.json index 450787af6..115e12e74 100644 --- a/tests/draft7/refRemote.json +++ b/tests/draft7/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/integer"}, + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "$id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "draft7/name.json#/definitions/orNull"} + "name": {"$ref": "name.json#/definitions/orNull"} } }, "tests": [ @@ -173,7 +173,7 @@ "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ - { "$ref": "draft7/ref-and-definitions.json" } + { "$ref": "ref-and-definitions.json" } ] }, "tests": [ @@ -196,7 +196,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/draft7/locationIndependentIdentifier.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft7/optional/unknownKeyword.json b/tests/draft7/unknownKeyword.json similarity index 100% rename from tests/draft7/optional/unknownKeyword.json rename to tests/draft7/unknownKeyword.json From e3bc2dcda731844a21b4b20633386f65efd9c3f3 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Tue, 29 Apr 2025 11:13:05 +0200 Subject: [PATCH 089/212] Adapt test case generation from suite --- jsonschema/tests/test_jsonschema_test_suite.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 41c982553..9ff067f33 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -136,7 +136,6 @@ def leap_second(test): DRAFT4.format_cases(), DRAFT4.optional_cases_of(name="bignum"), DRAFT4.optional_cases_of(name="float-overflow"), - DRAFT4.optional_cases_of(name="id"), DRAFT4.optional_cases_of(name="non-bmp-regex"), DRAFT4.optional_cases_of(name="zeroTerminatedFloats"), Validator=jsonschema.Draft4Validator, @@ -155,7 +154,6 @@ def leap_second(test): DRAFT6.format_cases(), DRAFT6.optional_cases_of(name="bignum"), DRAFT6.optional_cases_of(name="float-overflow"), - DRAFT6.optional_cases_of(name="id"), DRAFT6.optional_cases_of(name="non-bmp-regex"), Validator=jsonschema.Draft6Validator, format_checker=jsonschema.Draft6Validator.FORMAT_CHECKER, @@ -174,9 +172,7 @@ def leap_second(test): DRAFT7.optional_cases_of(name="bignum"), DRAFT7.optional_cases_of(name="cross-draft"), DRAFT7.optional_cases_of(name="float-overflow"), - DRAFT6.optional_cases_of(name="id"), DRAFT7.optional_cases_of(name="non-bmp-regex"), - DRAFT7.optional_cases_of(name="unknownKeyword"), Validator=jsonschema.Draft7Validator, format_checker=jsonschema.Draft7Validator.FORMAT_CHECKER, skip=lambda test: ( @@ -190,15 +186,12 @@ def leap_second(test): TestDraft201909 = DRAFT201909.to_unittest_testcase( DRAFT201909.cases(), - DRAFT201909.optional_cases_of(name="anchor"), DRAFT201909.optional_cases_of(name="bignum"), DRAFT201909.optional_cases_of(name="cross-draft"), DRAFT201909.optional_cases_of(name="float-overflow"), - DRAFT201909.optional_cases_of(name="id"), DRAFT201909.optional_cases_of(name="no-schema"), DRAFT201909.optional_cases_of(name="non-bmp-regex"), DRAFT201909.optional_cases_of(name="refOfUnknownKeyword"), - DRAFT201909.optional_cases_of(name="unknownKeyword"), Validator=jsonschema.Draft201909Validator, skip=skip( message="Vocabulary support is still in-progress.", @@ -227,15 +220,12 @@ def leap_second(test): TestDraft202012 = DRAFT202012.to_unittest_testcase( DRAFT202012.cases(), - DRAFT201909.optional_cases_of(name="anchor"), DRAFT202012.optional_cases_of(name="bignum"), DRAFT202012.optional_cases_of(name="cross-draft"), DRAFT202012.optional_cases_of(name="float-overflow"), - DRAFT202012.optional_cases_of(name="id"), DRAFT202012.optional_cases_of(name="no-schema"), DRAFT202012.optional_cases_of(name="non-bmp-regex"), DRAFT202012.optional_cases_of(name="refOfUnknownKeyword"), - DRAFT202012.optional_cases_of(name="unknownKeyword"), Validator=jsonschema.Draft202012Validator, skip=skip( message="Vocabulary support is still in-progress.", From 2b6d928692e6faf2a6b27c270b36c18cf4d9beca Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Tue, 29 Apr 2025 12:03:41 +0200 Subject: [PATCH 090/212] Revert "Add test for unevaluatedProperties" This reverts commit 75218a4c4632ecafa722724fd338dc3598625764. --- jsonschema/tests/test_validators.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 309229ee6..28cc40273 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -742,14 +742,6 @@ def test_unevaluated_properties_on_invalid_type(self): message = self.message_for(instance="foo", schema=schema) self.assertEqual(message, "'foo' is not of type 'object'") - def test_unevaluated_properties_with_additional_properties(self): - schema = { - "additionalProperties": {"type": "string"}, - "unevaluatedProperties": False, - } - validator = validators._LATEST_VERSION(schema) - validator.validate(instance={"foo": "foo"}) - def test_single_item(self): schema = {"prefixItems": [{}], "items": False} message = self.message_for( From 184d81e18e2b3ec2fa853914598b36324ef885d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 10:03:59 +0000 Subject: [PATCH 091/212] Bump astral-sh/setup-uv from 5 to 6 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 5 to 6. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/v5...v6) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2349b73a5..aa9e6f8a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@v6 with: enable-cache: true - id: noxenvs-matrix @@ -94,7 +94,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@v6 with: enable-cache: true @@ -117,7 +117,7 @@ jobs: with: fetch-depth: 0 - name: Set up uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@v6 with: enable-cache: true From 95138421caed135b7b480ac529435b8e780aabe6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 18:03:02 +0000 Subject: [PATCH 092/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.6 → v0.11.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.6...v0.11.8) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6e7a9acb3..985a60eef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.6" + rev: "v0.11.8" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From e68b54949f503c0f3c599da5b8b4d265ed9a6eb7 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Mon, 26 May 2025 11:12:55 +0200 Subject: [PATCH 093/212] Move is_valid function to module scope --- jsonschema/_utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 61defd303..84a0965e5 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -270,10 +270,6 @@ def find_evaluated_property_keys_by_schema(validator, instance, schema): return [] evaluated_keys = [] - def is_valid(errs_it): - """Whether there are no errors in the given iterator.""" - return next(errs_it, None) is None - ref = schema.get("$ref") if ref is not None: resolved = validator._resolver.lookup(ref) @@ -352,3 +348,8 @@ def is_valid(errs_it): ) return evaluated_keys + + +def is_valid(errs_it): + """Whether there are no errors in the given iterator.""" + return next(errs_it, None) is None From 56ee673df89298879feb9d7fc5737050d64bf94f Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Mon, 26 May 2025 11:32:11 +0200 Subject: [PATCH 094/212] Squashed 'json/' changes from ab3924a6..9ad349be 9ad349be Merge pull request #773 from jdesrosiers/annotation-propname-desc f164982c Merge pull request #771 from bavulapati/add-blaze-as-consumer d2bd2ad2 Update annotation test description for propertyNames a7a64707 Add [Blaze](https://github.com/sourcemeta/blaze) to the README 9f256c88 Change "expected" to an object with schema locations 7f996868 Update content tests to only apply to string instances 5338ecd1 Remove tests that assert a keyword doesn't emit annotations 738653b5 Make order of assertion properties consistent 8b5de3b9 Updates based on feedback from Juan 6270e399 Updates based on feedback from Karen 341df3ec Add automation to check that annotation tests are valid 16988c67 Add annotation tests bc919bdb Merge pull request #755 from V02460/unevaluated-additional-properties 83e866b4 Merge pull request #763 from michaelmior/propertynames-const c5a9703f Merge pull request #760 from OptimumCode/rfc3490-label-separator b4c09b65 Add tests for propertyNames with const/enum 4fa572d8 Move tests for rfc3490#3.1 into a separate test case ce9f68ca Add link to rfc and quote ad94cacc Add test cases for other valid label separators in IDN hostnames 39002ae7 Merge pull request #762 from OptimumCode/rfc-html-link c8780535 Correct section anchor for rfc URL template 5f2ca7d6 Modify rfc url template to use html version 9c5d99b6 Merge pull request #761 from OptimumCode/annotation-script-rfc-support 9563ce7b Correct rfc URL template - incorrect path pattern was used 961bfad0 Correct spec kind extraction from defined key. Continue on unkown URL kind e524505b Merge pull request #759 from sirosen/hostname-format-reject-single-dot 4a3efd18 Add negative tests for "." for hostname formats 4ba013d5 Merge pull request #747 from santhosh-tekuri/duration aa500e80 Merge pull request #749 from json-schema-org/gregsdennis/json-everything-update eb8ce976 Merge pull request #757 from ajevans99/main dcdae5c0 Merge pull request #758 from sirosen/hostname-format-check-empty-string db21d21b Merge branch 'main' into hostname-format-check-empty-string 3fd78f04 Merge pull request #1 from ajevans99/swift-json-schema 3cada3a9 Update README.md 5273e0d6 Make test descriptions more specific 43828fee Simplify adjacent additionalProperties test 347d6099 unevaluatedProperties: Remove type keywords 7dfbb1e9 Add test for unevaluatedProperties 82a07749 Merge pull request #753 from json-schema-org/ether/fix-draft-locations a66d23d4 move draft-specific files to the dedicated dir for its draft 8ef15501 Merge pull request #751 from big-andy-coates/format_tests_under_format fe1b1392 All format test cases should be under the `format` directory. b1ee90f6 json-everything moved to an org c00a3f94 test: duration format must start with P 9fc880bf Merge pull request #740 from notEthan/format-pattern-control-char cbd48ea5 Simplify test of \a regex character to test directly against `pattern` schema d6f1010a Merge pull request #746 from json-schema-org/annotations 4aec22c1 Revert the changes to additionalProperties.json. 2dc10671 Move the workflow step title. d9ce71ac May as well also show quotes in the annotation. 1b719a84 Pick the line after the description when attaching spec annotations. 08105151 Markdown is apparently not (yet?) supported in annotations. 81645773 Tidy up the specification annotator a bit. 38628b79 Make the spec URLs structure a bit easier for internal use. 4ebbeaf4 Merge branch 'Era-cell/main' e4bd7554 dumbness2 corrected d8ade402 inside run 57c7c869 changed install location 11f8e511 Added installing command in workflow f2766616 template library, url loads changes c2badb12 Merge pull request #734 from OptimumCode/idn-hostname-arabic-indic-mixed dd9599a5 Merge branch 'main' of github.com:json-schema-org/JSON-Schema-Test-Suite 5b393436 add pr dependencies action 3a509007 Clear existin annotations on same PR 23674123 Cases for rfc and iso written separately 0b780b2c Corected yaml format 2b1ffb74 Best practices followed with optimized code e88a2da6 Works for all OS 7b40efe4 Base path for neighbouring file? 564e6957 Walking through all leaf files 7b84fb44 Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-Suite 891d0265 First workflow2 1c175195 regex correction 96f7683a Final correction2 - file names beautufied 5f050a07 Final correction1 77527b63 Stupidity corrected eb8fd760 Branch name specified 540a269b Log2 f29d090a Wrong location sepcification 582e12be logging logs check df3bdecc path corrected c6b937ca Reading all jsons and spec urls added cbdd1755 change day2 54f3784a Merge pull request #731 from MeastroZI/main 79dc92f1 TOKEN ce52852d Python file location changed 3558c2c6 Fake add to tests eecc7b7a Merge branch 'main' of https://github.com/Era-cell/JSON-Schema-Test-Suite 810d148a First workflow2 4eac02c7 First workflow ff29264c Merge pull request #741 from harrel56/chore/tabs-to-spaces 9f39cf73 use spaces instead of tabs 2f3b5f7a Corrected replaced unevaluated with additoinalProperties 40bcb8b3 Corrected replaced unevaluated with additoinalProperties fa9224d7 Merge pull request #732 from MeastroZI/main2 83bedd5c Changing descriptions 49f73429 fixing tests e6d6a081 adding more test cases 7e6c9be6 changing descriptions 959aca92 shifting test 605d7d78 Update propertyDependencies.json : test must be tests deb82824 test for dependentSchema and propertyDependencies with unevaluatedProperties and additionalProperties ea485124 Merge branch 'json-schema-org:main' into main 64a3e7b3 Merge pull request #721 from json-schema-org/gregsdennis/dynamicref-skips-resources b9f14e64 Fix $schema in new new test 3d5048e8 Merge pull request #733 from Era-cell/main 4ae14268 Add valid first character to avoid Bidi rule violation 2480edba Update additionalProperties.json formatting it 6aa79c0b Update additionalProperties.json formatting it 3e0139a5 Update tests/draft-next/additionalProperties.json 616240b0 Update tests/draft-next/additionalProperties.json c5f3e4ea Update tests/draft2020-12/propertyNames.json 964efb8e propertyNames doesn't affect additionalProperties, tests exist already for unevaluatedProps f08b884c Cases go under additional and unevaluated Properties 99864ff6 added tests for propertyNames with additionalProperties/unevaluatedProperties, also with specification property 3b5782b6 Update ref.json : changing $Ids 546b3561 test for $ref with $recursiveAnchor 57617f25 Merge pull request #726 from Era-cell/main 51fc69cd meta data and property names constraints added, additional Items: string 9b169bed specification takes array of objects having section and quote 1362a8cc Pattern for para corrected 340116ec Schema of specification in much structured 003ac021 Test-schema including sub-schema for scpecification 50a20280 adding specification enhancement for additionalProperties 604f5f99 Drop tests of `$id` and `$anchor` that just test values against meta-schema `pattern` for those properties 9cd64ec9 come on man, save all the files f494440e use unique $id in optional tests, too 468453b0 use unique $id 9ec6d17e fix copy/paste error b284f423 add tests for $dynamicRef skipping over resources bf0360f4 add $recursiveAnchor to 2019-09 meta-schemas 0519d1f0 add $dynamicAnchor to meta-schemas b41167c7 Merge pull request #714 from json-schema-org/more-not 4221a55a Add tests for not: {} schemas for all values. c499d1d2 Merge pull request #713 from spacether/patch-1 24a471bd Update README.md 544f7c3d Merge pull request #712 from otto-ifak/main 9dad3ebe Add tests for enum with array of bool 589a0858 Merge pull request #706 from marksparkza/unevaluated-before-ref 64d5cab9 Merge pull request #710 from spacether/patch-1 418cdbd6 Removes idea folder e0a9e066 Updates all other tests to mention grapheme/graphemes 217bf81b Merge pull request #701 from json-schema-org/ether/dynamicRef-boolean 7a3d06d7 I remove a test that doesn't make sense. e8bf453d Move tests with ids in non-schemas to optional 69136952 Update minLength.json d545be21 Fix duplidate identifiers in recently added tests 4e9640c8 test when $dynamicRef references a boolean schema 3dab98ca Merge pull request #705 from json-schema-org/gregsdennis/remove-contains-objects-tests 1d3aa495 remove more maxContains 4a2c61e8 Test unevaluatedItems|Properties before $ref ec553d76 contains no longer applies to objects 0433a2bf Merge pull request #704 from big-andy-coates/clarify-format-requirements c685195f Merge pull request #703 from big-andy-coates/link-to-creek-validator-comprison-site a46174b0 Add more detail around test runner requirements for `format` tests bb1de8a9 The site linked to is a data-driven functional and performance benchmark of JVM based validator implementations. d38ddd54 Merge pull request #696 from jdesrosiers/unevaluated-dynamicref 5d0c05fa Fix copy/paste error 95fe6ca2 Merge pull request #694 from json-schema-org/heterogeneous-additionalItems 9c88a0be Merge pull request #697 from json-schema-org/gregsdennis/add-ref-into-known-nonapplicator 49222046 Add unevaluted with dynamic ref tests to draft-next 8ba1c90d Update unevaluted with dynamic ref to be more likely to catch errors fea2cf19 add tests for 2019 and 2020 6695ca38 add optional tests for `$ref`ing into known non-applicator keywords 2834c630 Add tests for unevaluated with dynamic reference cda4281c Merge pull request #695 from json-schema-org/ether/clean-up-subSchemas 7b9f45c2 move subSchemas-defs.json to subSchemas.json e41ec0ec remove unused definition files 349c5a82 Merge pull request #692 from json-schema-org/ether/fix-subSchemas-refs 451baca4 Merge pull request #670 from marksparkza/invalid-output-test b8da838a Add tests for heterogeneous arrays with additionalItems 6d7a44b7 fix subschema locations and their $refs a9a1e2e3 Merge pull request #690 from skryukov/add-ipv4-mask-test ba52c48a Merge pull request #689 from skryukov/add-schema-keyword-to-required-tests 69b53add Add a test case for ipv4 with netmask d0c602a7 Add $schema keyword to required tests 20f1f52c Merge pull request #688 from spacether/feat_updates_python_exp_impl b087b3ca Updates implmentation 4ecd01f3 Merge pull request #687 from swaeberle/check-single-label-idn-hostnames 732e7275 test single label IDN hostnames 202d5625 test: hostname format check fails on empty string ea0b63c9 Remove invalid output tests git-subtree-dir: json git-subtree-split: 9ad349be933f1e74810cb4fd3ad19780694dc77e --- .github/workflows/annotation-tests.yml | 21 + .github/workflows/pr-dependencies.yml | 12 + .../show_specification_annotations.yml | 21 + README.md | 17 +- annotations/README.md | 116 +++ annotations/assertion.schema.json | 24 + annotations/test-case.schema.json | 38 + annotations/test-suite.schema.json | 15 + annotations/test.schema.json | 16 + annotations/tests/applicators.json | 409 +++++++++++ annotations/tests/content.json | 121 ++++ annotations/tests/core.json | 30 + annotations/tests/format.json | 26 + annotations/tests/meta-data.json | 150 ++++ annotations/tests/unevaluated.json | 661 ++++++++++++++++++ annotations/tests/unknown.json | 27 + bin/annotate-specification-links | 140 ++++ bin/annotation-tests.ts | 31 + bin/specification_urls.json | 34 + output-tests/draft2019-09/content/type.json | 26 - output-tests/draft2020-12/content/type.json | 26 - .../draft-next/format-assertion-false.json | 1 + remotes/draft-next/format-assertion-true.json | 1 + .../draft-next/metaschema-no-validation.json | 1 + .../metaschema-optional-vocabulary.json | 1 + remotes/draft-next/subSchemas-defs.json | 11 - remotes/draft-next/subSchemas.json | 12 +- .../metaschema-no-validation.json | 1 + .../metaschema-optional-vocabulary.json | 1 + remotes/draft2019-09/subSchemas-defs.json | 11 - remotes/draft2019-09/subSchemas.json | 12 +- .../draft2020-12/format-assertion-false.json | 1 + .../draft2020-12/format-assertion-true.json | 1 + .../metaschema-no-validation.json | 1 + .../metaschema-optional-vocabulary.json | 1 + remotes/draft2020-12/subSchemas-defs.json | 11 - remotes/draft2020-12/subSchemas.json | 12 +- .../subSchemas.json} | 4 +- .../locationIndependentIdentifier.json} | 0 remotes/{ => draft4}/name.json | 0 remotes/draft4/subSchemas.json | 10 + .../locationIndependentIdentifier.json} | 0 remotes/draft6/name.json | 15 + remotes/{ => draft6}/ref-and-definitions.json | 2 +- remotes/draft6/subSchemas.json | 10 + .../draft7/locationIndependentIdentifier.json | 11 + remotes/draft7/name.json | 15 + remotes/draft7/ref-and-definitions.json | 11 + remotes/draft7/subSchemas.json | 10 + remotes/subSchemas.json | 8 - test-schema.json | 63 ++ tests/draft-next/additionalProperties.json | 92 +++ tests/draft-next/anchor.json | 114 --- tests/draft-next/contains.json | 104 +-- tests/draft-next/dependentSchemas.json | 1 + tests/draft-next/dynamicRef.json | 85 +++ tests/draft-next/enum.json | 96 +++ tests/draft-next/id.json | 294 -------- tests/draft-next/items.json | 20 + tests/draft-next/maxContains.json | 50 -- tests/draft-next/maxLength.json | 2 +- tests/draft-next/minLength.json | 2 +- tests/draft-next/oneOf.json | 2 +- tests/draft-next/optional/anchor.json | 60 ++ tests/draft-next/optional/dynamicRef.json | 56 ++ .../draft-next/optional/ecmascript-regex.json | 14 - .../draft-next/optional/format/duration.json | 5 + .../optional/format/ecmascript-regex.json | 16 + .../draft-next/optional/format/hostname.json | 10 + .../optional/format/idn-hostname.json | 84 ++- tests/draft-next/optional/format/ipv4.json | 5 + tests/draft-next/optional/id.json | 53 ++ .../optional/refOfUnknownKeyword.json | 23 + .../{ => optional}/unknownKeyword.json | 0 tests/draft-next/ref.json | 8 + tests/draft-next/refRemote.json | 20 +- tests/draft-next/unevaluatedItems.json | 73 ++ tests/draft-next/unevaluatedProperties.json | 206 ++++-- tests/draft2019-09/additionalItems.json | 20 + tests/draft2019-09/additionalProperties.json | 57 ++ tests/draft2019-09/anchor.json | 115 --- tests/draft2019-09/dependentSchemas.json | 1 + tests/draft2019-09/enum.json | 96 +++ tests/draft2019-09/id.json | 294 -------- tests/draft2019-09/maxLength.json | 2 +- tests/draft2019-09/minLength.json | 2 +- tests/draft2019-09/not.json | 154 +++- tests/draft2019-09/oneOf.json | 2 +- tests/draft2019-09/optional/anchor.json | 60 ++ .../optional/format/duration.json | 5 + .../optional/format/hostname.json | 10 + .../optional/format/idn-hostname.json | 84 ++- tests/draft2019-09/optional/format/ipv4.json | 5 + tests/draft2019-09/optional/id.json | 53 ++ .../optional/refOfUnknownKeyword.json | 23 + .../{ => optional}/unknownKeyword.json | 0 tests/draft2019-09/propertyNames.json | 53 ++ tests/draft2019-09/ref.json | 63 +- tests/draft2019-09/refRemote.json | 20 +- tests/draft2019-09/unevaluatedItems.json | 76 ++ tests/draft2019-09/unevaluatedProperties.json | 129 ++++ tests/draft2020-12/additionalProperties.json | 67 +- tests/draft2020-12/anchor.json | 115 --- tests/draft2020-12/dependentSchemas.json | 1 + tests/draft2020-12/dynamicRef.json | 85 +++ tests/draft2020-12/enum.json | 96 +++ tests/draft2020-12/id.json | 294 -------- tests/draft2020-12/items.json | 20 + tests/draft2020-12/maxLength.json | 2 +- tests/draft2020-12/minLength.json | 2 +- tests/draft2020-12/not.json | 154 +++- tests/draft2020-12/oneOf.json | 2 +- tests/draft2020-12/optional/anchor.json | 60 ++ tests/draft2020-12/optional/dynamicRef.json | 56 ++ .../optional/ecmascript-regex.json | 14 - .../optional/format/duration.json | 5 + .../optional/format/ecmascript-regex.json | 16 + .../optional/format/hostname.json | 10 + .../optional/format/idn-hostname.json | 84 ++- tests/draft2020-12/optional/format/ipv4.json | 5 + tests/draft2020-12/optional/id.json | 53 ++ .../optional/refOfUnknownKeyword.json | 23 + .../{ => optional}/unknownKeyword.json | 0 tests/draft2020-12/propertyNames.json | 83 +++ tests/draft2020-12/ref.json | 23 +- tests/draft2020-12/refRemote.json | 20 +- tests/draft2020-12/unevaluatedItems.json | 81 ++- tests/draft2020-12/unevaluatedProperties.json | 184 ++++- tests/draft3/additionalItems.json | 19 + tests/draft3/maxLength.json | 2 +- tests/draft3/minLength.json | 2 +- .../{ => format}/ecmascript-regex.json | 0 tests/draft3/optional/format/host-name.json | 5 + tests/draft3/refRemote.json | 4 +- tests/draft4/additionalItems.json | 19 + tests/draft4/enum.json | 84 +++ tests/draft4/maxLength.json | 2 +- tests/draft4/minLength.json | 2 +- tests/draft4/not.json | 63 +- tests/draft4/oneOf.json | 2 +- tests/draft4/optional/format/hostname.json | 10 + tests/draft4/optional/format/ipv4.json | 5 + tests/draft4/{ => optional}/id.json | 0 tests/draft4/refRemote.json | 8 +- tests/draft6/additionalItems.json | 19 + tests/draft6/enum.json | 84 +++ tests/draft6/maxLength.json | 2 +- tests/draft6/minLength.json | 2 +- tests/draft6/not.json | 152 +++- tests/draft6/oneOf.json | 2 +- tests/draft6/optional/format/hostname.json | 10 + tests/draft6/optional/format/ipv4.json | 5 + tests/draft6/{ => optional}/id.json | 0 .../draft6/{ => optional}/unknownKeyword.json | 0 tests/draft6/propertyNames.json | 47 ++ tests/draft6/refRemote.json | 10 +- tests/draft7/additionalItems.json | 19 + tests/draft7/enum.json | 84 +++ tests/draft7/maxLength.json | 2 +- tests/draft7/minLength.json | 2 +- tests/draft7/not.json | 152 +++- tests/draft7/oneOf.json | 2 +- tests/draft7/optional/format/hostname.json | 10 + .../draft7/optional/format/idn-hostname.json | 76 +- tests/draft7/optional/format/ipv4.json | 5 + tests/draft7/{ => optional}/id.json | 0 .../draft7/{ => optional}/unknownKeyword.json | 0 tests/draft7/propertyNames.json | 47 ++ tests/draft7/refRemote.json | 10 +- 169 files changed, 5845 insertions(+), 1697 deletions(-) create mode 100644 .github/workflows/annotation-tests.yml create mode 100644 .github/workflows/pr-dependencies.yml create mode 100644 .github/workflows/show_specification_annotations.yml create mode 100644 annotations/README.md create mode 100644 annotations/assertion.schema.json create mode 100644 annotations/test-case.schema.json create mode 100644 annotations/test-suite.schema.json create mode 100644 annotations/test.schema.json create mode 100644 annotations/tests/applicators.json create mode 100644 annotations/tests/content.json create mode 100644 annotations/tests/core.json create mode 100644 annotations/tests/format.json create mode 100644 annotations/tests/meta-data.json create mode 100644 annotations/tests/unevaluated.json create mode 100644 annotations/tests/unknown.json create mode 100755 bin/annotate-specification-links create mode 100755 bin/annotation-tests.ts create mode 100644 bin/specification_urls.json delete mode 100644 remotes/draft-next/subSchemas-defs.json delete mode 100644 remotes/draft2019-09/subSchemas-defs.json delete mode 100644 remotes/draft2020-12/subSchemas-defs.json rename remotes/{subSchemas-defs.json => draft3/subSchemas.json} (62%) rename remotes/{locationIndependentIdentifierDraft4.json => draft4/locationIndependentIdentifier.json} (100%) rename remotes/{ => draft4}/name.json (100%) create mode 100644 remotes/draft4/subSchemas.json rename remotes/{locationIndependentIdentifierPre2019.json => draft6/locationIndependentIdentifier.json} (100%) create mode 100644 remotes/draft6/name.json rename remotes/{ => draft6}/ref-and-definitions.json (74%) create mode 100644 remotes/draft6/subSchemas.json create mode 100644 remotes/draft7/locationIndependentIdentifier.json create mode 100644 remotes/draft7/name.json create mode 100644 remotes/draft7/ref-and-definitions.json create mode 100644 remotes/draft7/subSchemas.json delete mode 100644 remotes/subSchemas.json delete mode 100644 tests/draft-next/id.json create mode 100644 tests/draft-next/optional/anchor.json create mode 100644 tests/draft-next/optional/dynamicRef.json create mode 100644 tests/draft-next/optional/format/ecmascript-regex.json create mode 100644 tests/draft-next/optional/id.json rename tests/draft-next/{ => optional}/unknownKeyword.json (100%) delete mode 100644 tests/draft2019-09/id.json create mode 100644 tests/draft2019-09/optional/anchor.json create mode 100644 tests/draft2019-09/optional/id.json rename tests/draft2019-09/{ => optional}/unknownKeyword.json (100%) delete mode 100644 tests/draft2020-12/id.json create mode 100644 tests/draft2020-12/optional/anchor.json create mode 100644 tests/draft2020-12/optional/dynamicRef.json create mode 100644 tests/draft2020-12/optional/format/ecmascript-regex.json create mode 100644 tests/draft2020-12/optional/id.json rename tests/draft2020-12/{ => optional}/unknownKeyword.json (100%) rename tests/draft3/optional/{ => format}/ecmascript-regex.json (100%) rename tests/draft4/{ => optional}/id.json (100%) rename tests/draft6/{ => optional}/id.json (100%) rename tests/draft6/{ => optional}/unknownKeyword.json (100%) rename tests/draft7/{ => optional}/id.json (100%) rename tests/draft7/{ => optional}/unknownKeyword.json (100%) diff --git a/.github/workflows/annotation-tests.yml b/.github/workflows/annotation-tests.yml new file mode 100644 index 000000000..16de7b169 --- /dev/null +++ b/.github/workflows/annotation-tests.yml @@ -0,0 +1,21 @@ +name: Validate annotation tests + +on: + pull_request: + paths: + - "annotations/**" + +jobs: + annotate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Deno + uses: denoland/setup-deno@v2 + with: + deno-version: "2.x" + + - name: Validate annotation tests + run: deno --node-modules-dir=auto --allow-read --no-prompt bin/annotation-tests.ts diff --git a/.github/workflows/pr-dependencies.yml b/.github/workflows/pr-dependencies.yml new file mode 100644 index 000000000..34a231dcb --- /dev/null +++ b/.github/workflows/pr-dependencies.yml @@ -0,0 +1,12 @@ +name: Check PR Dependencies + +on: pull_request + +jobs: + check_dependencies: + runs-on: ubuntu-latest + name: Check Dependencies + steps: + - uses: gregsdennis/dependencies-action@main + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/show_specification_annotations.yml b/.github/workflows/show_specification_annotations.yml new file mode 100644 index 000000000..f7d7b398b --- /dev/null +++ b/.github/workflows/show_specification_annotations.yml @@ -0,0 +1,21 @@ +name: Show Specification Annotations + +on: + pull_request: + paths: + - 'tests/**' + +jobs: + annotate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Generate Annotations + run: pip install uritemplate && bin/annotate-specification-links diff --git a/README.md b/README.md index cdd5dc8a4..9f4c516db 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ To test a specific version: * For 2019-09 and later published drafts, implementations that are able to detect the draft of each schema via `$schema` SHOULD be configured to do so * For draft-07 and earlier, draft-next, and implementations unable to detect via `$schema`, implementations MUST be configured to expect the draft matching the test directory name -* Load any remote references [described below](additional-assumptions) and configure your implementation to retrieve them via their URIs +* Load any remote references [described below](#additional-assumptions) and configure your implementation to retrieve them via their URIs * Walk the filesystem tree for that version's subdirectory and for each `.json` file found: * if the file is located in the root of the version directory: @@ -159,7 +159,7 @@ If your implementation supports multiple versions, run the above procedure for e ``` 2. Test cases found within [special subdirectories](#subdirectories-within-each-draft) may require additional configuration to run. - In particular, tests within the `optional/format` subdirectory may require implementations to change the way they treat the `"format"`keyword (particularly on older drafts which did not have a notion of vocabularies). + In particular, when running tests within the `optional/format` subdirectory, test runners should configure implementations to enable format validation, where the implementation supports it. ### Invariants & Guarantees @@ -227,6 +227,7 @@ This suite is being used by: ### C++ +* [Blaze](https://github.com/sourcemeta/blaze) * [Modern C++ JSON schema validator](https://github.com/pboettch/json-schema-validator) * [Valijson](https://github.com/tristanpenman/valijson) @@ -254,12 +255,14 @@ This suite is being used by: ### Java +* [json-schema-validation-comparison](https://www.creekservice.org/json-schema-validation-comparison/functional) (Comparison site for JVM-based validator implementations) * [json-schema-validator](https://github.com/daveclayton/json-schema-validator) * [everit-org/json-schema](https://github.com/everit-org/json-schema) * [networknt/json-schema-validator](https://github.com/networknt/json-schema-validator) * [Justify](https://github.com/leadpony/justify) * [Snow](https://github.com/ssilverman/snowy-json) * [jsonschemafriend](https://github.com/jimblackler/jsonschemafriend) +* [OpenAPI JSON Schema Generator](https://github.com/openapi-json-schema-tools/openapi-json-schema-generator) ### JavaScript @@ -279,6 +282,10 @@ This suite is being used by: * [ajv](https://github.com/epoberezkin/ajv) * [djv](https://github.com/korzio/djv) +### Kotlin + +* [json-schema-validation-comparison](https://www.creekservice.org/json-schema-validation-comparison/functional) (Comparison site for JVM-based validator implementations) + ### Node.js For node.js developers, the suite is also available as an [npm](https://www.npmjs.com/package/@json-schema-org/tests) package. @@ -287,7 +294,7 @@ Node-specific support is maintained in a [separate repository](https://github.co ### .NET -* [JsonSchema.Net](https://github.com/gregsdennis/json-everything) +* [JsonSchema.Net](https://github.com/json-everything/json-everything) * [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema) ### Perl @@ -313,7 +320,7 @@ Node-specific support is maintained in a [separate repository](https://github.co * [fastjsonschema](https://github.com/seznam/python-fastjsonschema) * [hypothesis-jsonschema](https://github.com/Zac-HD/hypothesis-jsonschema) * [jschon](https://github.com/marksparkza/jschon) -* [python-experimental, OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/python-experimental.md) +* [OpenAPI JSON Schema Generator](https://github.com/openapi-json-schema-tools/openapi-json-schema-generator) ### Ruby @@ -327,11 +334,13 @@ Node-specific support is maintained in a [separate repository](https://github.co ### Scala +* [json-schema-validation-comparison](https://www.creekservice.org/json-schema-validation-comparison/functional) (Comparison site for JVM-based validator implementations) * [typed-json](https://github.com/frawa/typed-json) ### Swift * [JSONSchema](https://github.com/kylef/JSONSchema.swift) +* [swift-json-schema](https://github.com/ajevans99/swift-json-schema) If you use it as well, please fork and send a pull request adding yourself to the list :). diff --git a/annotations/README.md b/annotations/README.md new file mode 100644 index 000000000..69cd3dd7e --- /dev/null +++ b/annotations/README.md @@ -0,0 +1,116 @@ +# Annotations Tests Suite + +The Annotations Test Suite tests which annotations should appear (or not appear) +on which values of an instance. These tests are agnostic of any output format. + +## Supported Dialects + +Although the annotation terminology of didn't appear in the spec until 2019-09, +the concept is compatible with every version of JSON Schema. Test Cases in this +Test Suite are designed to be compatible with as many releases of JSON Schema as +possible. They do not include `$schema` or `$id`/`id` keywords so +implementations can run the same Test Suite for each dialect they support. + +Since this Test Suite can be used for a variety of dialects, there are a couple +of options that can be used by Test Runners to filter out Test Cases that don't +apply to the dialect under test. + +## Test Case Components + +### description + +A short description of what behavior the Test Case is covering. + +### compatibility + +The `compatibility` option allows you to set which dialects the Test Case is +compatible with. Test Runners can use this value to filter out Test Cases that +don't apply the to dialect currently under test. The terminology for annotations +didn't appear in the spec until 2019-09, but the concept is compatible with +older releases as well. When setting `compatibility`, test authors should take +into account dialects before 2019-09 for implementations that chose to support +annotations for older dialects. + +Dialects are indicated by the number corresponding to their release. Date-based +releases use just the year. If this option isn't present, it means the Test Case +is compatible with any dialect. + +If this option is present with a number, the number indicates the minimum +release the Test Case is compatible with. This example indicates that the Test +Case is compatible with draft-07 and up. + +**Example**: `"compatibility": "7"` + +You can use a `<=` operator to indicate that the Test Case is compatible with +releases less then or equal to the given release. This example indicates that +the Test Case is compatible with 2019-09 and under. + +**Example**: `"compatibility": "<=2019"` + +You can use comma-separated values to indicate multiple constraints if needed. +This example indicates that the Test Case is compatible with releases between +draft-06 and 2019-09. + +**Example**: `"compatibility": "6,<=2019"` + +For convenience, you can use the `=` operator to indicate a Test Case is only +compatible with a single release. This example indicates that the Test Case is +compatible only with 2020-12. + +**Example**: `"compatibility": "=2020"` + +### schema + +The schema that will serve as the subject for the tests. Whenever possible, this +schema shouldn't include `$schema` or `id`/`$id` because Test Cases should be +designed to work with as many releases as possible. + +### externalSchemas + +This allows you to define additional schemas that `schema` makes references to. +The value is an object where the keys are retrieval URIs and values are schemas. +Most external schemas aren't self identifying (using `id`/`$id`) and rely on the +retrieval URI for identification. This is done to increase the number of +dialects that the test is compatible with. Because `id` changed to `$id` in +draft-06, if you use `$id`, the test becomes incompatible with draft-03/4 and in +most cases, that's not necessary. + +### tests + +A collection of Tests to run to verify the Test Case. + +## Test Components + +### instance + +The JSON instance to be annotated. + +### assertions + +A collection of assertions that must be true for the test to pass. + +## Assertions Components + +### location + +The instance location. + +### keyword + +The annotating keyword. + +### expected + +A collection of `keyword` annotations expected on the instance at `location`. +`expected` is an object where the keys are schema locations and the values are +the annotation that schema location contributed for the given `keyword`. + +There can be more than one expected annotation because multiple schema locations +could contribute annotations for a single keyword. + +An empty object is an assertion that the annotation must not appear at the +`location` for the `keyword`. + +As a convention for this Test Suite, the `expected` array should be sorted such +that the most recently encountered value for an annotation given top-down +evaluation of the schema comes before previously encountered values. diff --git a/annotations/assertion.schema.json b/annotations/assertion.schema.json new file mode 100644 index 000000000..882517887 --- /dev/null +++ b/annotations/assertion.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + + "type": "object", + "properties": { + "location": { + "markdownDescription": "The instance location.", + "type": "string", + "format": "json-pointer" + }, + "keyword": { + "markdownDescription": "The annotation keyword.", + "type": "string" + }, + "expected": { + "markdownDescription": "An object of schemaLocation/annotations pairs for `keyword` annotations expected on the instance at `location`.", + "type": "object", + "propertyNames": { + "format": "uri" + } + } + }, + "required": ["location", "keyword", "expected"] +} diff --git a/annotations/test-case.schema.json b/annotations/test-case.schema.json new file mode 100644 index 000000000..6df5f1098 --- /dev/null +++ b/annotations/test-case.schema.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + + "type": "object", + "properties": { + "description": { + "markdownDescription": "A short description of what behavior the Test Case is covering.", + "type": "string" + }, + "compatibility": { + "markdownDescription": "Set which dialects the Test Case is compatible with. Examples:\n- `\"7\"` -- draft-07 and above\n- `\"<=2019\"` -- 2019-09 and previous\n- `\"6,<=2019\"` -- Between draft-06 and 2019-09\n- `\"=2020\"` -- 2020-12 only", + "type": "string", + "pattern": "^(<=|=)?([123467]|2019|2020)(,(<=|=)?([123467]|2019|2020))*$" + }, + "schema": { + "markdownDescription": "This schema shouldn't include `$schema` or `id`/`$id` unless necesary for the test because Test Cases should be designed to work with as many releases as possible.", + "type": ["boolean", "object"] + }, + "externalSchemas": { + "markdownDescription": "The keys are retrieval URIs and values are schemas.", + "type": "object", + "patternProperties": { + "": { + "type": ["boolean", "object"] + } + }, + "propertyNames": { + "format": "uri" + } + }, + "tests": { + "markdownDescription": "A collection of Tests to run to verify the Test Case.", + "type": "array", + "items": { "$ref": "./test.schema.json" } + } + }, + "required": ["description", "schema", "tests"] +} diff --git a/annotations/test-suite.schema.json b/annotations/test-suite.schema.json new file mode 100644 index 000000000..c8b17f0d5 --- /dev/null +++ b/annotations/test-suite.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "suite": { + "type": "array", + "items": { "$ref": "./test-case.schema.json" } + } + }, + "required": ["description", "suite"] +} diff --git a/annotations/test.schema.json b/annotations/test.schema.json new file mode 100644 index 000000000..3581fbfca --- /dev/null +++ b/annotations/test.schema.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + + "type": "object", + "properties": { + "instance": { + "markdownDescription": "The JSON instance to be annotated." + }, + "assertions": { + "markdownDescription": "A collection of assertions that must be true for the test to pass.", + "type": "array", + "items": { "$ref": "./assertion.schema.json" } + } + }, + "required": ["instance", "assertions"] +} diff --git a/annotations/tests/applicators.json b/annotations/tests/applicators.json new file mode 100644 index 000000000..ceb5044f3 --- /dev/null +++ b/annotations/tests/applicators.json @@ -0,0 +1,409 @@ +{ + "$schema": "../test-suite.schema.json", + "description": "The applicator vocabulary", + "suite": [ + { + "description": "`properties`, `patternProperties`, and `additionalProperties`", + "compatibility": "3", + "schema": { + "properties": { + "foo": { + "title": "Foo" + } + }, + "patternProperties": { + "^a": { + "title": "Bar" + } + }, + "additionalProperties": { + "title": "Baz" + } + }, + "tests": [ + { + "instance": {}, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": {} + }, + { + "location": "/apple", + "keyword": "title", + "expected": {} + }, + { + "location": "/bar", + "keyword": "title", + "expected": {} + } + ] + }, + { + "instance": { + "foo": {}, + "apple": {}, + "baz": {} + }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/properties/foo": "Foo" + } + }, + { + "location": "/apple", + "keyword": "title", + "expected": { + "#/patternProperties/%5Ea": "Bar" + } + }, + { + "location": "/baz", + "keyword": "title", + "expected": { + "#/additionalProperties": "Baz" + } + } + ] + } + ] + }, + { + "description": "`propertyNames` doesn't annotate property values", + "compatibility": "6", + "schema": { + "propertyNames": { + "const": "foo", + "title": "Foo" + } + }, + "tests": [ + { + "instance": { + "foo": 42 + }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": {} + } + ] + } + ] + }, + { + "description": "`prefixItems` and `items`", + "compatibility": "2020", + "schema": { + "prefixItems": [ + { + "title": "Foo" + } + ], + "items": { + "title": "Bar" + } + }, + "tests": [ + { + "instance": [ + "foo", + "bar" + ], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/prefixItems/0": "Foo" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/items": "Bar" + } + }, + { + "location": "/2", + "keyword": "title", + "expected": {} + } + ] + } + ] + }, + { + "description": "`contains`", + "compatibility": "6", + "schema": { + "contains": { + "type": "number", + "title": "Foo" + } + }, + "tests": [ + { + "instance": [ + "foo", + 42, + true + ], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": {} + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/contains": "Foo" + } + }, + { + "location": "/2", + "keyword": "title", + "expected": {} + }, + { + "location": "/3", + "keyword": "title", + "expected": {} + } + ] + } + ] + }, + { + "description": "`allOf`", + "compatibility": "4", + "schema": { + "allOf": [ + { + "title": "Foo" + }, + { + "title": "Bar" + } + ] + }, + "tests": [ + { + "instance": "foo", + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/allOf/1": "Bar", + "#/allOf/0": "Foo" + } + } + ] + } + ] + }, + { + "description": "`anyOf`", + "compatibility": "4", + "schema": { + "anyOf": [ + { + "type": "integer", + "title": "Foo" + }, + { + "type": "number", + "title": "Bar" + } + ] + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/anyOf/1": "Bar", + "#/anyOf/0": "Foo" + } + } + ] + }, + { + "instance": 4.2, + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/anyOf/1": "Bar" + } + } + ] + } + ] + }, + { + "description": "`oneOf`", + "compatibility": "4", + "schema": { + "oneOf": [ + { + "type": "string", + "title": "Foo" + }, + { + "type": "number", + "title": "Bar" + } + ] + }, + "tests": [ + { + "instance": "foo", + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/oneOf/0": "Foo" + } + } + ] + }, + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/oneOf/1": "Bar" + } + } + ] + } + ] + }, + { + "description": "`not`", + "compatibility": "4", + "schema": { + "title": "Foo", + "not": { + "not": { + "title": "Bar" + } + } + }, + "tests": [ + { + "instance": {}, + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#": "Foo" + } + } + ] + } + ] + }, + { + "description": "`dependentSchemas`", + "compatibility": "2019", + "schema": { + "dependentSchemas": { + "foo": { + "title": "Foo" + } + } + }, + "tests": [ + { + "instance": { + "foo": 42 + }, + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/dependentSchemas/foo": "Foo" + } + } + ] + }, + { + "instance": { + "foo": 42 + }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": {} + } + ] + } + ] + }, + { + "description": "`if`, `then`, and `else`", + "compatibility": "7", + "schema": { + "if": { + "title": "If", + "type": "string" + }, + "then": { + "title": "Then" + }, + "else": { + "title": "Else" + } + }, + "tests": [ + { + "instance": "foo", + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/then": "Then", + "#/if": "If" + } + } + ] + }, + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/else": "Else" + } + } + ] + } + ] + } + ] +} diff --git a/annotations/tests/content.json b/annotations/tests/content.json new file mode 100644 index 000000000..07c17a691 --- /dev/null +++ b/annotations/tests/content.json @@ -0,0 +1,121 @@ +{ + "$schema": "../test-suite.schema.json", + "description": "The content vocabulary", + "suite": [ + { + "description": "`contentMediaType` is an annotation for string instances", + "compatibility": "7", + "schema": { + "contentMediaType": "application/json" + }, + "tests": [ + { + "instance": "{ \"foo\": \"bar\" }", + "assertions": [ + { + "location": "", + "keyword": "contentMediaType", + "expected": { + "#": "application/json" + } + } + ] + }, + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "contentMediaType", + "expected": {} + } + ] + } + ] + }, + { + "description": "`contentEncoding` is an annotation for string instances", + "compatibility": "7", + "schema": { + "contentEncoding": "base64" + }, + "tests": [ + { + "instance": "SGVsbG8gZnJvbSBKU09OIFNjaGVtYQ==", + "assertions": [ + { + "location": "", + "keyword": "contentEncoding", + "expected": { + "#": "base64" + } + } + ] + }, + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "contentEncoding", + "expected": {} + } + ] + } + ] + }, + { + "description": "`contentSchema` is an annotation for string instances", + "compatibility": "2019", + "schema": { + "$id": "https://annotations.json-schema.org/test/contentSchema-is-an-annotation", + "contentMediaType": "application/json", + "contentSchema": { "type": "number" } + }, + "tests": [ + { + "instance": "42", + "assertions": [ + { + "location": "", + "keyword": "contentSchema", + "expected": { + "#": { "type": "number" } + } + } + ] + }, + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "contentSchema", + "expected": {} + } + ] + } + ] + }, + { + "description": "`contentSchema` requires `contentMediaType`", + "compatibility": "2019", + "schema": { + "$id": "https://annotations.json-schema.org/test/contentSchema-is-an-annotation", + "contentSchema": { "type": "number" } + }, + "tests": [ + { + "instance": "42", + "assertions": [ + { + "location": "", + "keyword": "contentSchema", + "expected": {} + } + ] + } + ] + } + ] +} diff --git a/annotations/tests/core.json b/annotations/tests/core.json new file mode 100644 index 000000000..1d8dee556 --- /dev/null +++ b/annotations/tests/core.json @@ -0,0 +1,30 @@ +{ + "$schema": "../test-suite.schema.json", + "description": "The core vocabulary", + "suite": [ + { + "description": "`$ref` and `$defs`", + "compatibility": "2019", + "schema": { + "$ref": "#/$defs/foo", + "$defs": { + "foo": { "title": "Foo" } + } + }, + "tests": [ + { + "instance": "foo", + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#/$defs/foo": "Foo" + } + } + ] + } + ] + } + ] +} diff --git a/annotations/tests/format.json b/annotations/tests/format.json new file mode 100644 index 000000000..d8cf9a7af --- /dev/null +++ b/annotations/tests/format.json @@ -0,0 +1,26 @@ +{ + "$schema": "../test-suite.schema.json", + "description": "The format vocabulary", + "suite": [ + { + "description": "`format` is an annotation", + "schema": { + "format": "email" + }, + "tests": [ + { + "instance": "foo@bar.com", + "assertions": [ + { + "location": "", + "keyword": "format", + "expected": { + "#": "email" + } + } + ] + } + ] + } + ] +} diff --git a/annotations/tests/meta-data.json b/annotations/tests/meta-data.json new file mode 100644 index 000000000..be99b652f --- /dev/null +++ b/annotations/tests/meta-data.json @@ -0,0 +1,150 @@ +{ + "$schema": "../test-suite.schema.json", + "description": "The meta-data vocabulary", + "suite": [ + { + "description": "`title` is an annotation", + "schema": { + "title": "Foo" + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "title", + "expected": { + "#": "Foo" + } + } + ] + } + ] + }, + { + "description": "`description` is an annotation", + "schema": { + "description": "Foo" + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "description", + "expected": { + "#": "Foo" + } + } + ] + } + ] + }, + { + "description": "`default` is an annotation", + "schema": { + "default": "Foo" + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "default", + "expected": { + "#": "Foo" + } + } + ] + } + ] + }, + { + "description": "`deprecated` is an annotation", + "compatibility": "2019", + "schema": { + "deprecated": true + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "deprecated", + "expected": { + "#": true + } + } + ] + } + ] + }, + { + "description": "`readOnly` is an annotation", + "compatibility": "7", + "schema": { + "readOnly": true + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "readOnly", + "expected": { + "#": true + } + } + ] + } + ] + }, + { + "description": "`writeOnly` is an annotation", + "compatibility": "7", + "schema": { + "writeOnly": true + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "writeOnly", + "expected": { + "#": true + } + } + ] + } + ] + }, + { + "description": "`examples` is an annotation", + "compatibility": "6", + "schema": { + "examples": ["Foo", "Bar"] + }, + "tests": [ + { + "instance": "Foo", + "assertions": [ + { + "location": "", + "keyword": "examples", + "expected": { + "#": ["Foo", "Bar"] + } + } + ] + } + ] + } + ] +} diff --git a/annotations/tests/unevaluated.json b/annotations/tests/unevaluated.json new file mode 100644 index 000000000..9f2db1158 --- /dev/null +++ b/annotations/tests/unevaluated.json @@ -0,0 +1,661 @@ +{ + "$schema": "../test-suite.schema.json", + "description": "The unevaluated vocabulary", + "suite": [ + { + "description": "`unevaluatedProperties` alone", + "compatibility": "2019", + "schema": { + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `properties`", + "compatibility": "2019", + "schema": { + "properties": { + "foo": { "title": "Evaluated" } + }, + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/properties/foo": "Evaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `patternProperties`", + "compatibility": "2019", + "schema": { + "patternProperties": { + "^a": { "title": "Evaluated" } + }, + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "apple": 42, "bar": 24 }, + "assertions": [ + { + "location": "/apple", + "keyword": "title", + "expected": { + "#/patternProperties/%5Ea": "Evaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `additionalProperties`", + "compatibility": "2019", + "schema": { + "additionalProperties": { "title": "Evaluated" }, + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/additionalProperties": "Evaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/additionalProperties": "Evaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `dependentSchemas`", + "compatibility": "2019", + "schema": { + "dependentSchemas": { + "foo": { + "properties": { + "bar": { "title": "Evaluated" } + } + } + }, + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/dependentSchemas/foo/properties/bar": "Evaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `if`, `then`, and `else`", + "compatibility": "2019", + "schema": { + "if": { + "properties": { + "foo": { + "type": "string", + "title": "If" + } + } + }, + "then": { + "properties": { + "foo": { "title": "Then" } + } + }, + "else": { + "properties": { + "foo": { "title": "Else" } + } + }, + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": "", "bar": 42 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/then/properties/foo": "Then", + "#/if/properties/foo": "If" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + }, + { + "instance": { "foo": 42, "bar": "" }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/else/properties/foo": "Else" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `allOf`", + "compatibility": "2019", + "schema": { + "allOf": [ + { + "properties": { + "foo": { "title": "Evaluated" } + } + } + ], + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/allOf/0/properties/foo": "Evaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `anyOf`", + "compatibility": "2019", + "schema": { + "anyOf": [ + { + "properties": { + "foo": { "title": "Evaluated" } + } + } + ], + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/anyOf/0/properties/foo": "Evaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `oneOf`", + "compatibility": "2019", + "schema": { + "oneOf": [ + { + "properties": { + "foo": { "title": "Evaluated" } + } + } + ], + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/oneOf/0/properties/foo": "Evaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedProperties` with `not`", + "compatibility": "2019", + "schema": { + "not": { + "not": { + "properties": { + "foo": { "title": "Evaluated" } + } + } + }, + "unevaluatedProperties": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": { "foo": 42, "bar": 24 }, + "assertions": [ + { + "location": "/foo", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + }, + { + "location": "/bar", + "keyword": "title", + "expected": { + "#/unevaluatedProperties": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` alone", + "compatibility": "2019", + "schema": { + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": [42, 24], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` with `prefixItems`", + "compatibility": "2020", + "schema": { + "prefixItems": [{ "title": "Evaluated" }], + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": [42, 24], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/prefixItems/0": "Evaluated" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` with `contains`", + "compatibility": "2020", + "schema": { + "contains": { + "type": "string", + "title": "Evaluated" + }, + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": ["foo", 42], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/contains": "Evaluated" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` with `if`, `then`, and `else`", + "compatibility": "2020", + "schema": { + "if": { + "prefixItems": [ + { + "type": "string", + "title": "If" + } + ] + }, + "then": { + "prefixItems": [ + { "title": "Then" } + ] + }, + "else": { + "prefixItems": [ + { "title": "Else" } + ] + }, + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": ["", 42], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/then/prefixItems/0": "Then", + "#/if/prefixItems/0": "If" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + }, + { + "instance": [42, ""], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/else/prefixItems/0": "Else" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` with `allOf`", + "compatibility": "2020", + "schema": { + "allOf": [ + { + "prefixItems": [ + { "title": "Evaluated" } + ] + } + ], + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": [42, 24], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/allOf/0/prefixItems/0": "Evaluated" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` with `anyOf`", + "compatibility": "2020", + "schema": { + "anyOf": [ + { + "prefixItems": [ + { "title": "Evaluated" } + ] + } + ], + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": [42, 24], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/anyOf/0/prefixItems/0": "Evaluated" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` with `oneOf`", + "compatibility": "2020", + "schema": { + "oneOf": [ + { + "prefixItems": [ + { "title": "Evaluated" } + ] + } + ], + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": [42, 24], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/oneOf/0/prefixItems/0": "Evaluated" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + }, + { + "description": "`unevaluatedItems` with `not`", + "compatibility": "2020", + "schema": { + "not": { + "not": { + "prefixItems": [ + { "title": "Evaluated" } + ] + } + }, + "unevaluatedItems": { "title": "Unevaluated" } + }, + "tests": [ + { + "instance": [42, 24], + "assertions": [ + { + "location": "/0", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + }, + { + "location": "/1", + "keyword": "title", + "expected": { + "#/unevaluatedItems": "Unevaluated" + } + } + ] + } + ] + } + ] +} diff --git a/annotations/tests/unknown.json b/annotations/tests/unknown.json new file mode 100644 index 000000000..b0c89003c --- /dev/null +++ b/annotations/tests/unknown.json @@ -0,0 +1,27 @@ +{ + "$schema": "../test-suite.schema.json", + "description": "Unknown keywords", + "suite": [ + { + "description": "`unknownKeyword` is an annotation", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "x-unknownKeyword": "Foo" + }, + "tests": [ + { + "instance": 42, + "assertions": [ + { + "location": "", + "keyword": "x-unknownKeyword", + "expected": { + "#": "Foo" + } + } + ] + } + ] + } + ] +} diff --git a/bin/annotate-specification-links b/bin/annotate-specification-links new file mode 100755 index 000000000..963768b43 --- /dev/null +++ b/bin/annotate-specification-links @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +""" +Annotate pull requests to the GitHub repository with links to specifications. +""" + +from __future__ import annotations + +from pathlib import Path +from typing import Any +import json +import re +import sys + +from uritemplate import URITemplate + + +BIN_DIR = Path(__file__).parent +TESTS = BIN_DIR.parent / "tests" +URLS = json.loads(BIN_DIR.joinpath("specification_urls.json").read_text()) + + +def urls(version: str) -> dict[str, URITemplate]: + """ + Retrieve the version-specific URLs for specifications. + """ + for_version = {**URLS["json-schema"][version], **URLS["external"]} + return {k: URITemplate(v) for k, v in for_version.items()} + + +def annotation( + path: Path, + message: str, + line: int = 1, + level: str = "notice", + **kwargs: Any, +) -> str: + """ + Format a GitHub annotation. + + See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions + for full syntax. + """ + + if kwargs: + additional = "," + ",".join(f"{k}={v}" for k, v in kwargs.items()) + else: + additional = "" + + relative = path.relative_to(TESTS.parent) + return f"::{level} file={relative},line={line}{additional}::{message}\n" + + +def line_number_of(path: Path, case: dict[str, Any]) -> int: + """ + Crudely find the line number of a test case. + """ + with path.open() as file: + description = case["description"] + return next( + (i + 1 for i, line in enumerate(file, 1) if description in line), + 1, + ) + +def extract_kind_and_spec(key: str) -> (str, str): + """ + Extracts specification number and kind from the defined key + """ + can_have_spec = ["rfc", "iso"] + if not any(key.startswith(el) for el in can_have_spec): + return key, "" + number = re.search(r"\d+", key) + spec = "" if number is None else number.group(0) + kind = key.removesuffix(spec) + return kind, spec + + +def main(): + # Clear annotations which may have been emitted by a previous run. + sys.stdout.write("::remove-matcher owner=me::\n") + + for version in TESTS.iterdir(): + if version.name in {"draft-next", "latest"}: + continue + + version_urls = urls(version.name) + + for path in version.rglob("*.json"): + try: + contents = json.loads(path.read_text()) + except json.JSONDecodeError as error: + error = annotation( + level="error", + path=path, + line=error.lineno, + col=error.pos + 1, + title=str(error), + message=f"cannot load {path}" + ) + sys.stdout.write(error) + continue + + for test_case in contents: + specifications = test_case.get("specification") + if specifications is not None: + for each in specifications: + quote = each.pop("quote", "") + (key, section), = each.items() + + (kind, spec) = extract_kind_and_spec(key) + + url_template = version_urls[kind] + if url_template is None: + error = annotation( + level="error", + path=path, + line=line_number_of(path, test_case), + title=f"unsupported template '{kind}'", + message=f"cannot find a URL template for '{kind}'" + ) + sys.stdout.write(error) + continue + + url = url_template.expand( + spec=spec, + section=section, + ) + + message = f"{url}\n\n{quote}" if quote else url + sys.stdout.write( + annotation( + path=path, + line=line_number_of(path, test_case), + title="Specification Link", + message=message, + ), + ) + + +if __name__ == "__main__": + main() diff --git a/bin/annotation-tests.ts b/bin/annotation-tests.ts new file mode 100755 index 000000000..2d3d19326 --- /dev/null +++ b/bin/annotation-tests.ts @@ -0,0 +1,31 @@ +#!/usr/bin/env deno +import { validate } from "npm:@hyperjump/json-schema/draft-07"; +import { BASIC } from "npm:@hyperjump/json-schema/experimental"; + +const validateTestSuite = await validate("./annotations/test-suite.schema.json"); + +console.log("Validating annotation tests ..."); + +let isValid = true; +for await (const entry of Deno.readDir("./annotations/tests")) { + if (entry.isFile) { + const json = await Deno.readTextFile(`./annotations/tests/${entry.name}`); + const suite = JSON.parse(json); + + const output = validateTestSuite(suite, BASIC); + + if (output.valid) { + console.log(`\x1b[32m✔\x1b[0m ${entry.name}`); + } else { + isValid = false; + console.log(`\x1b[31m✖\x1b[0m ${entry.name}`); + console.log(output); + } + } +} + +console.log("Done."); + +if (!isValid) { + Deno.exit(1); +} diff --git a/bin/specification_urls.json b/bin/specification_urls.json new file mode 100644 index 000000000..e1824999a --- /dev/null +++ b/bin/specification_urls.json @@ -0,0 +1,34 @@ +{ + "json-schema": { + "draft2020-12": { + "core": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-{section}", + "validation": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#section-{section}" + }, + "draft2019-09": { + "core": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.{section}", + "validation": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-validation-02#rfc.section.{section}" + }, + "draft7": { + "core": "https://json-schema.org/draft-07/draft-handrews-json-schema-01#rfc.section.{section}", + "validation": "https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01#rfc.section.{section}" + }, + "draft6": { + "core": "https://json-schema.org/draft-06/draft-wright-json-schema-01#rfc.section.{section}", + "validation": "https://json-schema.org/draft-06/draft-wright-json-schema-validation-01#rfc.section.{section}" + }, + "draft4": { + "core": "https://json-schema.org/draft-04/draft-zyp-json-schema-04#rfc.section.{section}", + "validation": "https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.{section}" + }, + "draft3": { + "core": "https://json-schema.org/draft-03/draft-zyp-json-schema-03.pdf" + } + }, + + "external": { + "ecma262": "https://262.ecma-international.org/{section}", + "perl5": "https://perldoc.perl.org/perlre#{section}", + "rfc": "https://www.rfc-editor.org/rfc/rfc{spec}.html#section-{section}", + "iso": "https://www.iso.org/obp/ui" + } +} diff --git a/output-tests/draft2019-09/content/type.json b/output-tests/draft2019-09/content/type.json index cff77a740..21118fd5f 100644 --- a/output-tests/draft2019-09/content/type.json +++ b/output-tests/draft2019-09/content/type.json @@ -31,32 +31,6 @@ "required": ["errors"] } } - }, - { - "description": "correct type yields an output unit", - "data": "a string", - "output": { - "basic": { - "$id": "https://json-schema.org/tests/content/draft2019-09/type/0/tests/1/basic", - "$ref": "/draft/2019-09/output/schema", - "properties": { - "annotations": { - "contains": { - "properties": { - "valid": {"const": true}, - "keywordLocation": {"const": "/type"}, - "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2019-09/type/0#/type"}, - "instanceLocation": {"const": ""}, - "annotation": false, - "error": false - }, - "required": ["keywordLocation", "instanceLocation"] - } - } - }, - "required": ["annotations"] - } - } } ] } diff --git a/output-tests/draft2020-12/content/type.json b/output-tests/draft2020-12/content/type.json index 710475b2b..2949a6052 100644 --- a/output-tests/draft2020-12/content/type.json +++ b/output-tests/draft2020-12/content/type.json @@ -31,32 +31,6 @@ "required": ["errors"] } } - }, - { - "description": "correct type yields an output unit", - "data": "a string", - "output": { - "basic": { - "$id": "https://json-schema.org/tests/content/draft2020-12/type/0/tests/1/basic", - "$ref": "/draft/2020-12/output/schema", - "properties": { - "annotations": { - "contains": { - "properties": { - "valid": {"const": true}, - "keywordLocation": {"const": "/type"}, - "absoluteKeywordLocation": {"const": "https://json-schema.org/tests/content/draft2020-12/type/0#/type"}, - "instanceLocation": {"const": ""}, - "annotation": false, - "error": false - }, - "required": ["keywordLocation", "instanceLocation"] - } - } - }, - "required": ["annotations"] - } - } } ] } diff --git a/remotes/draft-next/format-assertion-false.json b/remotes/draft-next/format-assertion-false.json index 91c866996..9cbd2a1de 100644 --- a/remotes/draft-next/format-assertion-false.json +++ b/remotes/draft-next/format-assertion-false.json @@ -5,6 +5,7 @@ "https://json-schema.org/draft/next/vocab/core": true, "https://json-schema.org/draft/next/vocab/format-assertion": false }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/core" }, { "$ref": "https://json-schema.org/draft/next/meta/format-assertion" } diff --git a/remotes/draft-next/format-assertion-true.json b/remotes/draft-next/format-assertion-true.json index a33d1435f..b3ff69f3a 100644 --- a/remotes/draft-next/format-assertion-true.json +++ b/remotes/draft-next/format-assertion-true.json @@ -5,6 +5,7 @@ "https://json-schema.org/draft/next/vocab/core": true, "https://json-schema.org/draft/next/vocab/format-assertion": true }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/core" }, { "$ref": "https://json-schema.org/draft/next/meta/format-assertion" } diff --git a/remotes/draft-next/metaschema-no-validation.json b/remotes/draft-next/metaschema-no-validation.json index c19c9e8a7..90e32a672 100644 --- a/remotes/draft-next/metaschema-no-validation.json +++ b/remotes/draft-next/metaschema-no-validation.json @@ -5,6 +5,7 @@ "https://json-schema.org/draft/next/vocab/applicator": true, "https://json-schema.org/draft/next/vocab/core": true }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/applicator" }, { "$ref": "https://json-schema.org/draft/next/meta/core" } diff --git a/remotes/draft-next/metaschema-optional-vocabulary.json b/remotes/draft-next/metaschema-optional-vocabulary.json index e78e531d4..1af0cad4c 100644 --- a/remotes/draft-next/metaschema-optional-vocabulary.json +++ b/remotes/draft-next/metaschema-optional-vocabulary.json @@ -6,6 +6,7 @@ "https://json-schema.org/draft/next/vocab/core": true, "http://localhost:1234/draft/next/vocab/custom": false }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/next/meta/validation" }, { "$ref": "https://json-schema.org/draft/next/meta/core" } diff --git a/remotes/draft-next/subSchemas-defs.json b/remotes/draft-next/subSchemas-defs.json deleted file mode 100644 index 75b7583ca..000000000 --- a/remotes/draft-next/subSchemas-defs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/$defs/integer" - } - } -} diff --git a/remotes/draft-next/subSchemas.json b/remotes/draft-next/subSchemas.json index 575dd00c2..75b7583ca 100644 --- a/remotes/draft-next/subSchemas.json +++ b/remotes/draft-next/subSchemas.json @@ -1,9 +1,11 @@ { "$schema": "https://json-schema.org/draft/next/schema", - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/integer" + "$defs": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/$defs/integer" + } } } diff --git a/remotes/draft2019-09/metaschema-no-validation.json b/remotes/draft2019-09/metaschema-no-validation.json index 494f0abff..859006c27 100644 --- a/remotes/draft2019-09/metaschema-no-validation.json +++ b/remotes/draft2019-09/metaschema-no-validation.json @@ -5,6 +5,7 @@ "https://json-schema.org/draft/2019-09/vocab/applicator": true, "https://json-schema.org/draft/2019-09/vocab/core": true }, + "$recursiveAnchor": true, "allOf": [ { "$ref": "https://json-schema.org/draft/2019-09/meta/applicator" }, { "$ref": "https://json-schema.org/draft/2019-09/meta/core" } diff --git a/remotes/draft2019-09/metaschema-optional-vocabulary.json b/remotes/draft2019-09/metaschema-optional-vocabulary.json index 968597c45..3a7502a21 100644 --- a/remotes/draft2019-09/metaschema-optional-vocabulary.json +++ b/remotes/draft2019-09/metaschema-optional-vocabulary.json @@ -6,6 +6,7 @@ "https://json-schema.org/draft/2019-09/vocab/core": true, "http://localhost:1234/draft/2019-09/vocab/custom": false }, + "$recursiveAnchor": true, "allOf": [ { "$ref": "https://json-schema.org/draft/2019-09/meta/validation" }, { "$ref": "https://json-schema.org/draft/2019-09/meta/core" } diff --git a/remotes/draft2019-09/subSchemas-defs.json b/remotes/draft2019-09/subSchemas-defs.json deleted file mode 100644 index fdfee68d9..000000000 --- a/remotes/draft2019-09/subSchemas-defs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/$defs/integer" - } - } -} diff --git a/remotes/draft2019-09/subSchemas.json b/remotes/draft2019-09/subSchemas.json index 6dea22525..fdfee68d9 100644 --- a/remotes/draft2019-09/subSchemas.json +++ b/remotes/draft2019-09/subSchemas.json @@ -1,9 +1,11 @@ { "$schema": "https://json-schema.org/draft/2019-09/schema", - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/integer" + "$defs": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/$defs/integer" + } } } diff --git a/remotes/draft2020-12/format-assertion-false.json b/remotes/draft2020-12/format-assertion-false.json index d6dd645b6..43a711c9d 100644 --- a/remotes/draft2020-12/format-assertion-false.json +++ b/remotes/draft2020-12/format-assertion-false.json @@ -5,6 +5,7 @@ "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/format-assertion": false }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/core" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/format-assertion" } diff --git a/remotes/draft2020-12/format-assertion-true.json b/remotes/draft2020-12/format-assertion-true.json index bb16d5864..39c6b0abf 100644 --- a/remotes/draft2020-12/format-assertion-true.json +++ b/remotes/draft2020-12/format-assertion-true.json @@ -5,6 +5,7 @@ "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/format-assertion": true }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/core" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/format-assertion" } diff --git a/remotes/draft2020-12/metaschema-no-validation.json b/remotes/draft2020-12/metaschema-no-validation.json index 85d74b213..71be8b5da 100644 --- a/remotes/draft2020-12/metaschema-no-validation.json +++ b/remotes/draft2020-12/metaschema-no-validation.json @@ -5,6 +5,7 @@ "https://json-schema.org/draft/2020-12/vocab/applicator": true, "https://json-schema.org/draft/2020-12/vocab/core": true }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/applicator" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/core" } diff --git a/remotes/draft2020-12/metaschema-optional-vocabulary.json b/remotes/draft2020-12/metaschema-optional-vocabulary.json index f38ec281d..a6963e548 100644 --- a/remotes/draft2020-12/metaschema-optional-vocabulary.json +++ b/remotes/draft2020-12/metaschema-optional-vocabulary.json @@ -6,6 +6,7 @@ "https://json-schema.org/draft/2020-12/vocab/core": true, "http://localhost:1234/draft/2020-12/vocab/custom": false }, + "$dynamicAnchor": "meta", "allOf": [ { "$ref": "https://json-schema.org/draft/2020-12/meta/validation" }, { "$ref": "https://json-schema.org/draft/2020-12/meta/core" } diff --git a/remotes/draft2020-12/subSchemas-defs.json b/remotes/draft2020-12/subSchemas-defs.json deleted file mode 100644 index 1bb4846d7..000000000 --- a/remotes/draft2020-12/subSchemas-defs.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/$defs/integer" - } - } -} diff --git a/remotes/draft2020-12/subSchemas.json b/remotes/draft2020-12/subSchemas.json index 5fca21d82..1bb4846d7 100644 --- a/remotes/draft2020-12/subSchemas.json +++ b/remotes/draft2020-12/subSchemas.json @@ -1,9 +1,11 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/integer" + "$defs": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/$defs/integer" + } } } diff --git a/remotes/subSchemas-defs.json b/remotes/draft3/subSchemas.json similarity index 62% rename from remotes/subSchemas-defs.json rename to remotes/draft3/subSchemas.json index 50b7b6dc4..6e9b3de35 100644 --- a/remotes/subSchemas-defs.json +++ b/remotes/draft3/subSchemas.json @@ -1,10 +1,10 @@ { - "$defs": { + "definitions": { "integer": { "type": "integer" }, "refToInteger": { - "$ref": "#/$defs/integer" + "$ref": "#/definitions/integer" } } } diff --git a/remotes/locationIndependentIdentifierDraft4.json b/remotes/draft4/locationIndependentIdentifier.json similarity index 100% rename from remotes/locationIndependentIdentifierDraft4.json rename to remotes/draft4/locationIndependentIdentifier.json diff --git a/remotes/name.json b/remotes/draft4/name.json similarity index 100% rename from remotes/name.json rename to remotes/draft4/name.json diff --git a/remotes/draft4/subSchemas.json b/remotes/draft4/subSchemas.json new file mode 100644 index 000000000..6e9b3de35 --- /dev/null +++ b/remotes/draft4/subSchemas.json @@ -0,0 +1,10 @@ +{ + "definitions": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/definitions/integer" + } + } +} diff --git a/remotes/locationIndependentIdentifierPre2019.json b/remotes/draft6/locationIndependentIdentifier.json similarity index 100% rename from remotes/locationIndependentIdentifierPre2019.json rename to remotes/draft6/locationIndependentIdentifier.json diff --git a/remotes/draft6/name.json b/remotes/draft6/name.json new file mode 100644 index 000000000..fceacb809 --- /dev/null +++ b/remotes/draft6/name.json @@ -0,0 +1,15 @@ +{ + "definitions": { + "orNull": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#" + } + ] + } + }, + "type": "string" +} diff --git a/remotes/ref-and-definitions.json b/remotes/draft6/ref-and-definitions.json similarity index 74% rename from remotes/ref-and-definitions.json rename to remotes/draft6/ref-and-definitions.json index e0ee802a9..b80deeb7b 100644 --- a/remotes/ref-and-definitions.json +++ b/remotes/draft6/ref-and-definitions.json @@ -1,5 +1,5 @@ { - "$id": "http://localhost:1234/ref-and-definitions.json", + "$id": "http://localhost:1234/draft6/ref-and-definitions.json", "definitions": { "inner": { "properties": { diff --git a/remotes/draft6/subSchemas.json b/remotes/draft6/subSchemas.json new file mode 100644 index 000000000..6e9b3de35 --- /dev/null +++ b/remotes/draft6/subSchemas.json @@ -0,0 +1,10 @@ +{ + "definitions": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/definitions/integer" + } + } +} diff --git a/remotes/draft7/locationIndependentIdentifier.json b/remotes/draft7/locationIndependentIdentifier.json new file mode 100644 index 000000000..e72815cd5 --- /dev/null +++ b/remotes/draft7/locationIndependentIdentifier.json @@ -0,0 +1,11 @@ +{ + "definitions": { + "refToInteger": { + "$ref": "#foo" + }, + "A": { + "$id": "#foo", + "type": "integer" + } + } +} diff --git a/remotes/draft7/name.json b/remotes/draft7/name.json new file mode 100644 index 000000000..fceacb809 --- /dev/null +++ b/remotes/draft7/name.json @@ -0,0 +1,15 @@ +{ + "definitions": { + "orNull": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#" + } + ] + } + }, + "type": "string" +} diff --git a/remotes/draft7/ref-and-definitions.json b/remotes/draft7/ref-and-definitions.json new file mode 100644 index 000000000..d5929380c --- /dev/null +++ b/remotes/draft7/ref-and-definitions.json @@ -0,0 +1,11 @@ +{ + "$id": "http://localhost:1234/draft7/ref-and-definitions.json", + "definitions": { + "inner": { + "properties": { + "bar": { "type": "string" } + } + } + }, + "allOf": [ { "$ref": "#/definitions/inner" } ] +} diff --git a/remotes/draft7/subSchemas.json b/remotes/draft7/subSchemas.json new file mode 100644 index 000000000..6e9b3de35 --- /dev/null +++ b/remotes/draft7/subSchemas.json @@ -0,0 +1,10 @@ +{ + "definitions": { + "integer": { + "type": "integer" + }, + "refToInteger": { + "$ref": "#/definitions/integer" + } + } +} diff --git a/remotes/subSchemas.json b/remotes/subSchemas.json deleted file mode 100644 index 9f8030bce..000000000 --- a/remotes/subSchemas.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "integer": { - "type": "integer" - }, - "refToInteger": { - "$ref": "#/integer" - } -} diff --git a/test-schema.json b/test-schema.json index 833931620..0087c5e3d 100644 --- a/test-schema.json +++ b/test-schema.json @@ -27,6 +27,69 @@ "type": "array", "items": { "$ref": "#/$defs/test" }, "minItems": 1 + }, + "specification":{ + "description": "A reference to a specification document which defines the behavior tested by this test case. Typically this should be a JSON Schema specification document, though in cases where the JSON Schema specification points to another RFC it should contain *both* the portion of the JSON Schema specification which indicates what RFC (and section) to follow as *well* as information on where in that specification the behavior is specified.", + + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items":{ + "properties": { + "core": { + "description": "A section in official JSON Schema core drafts", + "url": "https://json-schema.org/specification-links", + "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", + "type":"string" + }, + "validation": { + "description": "A section in official JSON Schema validation drafts", + "url": "https://json-schema.org/specification-links", + "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", + "type":"string" + }, + "ecma262": { + "description": "A section in official ECMA 262 specification for defining regular expressions", + "url": "https://262.ecma-international.org/", + "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", + "type":"string" + }, + "perl5": { + "description": "A section name in Perl documentation for defining regular expressions", + "url": "https://perldoc.perl.org/perlre", + "type":"string" + }, + "quote": { + "description": "Quote describing the test case", + "type":"string" + } + }, + "patternProperties": { + "^rfc\\d+$": { + "description": "A section in official RFC for the given rfc number", + "url": "https://www.rfc-editor.org/", + "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", + "type":"string" + }, + "^iso\\d+$": { + "description": "A section in official ISO for the given iso number", + "pattern": "^[0-9a-zA-Z]+(\\.[0-9a-zA-Z]+)*$", + "type": "string" + } + }, + "additionalProperties": { "type": "string" }, + "minProperties": 1, + "propertyNames": { + "oneOf": [ + { + "pattern": "^((iso)|(rfc))[0-9]+$" + }, + { + "enum": [ "core", "validation", "ecma262", "perl5", "quote" ] + } + ] + } + } } }, "additionalProperties": false diff --git a/tests/draft-next/additionalProperties.json b/tests/draft-next/additionalProperties.json index 7859fbbf1..51b0edada 100644 --- a/tests/draft-next/additionalProperties.json +++ b/tests/draft-next/additionalProperties.json @@ -152,5 +152,97 @@ "valid": true } ] + }, + { + "description": "additionalProperties with propertyNames", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "propertyNames": { + "maxLength": 5 + }, + "additionalProperties": { + "type": "number" + } + }, + "tests": [ + { + "description": "Valid against both keywords", + "data": { "apple": 4 }, + "valid": true + }, + { + "description": "Valid against propertyNames, but not additionalProperties", + "data": { "fig": 2, "pear": "available" }, + "valid": false + } + ] + }, + { + "description": "propertyDependencies with additionalProperties", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "properties" : {"foo2" : {}}, + "propertyDependencies": { + "foo" : {}, + "foo2": { + "bar": { + "properties": { + "buz": {} + } + } + } + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "additionalProperties doesn't consider propertyDependencies properties" , + "data": {"foo": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see buz even when foo2 is present", + "data": {"foo2": "bar", "buz": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see buz", + "data": {"buz": ""}, + "valid": false + } + ] + }, + { + "description": "dependentSchemas with additionalProperties", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "properties": {"foo2": {}}, + "dependentSchemas": { + "foo": {}, + "foo2": { + "properties": { + "bar": {} + } + } + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "additionalProperties doesn't consider dependentSchemas", + "data": {"foo": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see bar", + "data": {"bar": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see bar even when foo2 is present", + "data": {"foo2": "", "bar": ""}, + "valid": false + } + ] } ] diff --git a/tests/draft-next/anchor.json b/tests/draft-next/anchor.json index 321d84461..84d4851ca 100644 --- a/tests/draft-next/anchor.json +++ b/tests/draft-next/anchor.json @@ -81,64 +81,6 @@ } ] }, - { - "description": "$anchor inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $anchor buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "anchor_in_enum": { - "enum": [ - { - "$anchor": "my_anchor", - "type": "null" - } - ] - }, - "real_identifier_in_schema": { - "$anchor": "my_anchor", - "type": "string" - }, - "zzz_anchor_in_const": { - "const": { - "$anchor": "my_anchor", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/anchor_in_enum" }, - { "$ref": "#my_anchor" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$anchor": "my_anchor", - "type": "null" - }, - "valid": true - }, - { - "description": "in implementations that strip $anchor, this may match either $def", - "data": { - "type": "null" - }, - "valid": false - }, - { - "description": "match $ref to $anchor", - "data": "a string to match #/$defs/anchor_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $anchor", - "data": 1, - "valid": false - } - ] - }, { "description": "same $anchor with different base uri", "schema": { @@ -174,61 +116,5 @@ "valid": false } ] - }, - { - "description": "non-schema object containing an $anchor property", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "const_not_anchor": { - "const": { - "$anchor": "not_a_real_anchor" - } - } - }, - "if": { - "const": "skip not_a_real_anchor" - }, - "then": true, - "else" : { - "$ref": "#/$defs/const_not_anchor" - } - }, - "tests": [ - { - "description": "skip traversing definition for a valid result", - "data": "skip not_a_real_anchor", - "valid": true - }, - { - "description": "const at const_not_anchor does not match", - "data": 1, - "valid": false - } - ] - }, - { - "description": "invalid anchors", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "https://json-schema.org/draft/next/schema" - }, - "tests": [ - { - "description": "MUST start with a letter (and not #)", - "data": { "$anchor" : "#foo" }, - "valid": false - }, - { - "description": "JSON pointers are not valid", - "data": { "$anchor" : "/a/b" }, - "valid": false - }, - { - "description": "invalid with valid beginning", - "data": { "$anchor" : "foo#something" }, - "valid": false - } - ] } ] diff --git a/tests/draft-next/contains.json b/tests/draft-next/contains.json index c17f55ee7..8539a531d 100644 --- a/tests/draft-next/contains.json +++ b/tests/draft-next/contains.json @@ -31,31 +31,6 @@ "data": [], "valid": false }, - { - "description": "object with property matching schema (5) is valid", - "data": { "a": 3, "b": 4, "c": 5 }, - "valid": true - }, - { - "description": "object with property matching schema (6) is valid", - "data": { "a": 3, "b": 4, "c": 6 }, - "valid": true - }, - { - "description": "object with two properties matching schema (5, 6) is valid", - "data": { "a": 3, "b": 4, "c": 5, "d": 6 }, - "valid": true - }, - { - "description": "object without properties matching schema is invalid", - "data": { "a": 2, "b": 3, "c": 4 }, - "valid": false - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false - }, { "description": "not array or object is valid", "data": 42, @@ -84,21 +59,6 @@ "description": "array without item 5 is invalid", "data": [1, 2, 3, 4], "valid": false - }, - { - "description": "object with property 5 is valid", - "data": { "a": 3, "b": 4, "c": 5 }, - "valid": true - }, - { - "description": "object with two properties 5 is valid", - "data": { "a": 3, "b": 4, "c": 5, "d": 5 }, - "valid": true - }, - { - "description": "object without property 5 is invalid", - "data": { "a": 1, "b": 2, "c": 3, "d": 4 }, - "valid": false } ] }, @@ -118,16 +78,6 @@ "description": "empty array is invalid", "data": [], "valid": false - }, - { - "description": "any non-empty object is valid", - "data": { "a": "foo" }, - "valid": true - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false } ] }, @@ -149,18 +99,28 @@ "valid": false }, { - "description": "any non-empty object is invalid", - "data": ["foo"], - "valid": false + "description": "non-arrays are valid - string", + "data": "contains does not apply to strings", + "valid": true }, { - "description": "empty object is invalid", + "description": "non-arrays are valid - object", "data": {}, - "valid": false + "valid": true }, { - "description": "non-arrays/objects are valid", - "data": "contains does not apply to strings", + "description": "non-arrays are valid - number", + "data": 42, + "valid": true + }, + { + "description": "non-arrays are valid - boolean", + "data": false, + "valid": true + }, + { + "description": "non-arrays are valid - null", + "data": null, "valid": true } ] @@ -193,26 +153,6 @@ "description": "matches neither items nor contains", "data": [1, 5], "valid": false - }, - { - "description": "matches additionalProperties, does not match contains", - "data": { "a": 2, "b": 4, "c": 8 }, - "valid": false - }, - { - "description": "does not match additionalProperties, matches contains", - "data": { "a": 3, "b": 6, "c": 9 }, - "valid": false - }, - { - "description": "matches both additionalProperties and contains", - "data": { "a": 6, "b": 12 }, - "valid": true - }, - { - "description": "matches neither additionalProperties nor contains", - "data": { "a": 1, "b": 5 }, - "valid": false } ] }, @@ -235,16 +175,6 @@ "description": "empty array is invalid", "data": [], "valid": false - }, - { - "description": "any non-empty object is valid", - "data": { "a": "foo" }, - "valid": true - }, - { - "description": "empty object is invalid", - "data": {}, - "valid": false } ] }, diff --git a/tests/draft-next/dependentSchemas.json b/tests/draft-next/dependentSchemas.json index 8a8477591..86079c34c 100644 --- a/tests/draft-next/dependentSchemas.json +++ b/tests/draft-next/dependentSchemas.json @@ -132,6 +132,7 @@ { "description": "dependent subschema incompatible with root", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "properties": { "foo": {} }, diff --git a/tests/draft-next/dynamicRef.json b/tests/draft-next/dynamicRef.json index 428c83b34..30821c5b1 100644 --- a/tests/draft-next/dynamicRef.json +++ b/tests/draft-next/dynamicRef.json @@ -612,5 +612,90 @@ "valid": false } ] + }, + { + "description": "$dynamicRef points to a boolean schema", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "true": true, + "false": false + }, + "properties": { + "true": { + "$dynamicRef": "#/$defs/true" + }, + "false": { + "$dynamicRef": "#/$defs/false" + } + } + }, + "tests": [ + { + "description": "follow $dynamicRef to a true schema", + "data": { "true": 1 }, + "valid": true + }, + { + "description": "follow $dynamicRef to a false schema", + "data": { "false": 1 }, + "valid": false + } + ] + }, + { + "description": "$dynamicRef skips over intermediate resources - direct reference", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/main", + "type": "object", + "properties": { + "bar-item": { + "$ref": "item" + } + }, + "$defs": { + "bar": { + "$id": "bar", + "type": "array", + "items": { + "$ref": "item" + }, + "$defs": { + "item": { + "$id": "item", + "type": "object", + "properties": { + "content": { + "$dynamicRef": "#content" + } + }, + "$defs": { + "defaultContent": { + "$dynamicAnchor": "content", + "type": "integer" + } + } + }, + "content": { + "$dynamicAnchor": "content", + "type": "string" + } + } + } + } + }, + "tests": [ + { + "description": "integer property passes", + "data": { "bar-item": { "content": 42 } }, + "valid": true + }, + { + "description": "string property fails", + "data": { "bar-item": { "content": "value" } }, + "valid": false + } + ] } ] diff --git a/tests/draft-next/enum.json b/tests/draft-next/enum.json index 32e5af01b..e263f3901 100644 --- a/tests/draft-next/enum.json +++ b/tests/draft-next/enum.json @@ -168,6 +168,30 @@ } ] }, + { + "description": "enum with [false] does not match [0]", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "enum": [[false]] + }, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, { "description": "enum with true does not match 1", "schema": { @@ -192,6 +216,30 @@ } ] }, + { + "description": "enum with [true] does not match [1]", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "enum": [[true]] + }, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, { "description": "enum with 0 does not match false", "schema": { @@ -216,6 +264,30 @@ } ] }, + { + "description": "enum with [0] does not match [false]", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "enum": [[0]] + }, + "tests": [ + { + "description": "[false] is invalid", + "data": [false], + "valid": false + }, + { + "description": "[0] is valid", + "data": [0], + "valid": true + }, + { + "description": "[0.0] is valid", + "data": [0.0], + "valid": true + } + ] + }, { "description": "enum with 1 does not match true", "schema": { @@ -240,6 +312,30 @@ } ] }, + { + "description": "enum with [1] does not match [true]", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "enum": [[1]] + }, + "tests": [ + { + "description": "[true] is invalid", + "data": [true], + "valid": false + }, + { + "description": "[1] is valid", + "data": [1], + "valid": true + }, + { + "description": "[1.0] is valid", + "data": [1.0], + "valid": true + } + ] + }, { "description": "nul characters in strings", "schema": { diff --git a/tests/draft-next/id.json b/tests/draft-next/id.json deleted file mode 100644 index 9b3a591f0..000000000 --- a/tests/draft-next/id.json +++ /dev/null @@ -1,294 +0,0 @@ -[ - { - "description": "Invalid use of fragments in location-independent $id", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "https://json-schema.org/draft/next/schema" - }, - "tests": [ - { - "description": "Identifier name", - "data": { - "$ref": "#foo", - "$defs": { - "A": { - "$id": "#foo", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name and no ref", - "data": { - "$defs": { - "A": { "$id": "#foo" } - } - }, - "valid": false - }, - { - "description": "Identifier path", - "data": { - "$ref": "#/a/b", - "$defs": { - "A": { - "$id": "#/a/b", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft-next/bar#foo", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft-next/bar#foo", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier path with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft-next/bar#/a/b", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft-next/bar#/a/b", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft-next/root", - "$ref": "http://localhost:1234/draft-next/nested.json#foo", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#foo", - "type": "integer" - } - } - } - } - }, - "valid": false - }, - { - "description": "Identifier path with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft-next/root", - "$ref": "http://localhost:1234/draft-next/nested.json#/a/b", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#/a/b", - "type": "integer" - } - } - } - } - }, - "valid": false - } - ] - }, - { - "description": "Valid use of empty fragments in location-independent $id", - "comment": "These are allowed but discouraged", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "https://json-schema.org/draft/next/schema" - }, - "tests": [ - { - "description": "Identifier name with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft-next/bar", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft-next/bar#", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Identifier name with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft-next/root", - "$ref": "http://localhost:1234/draft-next/nested.json#/$defs/B", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#", - "type": "integer" - } - } - } - } - }, - "valid": true - } - ] - }, - { - "description": "Unnormalized $ids are allowed but discouraged", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "https://json-schema.org/draft/next/schema" - }, - "tests": [ - { - "description": "Unnormalized identifier", - "data": { - "$ref": "http://localhost:1234/draft-next/foo/baz", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft-next/foo/bar/../baz", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier and no ref", - "data": { - "$defs": { - "A": { - "$id": "http://localhost:1234/draft-next/foo/bar/../baz", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier with empty fragment", - "data": { - "$ref": "http://localhost:1234/draft-next/foo/baz", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft-next/foo/bar/../baz#", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier with empty fragment and no ref", - "data": { - "$defs": { - "A": { - "$id": "http://localhost:1234/draft-next/foo/bar/../baz#", - "type": "integer" - } - } - }, - "valid": true - } - ] - }, - { - "description": "$id inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $id buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "id_in_enum": { - "enum": [ - { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "null" - } - ] - }, - "real_id_in_schema": { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "string" - }, - "zzz_id_in_const": { - "const": { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "https://localhost:1234/draft-next/id/my_identifier.json" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$id": "https://localhost:1234/draft-next/id/my_identifier.json", - "type": "null" - }, - "valid": true - }, - { - "description": "match $ref to $id", - "data": "a string to match #/$defs/id_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $id", - "data": 1, - "valid": false - } - ] - }, - { - "description": "non-schema object containing an $id property", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$defs": { - "const_not_id": { - "const": { - "$id": "not_a_real_id" - } - } - }, - "if": { - "const": "skip not_a_real_id" - }, - "then": true, - "else" : { - "$ref": "#/$defs/const_not_id" - } - }, - "tests": [ - { - "description": "skip traversing definition for a valid result", - "data": "skip not_a_real_id", - "valid": true - }, - { - "description": "const at const_not_id does not match", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft-next/items.json b/tests/draft-next/items.json index 459943bef..dfb79af2f 100644 --- a/tests/draft-next/items.json +++ b/tests/draft-next/items.json @@ -265,6 +265,26 @@ } ] }, + { + "description": "items with heterogeneous array", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "prefixItems": [{}], + "items": false + }, + "tests": [ + { + "description": "heterogeneous invalid instance", + "data": [ "foo", "bar", 37 ], + "valid": false + }, + { + "description": "valid instance", + "data": [ null ], + "valid": true + } + ] + }, { "description": "items with null instance elements", "schema": { diff --git a/tests/draft-next/maxContains.json b/tests/draft-next/maxContains.json index 7c1515753..5af6e4c13 100644 --- a/tests/draft-next/maxContains.json +++ b/tests/draft-next/maxContains.json @@ -15,16 +15,6 @@ "description": "two items still valid against lone maxContains", "data": [1, 2], "valid": true - }, - { - "description": "one property valid against lone maxContains", - "data": { "a": 1 }, - "valid": true - }, - { - "description": "two properties still valid against lone maxContains", - "data": { "a": 1, "b": 2 }, - "valid": true } ] }, @@ -60,31 +50,6 @@ "description": "some elements match, invalid maxContains", "data": [1, 2, 1], "valid": false - }, - { - "description": "empty object", - "data": {}, - "valid": false - }, - { - "description": "all properties match, valid maxContains", - "data": { "a": 1 }, - "valid": true - }, - { - "description": "all properties match, invalid maxContains", - "data": { "a": 1, "b": 1 }, - "valid": false - }, - { - "description": "some properties match, valid maxContains", - "data": { "a": 1, "b": 2 }, - "valid": true - }, - { - "description": "some properties match, invalid maxContains", - "data": { "a": 1, "b": 2, "c": 1 }, - "valid": false } ] }, @@ -131,21 +96,6 @@ "description": "array with minContains < maxContains < actual", "data": [1, 1, 1, 1], "valid": false - }, - { - "description": "object with actual < minContains < maxContains", - "data": {}, - "valid": false - }, - { - "description": "object with minContains < actual < maxContains", - "data": { "a": 1, "b": 1 }, - "valid": true - }, - { - "description": "object with minContains < maxContains < actual", - "data": { "a": 1, "b": 1, "c": 1, "d": 1 }, - "valid": false } ] } diff --git a/tests/draft-next/maxLength.json b/tests/draft-next/maxLength.json index e09e44ad8..c88f604ef 100644 --- a/tests/draft-next/maxLength.json +++ b/tests/draft-next/maxLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "two supplementary Unicode code points is long enough", + "description": "two graphemes is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft-next/minLength.json b/tests/draft-next/minLength.json index 16022acb5..52c9c9a14 100644 --- a/tests/draft-next/minLength.json +++ b/tests/draft-next/minLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "one supplementary Unicode code point is not long enough", + "description": "one grapheme is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft-next/oneOf.json b/tests/draft-next/oneOf.json index e8c077131..840d1579d 100644 --- a/tests/draft-next/oneOf.json +++ b/tests/draft-next/oneOf.json @@ -220,7 +220,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/next/schema", diff --git a/tests/draft-next/optional/anchor.json b/tests/draft-next/optional/anchor.json new file mode 100644 index 000000000..1de0b7a70 --- /dev/null +++ b/tests/draft-next/optional/anchor.json @@ -0,0 +1,60 @@ +[ + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft-next/optional/dynamicRef.json b/tests/draft-next/optional/dynamicRef.json new file mode 100644 index 000000000..dcace154e --- /dev/null +++ b/tests/draft-next/optional/dynamicRef.json @@ -0,0 +1,56 @@ +[ + { + "description": "$dynamicRef skips over intermediate resources - pointer reference across resource boundary", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/optional/main", + "type": "object", + "properties": { + "bar-item": { + "$ref": "bar#/$defs/item" + } + }, + "$defs": { + "bar": { + "$id": "bar", + "type": "array", + "items": { + "$ref": "item" + }, + "$defs": { + "item": { + "$id": "item", + "type": "object", + "properties": { + "content": { + "$dynamicRef": "#content" + } + }, + "$defs": { + "defaultContent": { + "$dynamicAnchor": "content", + "type": "integer" + } + } + }, + "content": { + "$dynamicAnchor": "content", + "type": "string" + } + } + } + } + }, + "tests": [ + { + "description": "integer property passes", + "data": { "bar-item": { "content": 42 } }, + "valid": true + }, + { + "description": "string property fails", + "data": { "bar-item": { "content": "value" } }, + "valid": false + } + ] + }] \ No newline at end of file diff --git a/tests/draft-next/optional/ecmascript-regex.json b/tests/draft-next/optional/ecmascript-regex.json index 272114503..a1a4f9638 100644 --- a/tests/draft-next/optional/ecmascript-regex.json +++ b/tests/draft-next/optional/ecmascript-regex.json @@ -405,20 +405,6 @@ } ] }, - { - "description": "\\a is not an ECMA 262 control escape", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "https://json-schema.org/draft/next/schema" - }, - "tests": [ - { - "description": "when used as a pattern", - "data": { "pattern": "\\a" }, - "valid": false - } - ] - }, { "description": "pattern with non-ASCII digits", "schema": { diff --git a/tests/draft-next/optional/format/duration.json b/tests/draft-next/optional/format/duration.json index d5adca206..c4aa66bae 100644 --- a/tests/draft-next/optional/format/duration.json +++ b/tests/draft-next/optional/format/duration.json @@ -46,6 +46,11 @@ "data": "PT1D", "valid": false }, + { + "description": "must start with P", + "data": "4DT12H30M5S", + "valid": false + }, { "description": "no elements present", "data": "P", diff --git a/tests/draft-next/optional/format/ecmascript-regex.json b/tests/draft-next/optional/format/ecmascript-regex.json new file mode 100644 index 000000000..1e19c2729 --- /dev/null +++ b/tests/draft-next/optional/format/ecmascript-regex.json @@ -0,0 +1,16 @@ +[ + { + "description": "\\a is not an ECMA 262 control escape", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "format": "regex" + }, + "tests": [ + { + "description": "when used as a pattern", + "data": "\\a", + "valid": false + } + ] + } +] diff --git a/tests/draft-next/optional/format/hostname.json b/tests/draft-next/optional/format/hostname.json index bfb306363..bc3a60dcc 100644 --- a/tests/draft-next/optional/format/hostname.json +++ b/tests/draft-next/optional/format/hostname.json @@ -120,6 +120,16 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft-next/optional/format/idn-hostname.json b/tests/draft-next/optional/format/idn-hostname.json index ee2e792fa..1061f4243 100644 --- a/tests/draft-next/optional/format/idn-hostname.json +++ b/tests/draft-next/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -301,6 +301,88 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true + }, + { + "description": "single label", + "data": "hostname", + "valid": true + }, + { + "description": "single label with hyphen", + "data": "host-name", + "valid": true + }, + { + "description": "single label with digits", + "data": "h0stn4me", + "valid": true + }, + { + "description": "single label starting with digit", + "data": "1host", + "valid": true + }, + { + "description": "single label ending with digit", + "data": "hostnam3", + "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "format": "idn-hostname" + }, + "tests": [ + { + "description": "single dot", + "data": ".", + "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft-next/optional/format/ipv4.json b/tests/draft-next/optional/format/ipv4.json index e3e944015..2a4bc2b2f 100644 --- a/tests/draft-next/optional/format/ipv4.json +++ b/tests/draft-next/optional/format/ipv4.json @@ -81,6 +81,11 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false + }, + { + "description": "netmask is not a part of ipv4 address", + "data": "192.168.1.0/24", + "valid": false } ] } diff --git a/tests/draft-next/optional/id.json b/tests/draft-next/optional/id.json new file mode 100644 index 000000000..fc26f26c2 --- /dev/null +++ b/tests/draft-next/optional/id.json @@ -0,0 +1,53 @@ +[ + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/draft-next/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/draft-next/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft-next/optional/refOfUnknownKeyword.json b/tests/draft-next/optional/refOfUnknownKeyword.json index 489701cd2..c832e09f6 100644 --- a/tests/draft-next/optional/refOfUnknownKeyword.json +++ b/tests/draft-next/optional/refOfUnknownKeyword.json @@ -42,5 +42,28 @@ "valid": false } ] + }, + { + "description": "reference internals of known non-applicator", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "/base", + "examples": [ + { "type": "string" } + ], + "$ref": "#/examples/0" + }, + "tests": [ + { + "description": "match", + "data": "a string", + "valid": true + }, + { + "description": "mismatch", + "data": 42, + "valid": false + } + ] } ] diff --git a/tests/draft-next/unknownKeyword.json b/tests/draft-next/optional/unknownKeyword.json similarity index 100% rename from tests/draft-next/unknownKeyword.json rename to tests/draft-next/optional/unknownKeyword.json diff --git a/tests/draft-next/ref.json b/tests/draft-next/ref.json index 1d5f25613..8417ce299 100644 --- a/tests/draft-next/ref.json +++ b/tests/draft-next/ref.json @@ -862,6 +862,7 @@ { "description": "URN ref with nested pointer ref", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { @@ -887,6 +888,7 @@ { "description": "ref to if", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", @@ -909,6 +911,7 @@ { "description": "ref to then", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", @@ -931,6 +934,7 @@ { "description": "ref to else", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", @@ -953,6 +957,7 @@ { "description": "ref with absolute-path-reference", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { @@ -982,6 +987,7 @@ { "description": "$id with file URI still resolves pointers - *nix", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { @@ -1006,6 +1012,7 @@ { "description": "$id with file URI still resolves pointers - windows", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { @@ -1030,6 +1037,7 @@ { "description": "empty tokens in $ref json-pointer", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$defs": { "": { "$defs": { diff --git a/tests/draft-next/refRemote.json b/tests/draft-next/refRemote.json index 9befceb25..647fb9f19 100644 --- a/tests/draft-next/refRemote.json +++ b/tests/draft-next/refRemote.json @@ -22,7 +22,7 @@ "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "http://localhost:1234/draft-next/subSchemas-defs.json#/$defs/integer" + "$ref": "http://localhost:1234/draft-next/subSchemas.json#/$defs/integer" }, "tests": [ { @@ -60,7 +60,7 @@ "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/next/schema", - "$ref": "http://localhost:1234/draft-next/subSchemas-defs.json#/$defs/refToInteger" + "$ref": "http://localhost:1234/draft-next/subSchemas.json#/$defs/refToInteger" }, "tests": [ { @@ -265,7 +265,10 @@ }, { "description": "remote HTTP ref with different $id", - "schema": {"$ref": "http://localhost:1234/different-id-ref-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "http://localhost:1234/different-id-ref-string.json" + }, "tests": [ { "description": "number is invalid", @@ -281,7 +284,10 @@ }, { "description": "remote HTTP ref with different URN $id", - "schema": {"$ref": "http://localhost:1234/urn-ref-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "http://localhost:1234/urn-ref-string.json" + }, "tests": [ { "description": "number is invalid", @@ -297,7 +303,10 @@ }, { "description": "remote HTTP ref with nested absolute ref", - "schema": {"$ref": "http://localhost:1234/nested-absolute-ref-to-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" + }, "tests": [ { "description": "number is invalid", @@ -314,6 +323,7 @@ { "description": "$ref to $ref finds detached $anchor", "schema": { + "$schema": "https://json-schema.org/draft/next/schema", "$ref": "http://localhost:1234/draft-next/detached-ref.json#/$defs/foo" }, "tests": [ diff --git a/tests/draft-next/unevaluatedItems.json b/tests/draft-next/unevaluatedItems.json index 7379afb41..08f6ef128 100644 --- a/tests/draft-next/unevaluatedItems.json +++ b/tests/draft-next/unevaluatedItems.json @@ -461,6 +461,79 @@ } ] }, + { + "description": "unevaluatedItems before $ref", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "unevaluatedItems": false, + "prefixItems": [ + { "type": "string" } + ], + "$ref": "#/$defs/bar", + "$defs": { + "bar": { + "prefixItems": [ + true, + { "type": "string" } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with $dynamicRef", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://example.com/unevaluated-items-with-dynamic-ref/derived", + + "$ref": "./baseSchema", + + "$defs": { + "derived": { + "$dynamicAnchor": "addons", + "prefixItems": [ + true, + { "type": "string" } + ] + }, + "baseSchema": { + "$id": "./baseSchema", + + "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", + "unevaluatedItems": false, + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "$dynamicRef": "#addons" + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, { "description": "unevaluatedItems can't see inside cousins", "schema": { diff --git a/tests/draft-next/unevaluatedProperties.json b/tests/draft-next/unevaluatedProperties.json index 69fe8a00c..13fe6e03a 100644 --- a/tests/draft-next/unevaluatedProperties.json +++ b/tests/draft-next/unevaluatedProperties.json @@ -715,6 +715,92 @@ } ] }, + { + "description": "unevaluatedProperties before $ref", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "type": "object", + "unevaluatedProperties": false, + "properties": { + "foo": { "type": "string" } + }, + "$ref": "#/$defs/bar", + "$defs": { + "bar": { + "properties": { + "bar": { "type": "string" } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with $dynamicRef", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "$id": "https://example.com/unevaluated-properties-with-dynamic-ref/derived", + + "$ref": "./baseSchema", + + "$defs": { + "derived": { + "$dynamicAnchor": "addons", + "properties": { + "bar": { "type": "string" } + } + }, + "baseSchema": { + "$id": "./baseSchema", + + "$comment": "unevaluatedProperties comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", + "unevaluatedProperties": false, + "type": "object", + "properties": { + "foo": { "type": "string" } + }, + "$dynamicRef": "#addons" + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { @@ -1365,57 +1451,6 @@ } ] }, - { - "description": "unevaluatedProperties depends on adjacent contains", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "properties": { - "foo": { "type": "number" } - }, - "contains": { "type": "string" }, - "unevaluatedProperties": false - }, - "tests": [ - { - "description": "bar is evaluated by contains", - "data": { "foo": 1, "bar": "foo" }, - "valid": true - }, - { - "description": "contains fails, bar is not evaluated", - "data": { "foo": 1, "bar": 2 }, - "valid": false - }, - { - "description": "contains passes, bar is not evaluated", - "data": { "foo": 1, "bar": 2, "baz": "foo" }, - "valid": false - } - ] - }, - { - "description": "unevaluatedProperties depends on multiple nested contains", - "schema": { - "$schema": "https://json-schema.org/draft/next/schema", - "allOf": [ - { "contains": { "multipleOf": 2 } }, - { "contains": { "multipleOf": 3 } } - ], - "unevaluatedProperties": { "multipleOf": 5 } - }, - "tests": [ - { - "description": "5 not evaluated, passes unevaluatedItems", - "data": { "a": 2, "b": 3, "c": 4, "d": 5, "e": 6 }, - "valid": true - }, - { - "description": "7 not evaluated, fails unevaluatedItems", - "data": { "a": 2, "b": 3, "c": 4, "d": 7, "e": 8 }, - "valid": false - } - ] - }, { "description": "non-object instances are valid", "schema": { @@ -1568,5 +1603,74 @@ "valid": false } ] + }, + { + "description": "propertyDependencies with unevaluatedProperties" , + "schema" : { + "$schema": "https://json-schema.org/draft/next/schema", + "properties" : {"foo2" : {}}, + "propertyDependencies": { + "foo" : {}, + "foo2": { + "bar": { + "properties": { + "buz": {} + } + } + } + }, + "unevaluatedProperties": false + }, + + "tests": [ + { + "description": "unevaluatedProperties doesn't consider propertyDependencies" , + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "unevaluatedProperties sees buz when foo2 is present", + "data": {"foo2": "bar", "buz": ""}, + "valid": true + }, + { + "description": "unevaluatedProperties doesn't see buz when foo2 is absent", + "data": {"buz": ""}, + "valid": false + } + ] + }, + { + "description": "dependentSchemas with unevaluatedProperties", + "schema": { + "$schema": "https://json-schema.org/draft/next/schema", + "properties": {"foo2": {}}, + "dependentSchemas": { + "foo" : {}, + "foo2": { + "properties": { + "bar":{} + } + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "unevaluatedProperties doesn't consider dependentSchemas", + "data": {"foo": ""}, + "valid": false + }, + { + "description": "unevaluatedProperties doesn't see bar when foo2 is absent", + "data": {"bar": ""}, + "valid": false + }, + { + "description": "unevaluatedProperties sees bar when foo2 is present", + "data": {"foo2": "", "bar": ""}, + "valid": true + } + ] } ] diff --git a/tests/draft2019-09/additionalItems.json b/tests/draft2019-09/additionalItems.json index aa44bcb76..9a7ae4f8a 100644 --- a/tests/draft2019-09/additionalItems.json +++ b/tests/draft2019-09/additionalItems.json @@ -182,6 +182,26 @@ } ] }, + { + "description": "additionalItems with heterogeneous array", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "items": [{}], + "additionalItems": false + }, + "tests": [ + { + "description": "heterogeneous invalid instance", + "data": [ "foo", "bar", 37 ], + "valid": false + }, + { + "description": "valid instance", + "data": [ null ], + "valid": true + } + ] + }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft2019-09/additionalProperties.json b/tests/draft2019-09/additionalProperties.json index f9f03bb04..73f9b909e 100644 --- a/tests/draft2019-09/additionalProperties.json +++ b/tests/draft2019-09/additionalProperties.json @@ -152,5 +152,62 @@ "valid": true } ] + }, + { + "description": "additionalProperties with propertyNames", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "propertyNames": { + "maxLength": 5 + }, + "additionalProperties": { + "type": "number" + } + }, + "tests": [ + { + "description": "Valid against both keywords", + "data": { "apple": 4 }, + "valid": true + }, + { + "description": "Valid against propertyNames, but not additionalProperties", + "data": { "fig": 2, "pear": "available" }, + "valid": false + } + ] + }, + { + "description": "dependentSchemas with additionalProperties", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "properties": {"foo2": {}}, + "dependentSchemas": { + "foo" : {}, + "foo2": { + "properties": { + "bar":{} + } + } + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "additionalProperties doesn't consider dependentSchemas", + "data": {"foo": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see bar", + "data": {"bar": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see bar even when foo2 is present", + "data": { "foo2": "", "bar": ""}, + "valid": false + } + ] } ] diff --git a/tests/draft2019-09/anchor.json b/tests/draft2019-09/anchor.json index 5d8c86f11..bce05e800 100644 --- a/tests/draft2019-09/anchor.json +++ b/tests/draft2019-09/anchor.json @@ -81,64 +81,6 @@ } ] }, - { - "description": "$anchor inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $anchor buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "anchor_in_enum": { - "enum": [ - { - "$anchor": "my_anchor", - "type": "null" - } - ] - }, - "real_identifier_in_schema": { - "$anchor": "my_anchor", - "type": "string" - }, - "zzz_anchor_in_const": { - "const": { - "$anchor": "my_anchor", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/anchor_in_enum" }, - { "$ref": "#my_anchor" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$anchor": "my_anchor", - "type": "null" - }, - "valid": true - }, - { - "description": "in implementations that strip $anchor, this may match either $def", - "data": { - "type": "null" - }, - "valid": false - }, - { - "description": "match $ref to $anchor", - "data": "a string to match #/$defs/anchor_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $anchor", - "data": 1, - "valid": false - } - ] - }, { "description": "same $anchor with different base uri", "schema": { @@ -174,62 +116,5 @@ "valid": false } ] - }, - { - "description": "non-schema object containing an $anchor property", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "const_not_anchor": { - "const": { - "$anchor": "not_a_real_anchor" - } - } - }, - "if": { - "const": "skip not_a_real_anchor" - }, - "then": true, - "else" : { - "$ref": "#/$defs/const_not_anchor" - } - }, - "tests": [ - { - "description": "skip traversing definition for a valid result", - "data": "skip not_a_real_anchor", - "valid": true - }, - { - "description": "const at const_not_anchor does not match", - "data": 1, - "valid": false - } - ] - }, - { - "description": "invalid anchors", - "comment": "Section 8.2.3", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "https://json-schema.org/draft/2019-09/schema" - }, - "tests": [ - { - "description": "MUST start with a letter (and not #)", - "data": { "$anchor" : "#foo" }, - "valid": false - }, - { - "description": "JSON pointers are not valid", - "data": { "$anchor" : "/a/b" }, - "valid": false - }, - { - "description": "invalid with valid beginning", - "data": { "$anchor" : "foo#something" }, - "valid": false - } - ] } ] diff --git a/tests/draft2019-09/dependentSchemas.json b/tests/draft2019-09/dependentSchemas.json index 3577efdf4..c5b8ea05f 100644 --- a/tests/draft2019-09/dependentSchemas.json +++ b/tests/draft2019-09/dependentSchemas.json @@ -132,6 +132,7 @@ { "description": "dependent subschema incompatible with root", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "properties": { "foo": {} }, diff --git a/tests/draft2019-09/enum.json b/tests/draft2019-09/enum.json index f9a44a61d..1315211ea 100644 --- a/tests/draft2019-09/enum.json +++ b/tests/draft2019-09/enum.json @@ -168,6 +168,30 @@ } ] }, + { + "description": "enum with [false] does not match [0]", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "enum": [[false]] + }, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, { "description": "enum with true does not match 1", "schema": { @@ -192,6 +216,30 @@ } ] }, + { + "description": "enum with [true] does not match [1]", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "enum": [[true]] + }, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, { "description": "enum with 0 does not match false", "schema": { @@ -216,6 +264,30 @@ } ] }, + { + "description": "enum with [0] does not match [false]", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "enum": [[0]] + }, + "tests": [ + { + "description": "[false] is invalid", + "data": [false], + "valid": false + }, + { + "description": "[0] is valid", + "data": [0], + "valid": true + }, + { + "description": "[0.0] is valid", + "data": [0.0], + "valid": true + } + ] + }, { "description": "enum with 1 does not match true", "schema": { @@ -240,6 +312,30 @@ } ] }, + { + "description": "enum with [1] does not match [true]", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "enum": [[1]] + }, + "tests": [ + { + "description": "[true] is invalid", + "data": [true], + "valid": false + }, + { + "description": "[1] is valid", + "data": [1], + "valid": true + }, + { + "description": "[1.0] is valid", + "data": [1.0], + "valid": true + } + ] + }, { "description": "nul characters in strings", "schema": { diff --git a/tests/draft2019-09/id.json b/tests/draft2019-09/id.json deleted file mode 100644 index e2e403f0b..000000000 --- a/tests/draft2019-09/id.json +++ /dev/null @@ -1,294 +0,0 @@ -[ - { - "description": "Invalid use of fragments in location-independent $id", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "https://json-schema.org/draft/2019-09/schema" - }, - "tests": [ - { - "description": "Identifier name", - "data": { - "$ref": "#foo", - "$defs": { - "A": { - "$id": "#foo", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name and no ref", - "data": { - "$defs": { - "A": { "$id": "#foo" } - } - }, - "valid": false - }, - { - "description": "Identifier path", - "data": { - "$ref": "#/a/b", - "$defs": { - "A": { - "$id": "#/a/b", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft2019-09/bar#foo", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2019-09/bar#foo", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier path with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft2019-09/bar#/a/b", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2019-09/bar#/a/b", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft2019-09/root", - "$ref": "http://localhost:1234/draft2019-09/nested.json#foo", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#foo", - "type": "integer" - } - } - } - } - }, - "valid": false - }, - { - "description": "Identifier path with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft2019-09/root", - "$ref": "http://localhost:1234/draft2019-09/nested.json#/a/b", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#/a/b", - "type": "integer" - } - } - } - } - }, - "valid": false - } - ] - }, - { - "description": "Valid use of empty fragments in location-independent $id", - "comment": "These are allowed but discouraged", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "https://json-schema.org/draft/2019-09/schema" - }, - "tests": [ - { - "description": "Identifier name with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft2019-09/bar", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2019-09/bar#", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Identifier name with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft2019-09/root", - "$ref": "http://localhost:1234/draft2019-09/nested.json#/$defs/B", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#", - "type": "integer" - } - } - } - } - }, - "valid": true - } - ] - }, - { - "description": "Unnormalized $ids are allowed but discouraged", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "https://json-schema.org/draft/2019-09/schema" - }, - "tests": [ - { - "description": "Unnormalized identifier", - "data": { - "$ref": "http://localhost:1234/draft2019-09/foo/baz", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier and no ref", - "data": { - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier with empty fragment", - "data": { - "$ref": "http://localhost:1234/draft2019-09/foo/baz", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz#", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier with empty fragment and no ref", - "data": { - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2019-09/foo/bar/../baz#", - "type": "integer" - } - } - }, - "valid": true - } - ] - }, - { - "description": "$id inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $id buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "id_in_enum": { - "enum": [ - { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "null" - } - ] - }, - "real_id_in_schema": { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "string" - }, - "zzz_id_in_const": { - "const": { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "https://localhost:1234/draft2019-09/id/my_identifier.json" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", - "type": "null" - }, - "valid": true - }, - { - "description": "match $ref to $id", - "data": "a string to match #/$defs/id_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $id", - "data": 1, - "valid": false - } - ] - }, - { - "description": "non-schema object containing an $id property", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$defs": { - "const_not_id": { - "const": { - "$id": "not_a_real_id" - } - } - }, - "if": { - "const": "skip not_a_real_id" - }, - "then": true, - "else" : { - "$ref": "#/$defs/const_not_id" - } - }, - "tests": [ - { - "description": "skip traversing definition for a valid result", - "data": "skip not_a_real_id", - "valid": true - }, - { - "description": "const at const_not_id does not match", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft2019-09/maxLength.json b/tests/draft2019-09/maxLength.json index f242c3eff..a0cc7d9b8 100644 --- a/tests/draft2019-09/maxLength.json +++ b/tests/draft2019-09/maxLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "two supplementary Unicode code points is long enough", + "description": "two graphemes is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft2019-09/minLength.json b/tests/draft2019-09/minLength.json index 19dec2cac..12782660c 100644 --- a/tests/draft2019-09/minLength.json +++ b/tests/draft2019-09/minLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "one supplementary Unicode code point is not long enough", + "description": "one grapheme is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft2019-09/not.json b/tests/draft2019-09/not.json index 62c9af9de..d90728c7b 100644 --- a/tests/draft2019-09/not.json +++ b/tests/draft2019-09/not.json @@ -97,25 +97,173 @@ ] }, { - "description": "not with boolean schema true", + "description": "forbid everything with empty schema", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "not": {} + }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": true }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false } ] }, { - "description": "not with boolean schema false", + "description": "allow everything with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "double negation", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "not": { "not": {} } + }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft2019-09/oneOf.json b/tests/draft2019-09/oneOf.json index 9b7a2204e..c27d4865c 100644 --- a/tests/draft2019-09/oneOf.json +++ b/tests/draft2019-09/oneOf.json @@ -220,7 +220,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", diff --git a/tests/draft2019-09/optional/anchor.json b/tests/draft2019-09/optional/anchor.json new file mode 100644 index 000000000..45951d0a3 --- /dev/null +++ b/tests/draft2019-09/optional/anchor.json @@ -0,0 +1,60 @@ +[ + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft2019-09/optional/format/duration.json b/tests/draft2019-09/optional/format/duration.json index 00d5f47ae..2d515a64a 100644 --- a/tests/draft2019-09/optional/format/duration.json +++ b/tests/draft2019-09/optional/format/duration.json @@ -46,6 +46,11 @@ "data": "PT1D", "valid": false }, + { + "description": "must start with P", + "data": "4DT12H30M5S", + "valid": false + }, { "description": "no elements present", "data": "P", diff --git a/tests/draft2019-09/optional/format/hostname.json b/tests/draft2019-09/optional/format/hostname.json index f3b7181c8..24bfdfc5a 100644 --- a/tests/draft2019-09/optional/format/hostname.json +++ b/tests/draft2019-09/optional/format/hostname.json @@ -120,6 +120,16 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft2019-09/optional/format/idn-hostname.json b/tests/draft2019-09/optional/format/idn-hostname.json index 72f179751..348c504c8 100644 --- a/tests/draft2019-09/optional/format/idn-hostname.json +++ b/tests/draft2019-09/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -301,6 +301,88 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true + }, + { + "description": "single label", + "data": "hostname", + "valid": true + }, + { + "description": "single label with hyphen", + "data": "host-name", + "valid": true + }, + { + "description": "single label with digits", + "data": "h0stn4me", + "valid": true + }, + { + "description": "single label starting with digit", + "data": "1host", + "valid": true + }, + { + "description": "single label ending with digit", + "data": "hostnam3", + "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "format": "idn-hostname" + }, + "tests": [ + { + "description": "single dot", + "data": ".", + "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft2019-09/optional/format/ipv4.json b/tests/draft2019-09/optional/format/ipv4.json index ac1e14c68..efe42471b 100644 --- a/tests/draft2019-09/optional/format/ipv4.json +++ b/tests/draft2019-09/optional/format/ipv4.json @@ -81,6 +81,11 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false + }, + { + "description": "netmask is not a part of ipv4 address", + "data": "192.168.1.0/24", + "valid": false } ] } diff --git a/tests/draft2019-09/optional/id.json b/tests/draft2019-09/optional/id.json new file mode 100644 index 000000000..4daa8f51f --- /dev/null +++ b/tests/draft2019-09/optional/id.json @@ -0,0 +1,53 @@ +[ + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/draft2019-09/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/draft2019-09/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft2019-09/optional/refOfUnknownKeyword.json b/tests/draft2019-09/optional/refOfUnknownKeyword.json index eee1c33ed..e9a75dd1e 100644 --- a/tests/draft2019-09/optional/refOfUnknownKeyword.json +++ b/tests/draft2019-09/optional/refOfUnknownKeyword.json @@ -42,5 +42,28 @@ "valid": false } ] + }, + { + "description": "reference internals of known non-applicator", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "/base", + "examples": [ + { "type": "string" } + ], + "$ref": "#/examples/0" + }, + "tests": [ + { + "description": "match", + "data": "a string", + "valid": true + }, + { + "description": "mismatch", + "data": 42, + "valid": false + } + ] } ] diff --git a/tests/draft2019-09/unknownKeyword.json b/tests/draft2019-09/optional/unknownKeyword.json similarity index 100% rename from tests/draft2019-09/unknownKeyword.json rename to tests/draft2019-09/optional/unknownKeyword.json diff --git a/tests/draft2019-09/propertyNames.json b/tests/draft2019-09/propertyNames.json index b7fecbf71..3b2bb23bb 100644 --- a/tests/draft2019-09/propertyNames.json +++ b/tests/draft2019-09/propertyNames.json @@ -111,5 +111,58 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "propertyNames": {"const": "foo"} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "propertyNames": {"enum": ["foo", "bar"]} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] diff --git a/tests/draft2019-09/ref.json b/tests/draft2019-09/ref.json index 7d850414d..eff5305c3 100644 --- a/tests/draft2019-09/ref.json +++ b/tests/draft2019-09/ref.json @@ -791,21 +791,6 @@ } ] }, - { - "description": "URN base URI with f-component", - "schema": { - "$schema": "https://json-schema.org/draft/2019-09/schema", - "$comment": "RFC 8141 §2.3.3, but we don't allow fragments", - "$ref": "https://json-schema.org/draft/2019-09/schema" - }, - "tests": [ - { - "description": "is invalid", - "data": {"$id": "urn:example:foo-bar-baz-qux#somepart"}, - "valid": false - } - ] - }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { @@ -862,6 +847,7 @@ { "description": "URN ref with nested pointer ref", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { @@ -887,6 +873,7 @@ { "description": "ref to if", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", @@ -909,6 +896,7 @@ { "description": "ref to then", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", @@ -931,6 +919,7 @@ { "description": "ref to else", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", @@ -953,6 +942,7 @@ { "description": "ref with absolute-path-reference", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { @@ -982,6 +972,7 @@ { "description": "$id with file URI still resolves pointers - *nix", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { @@ -1006,6 +997,7 @@ { "description": "$id with file URI still resolves pointers - windows", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { @@ -1030,6 +1022,7 @@ { "description": "empty tokens in $ref json-pointer", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$defs": { "": { "$defs": { @@ -1055,5 +1048,43 @@ "valid": false } ] - } + }, + { + "description": "$ref with $recursiveAnchor", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://example.com/schemas/unevaluated-items-are-disallowed", + "$ref": "/schemas/unevaluated-items-are-allowed", + "$recursiveAnchor": true, + "unevaluatedItems": false, + "$defs": { + "/schemas/unevaluated-items-are-allowed": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "/schemas/unevaluated-items-are-allowed", + "$recursiveAnchor": true, + "type": "array", + "items": [ + { + "type": "string" + }, + { + "$ref": "#" + } + ] + } + } + }, + "tests": [ + { + "description": "extra items allowed for inner arrays", + "data" : ["foo",["bar" , [] , 8]], + "valid": true + }, + { + "description": "extra items disallowed for root", + "data" : ["foo",["bar" , [] , 8], 8], + "valid": false + } + ] + } ] diff --git a/tests/draft2019-09/refRemote.json b/tests/draft2019-09/refRemote.json index 0bacbfc2e..072894cf2 100644 --- a/tests/draft2019-09/refRemote.json +++ b/tests/draft2019-09/refRemote.json @@ -22,7 +22,7 @@ "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "http://localhost:1234/draft2019-09/subSchemas-defs.json#/$defs/integer" + "$ref": "http://localhost:1234/draft2019-09/subSchemas.json#/$defs/integer" }, "tests": [ { @@ -60,7 +60,7 @@ "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2019-09/schema", - "$ref": "http://localhost:1234/draft2019-09/subSchemas-defs.json#/$defs/refToInteger" + "$ref": "http://localhost:1234/draft2019-09/subSchemas.json#/$defs/refToInteger" }, "tests": [ { @@ -265,7 +265,10 @@ }, { "description": "remote HTTP ref with different $id", - "schema": {"$ref": "http://localhost:1234/different-id-ref-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "http://localhost:1234/different-id-ref-string.json" + }, "tests": [ { "description": "number is invalid", @@ -281,7 +284,10 @@ }, { "description": "remote HTTP ref with different URN $id", - "schema": {"$ref": "http://localhost:1234/urn-ref-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "http://localhost:1234/urn-ref-string.json" + }, "tests": [ { "description": "number is invalid", @@ -297,7 +303,10 @@ }, { "description": "remote HTTP ref with nested absolute ref", - "schema": {"$ref": "http://localhost:1234/nested-absolute-ref-to-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" + }, "tests": [ { "description": "number is invalid", @@ -314,6 +323,7 @@ { "description": "$ref to $ref finds detached $anchor", "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", "$ref": "http://localhost:1234/draft2019-09/detached-ref.json#/$defs/foo" }, "tests": [ diff --git a/tests/draft2019-09/unevaluatedItems.json b/tests/draft2019-09/unevaluatedItems.json index 53565a0b9..8e2ee4b11 100644 --- a/tests/draft2019-09/unevaluatedItems.json +++ b/tests/draft2019-09/unevaluatedItems.json @@ -480,6 +480,82 @@ } ] }, + { + "description": "unevaluatedItems before $ref", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "unevaluatedItems": false, + "items": [ + { "type": "string" } + ], + "$ref": "#/$defs/bar", + "$defs": { + "bar": { + "items": [ + true, + { "type": "string" } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with $recursiveRef", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://example.com/unevaluated-items-with-recursive-ref/extended-tree", + + "$recursiveAnchor": true, + + "$ref": "./tree", + "items": [ + true, + true, + { "type": "string" } + ], + + "$defs": { + "tree": { + "$id": "./tree", + "$recursiveAnchor": true, + + "type": "array", + "items": [ + { "type": "number" }, + { + "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", + "unevaluatedItems": false, + "$recursiveRef": "#" + } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": [1, [2, [], "b"], "a"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": [1, [2, [], "b", "too many"], "a"], + "valid": false + } + ] + }, { "description": "unevaluatedItems can't see inside cousins", "schema": { diff --git a/tests/draft2019-09/unevaluatedProperties.json b/tests/draft2019-09/unevaluatedProperties.json index a6cce8bb6..e8765112c 100644 --- a/tests/draft2019-09/unevaluatedProperties.json +++ b/tests/draft2019-09/unevaluatedProperties.json @@ -715,6 +715,102 @@ } ] }, + { + "description": "unevaluatedProperties before $ref", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "type": "object", + "unevaluatedProperties": false, + "properties": { + "foo": { "type": "string" } + }, + "$ref": "#/$defs/bar", + "$defs": { + "bar": { + "properties": { + "bar": { "type": "string" } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with $recursiveRef", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://example.com/unevaluated-properties-with-recursive-ref/extended-tree", + + "$recursiveAnchor": true, + + "$ref": "./tree", + "properties": { + "name": { "type": "string" } + }, + + "$defs": { + "tree": { + "$id": "./tree", + "$recursiveAnchor": true, + + "type": "object", + "properties": { + "node": true, + "branches": { + "$comment": "unevaluatedProperties comes first so it's more likely to bugs errors with implementations that are sensitive to keyword ordering", + "unevaluatedProperties": false, + "$recursiveRef": "#" + } + }, + "required": ["node"] + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "name": "a", + "node": 1, + "branches": { + "name": "b", + "node": 2 + } + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "name": "a", + "node": 1, + "branches": { + "foo": "b", + "node": 2 + } + }, + "valid": false + } + ] + }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { @@ -1471,5 +1567,38 @@ "valid": false } ] + }, + { + "description": "dependentSchemas with unevaluatedProperties", + "schema": { + "$schema": "https://json-schema.org/draft/2019-09/schema", + "properties": {"foo2": {}}, + "dependentSchemas": { + "foo" : {}, + "foo2": { + "properties": { + "bar":{} + } + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "unevaluatedProperties doesn't consider dependentSchemas", + "data": {"foo": ""}, + "valid": false + }, + { + "description": "unevaluatedProperties doesn't see bar when foo2 is absent", + "data": {"bar": ""}, + "valid": false + }, + { + "description": "unevaluatedProperties sees bar when foo2 is present", + "data": { "foo2": "", "bar": ""}, + "valid": true + } + ] } ] diff --git a/tests/draft2020-12/additionalProperties.json b/tests/draft2020-12/additionalProperties.json index 29e69c135..9618575e2 100644 --- a/tests/draft2020-12/additionalProperties.json +++ b/tests/draft2020-12/additionalProperties.json @@ -2,6 +2,7 @@ { "description": "additionalProperties being false does not allow other properties", + "specification": [ { "core":"10.3.2.3", "quote": "The value of \"additionalProperties\" MUST be a valid JSON Schema. Boolean \"false\" forbids everything." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}}, @@ -43,6 +44,7 @@ }, { "description": "non-ASCII pattern with additionalProperties", + "specification": [ { "core":"10.3.2.3"} ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "patternProperties": {"^á": {}}, @@ -63,6 +65,7 @@ }, { "description": "additionalProperties with schema", + "specification": [ { "core":"10.3.2.3", "quote": "The value of \"additionalProperties\" MUST be a valid JSON Schema." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}}, @@ -87,8 +90,8 @@ ] }, { - "description": - "additionalProperties can exist by itself", + "description": "additionalProperties can exist by itself", + "specification": [ { "core":"10.3.2.3", "quote": "With no other applicator applying to object instances. This validates all the instance values irrespective of their property names" } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": {"type": "boolean"} @@ -108,6 +111,7 @@ }, { "description": "additionalProperties are allowed by default", + "specification": [ { "core":"10.3.2.3", "quote": "Omitting this keyword has the same assertion behavior as an empty schema." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": {"foo": {}, "bar": {}} @@ -122,6 +126,7 @@ }, { "description": "additionalProperties does not look in applicators", + "specification":[ { "core": "10.2", "quote": "Subschemas of applicator keywords evaluate the instance completely independently such that the results of one such subschema MUST NOT impact the results of sibling subschemas." } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "allOf": [ @@ -139,6 +144,7 @@ }, { "description": "additionalProperties with null valued instance properties", + "specification": [ { "core":"10.3.2.3" } ], "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": { @@ -152,5 +158,62 @@ "valid": true } ] + }, + { + "description": "additionalProperties with propertyNames", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "propertyNames": { + "maxLength": 5 + }, + "additionalProperties": { + "type": "number" + } + }, + "tests": [ + { + "description": "Valid against both keywords", + "data": { "apple": 4 }, + "valid": true + }, + { + "description": "Valid against propertyNames, but not additionalProperties", + "data": { "fig": 2, "pear": "available" }, + "valid": false + } + ] + }, + { + "description": "dependentSchemas with additionalProperties", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": {"foo2": {}}, + "dependentSchemas": { + "foo" : {}, + "foo2": { + "properties": { + "bar": {} + } + } + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "additionalProperties doesn't consider dependentSchemas", + "data": {"foo": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see bar", + "data": {"bar": ""}, + "valid": false + }, + { + "description": "additionalProperties can't see bar even when foo2 is present", + "data": {"foo2": "", "bar": ""}, + "valid": false + } + ] } ] diff --git a/tests/draft2020-12/anchor.json b/tests/draft2020-12/anchor.json index 423835dac..99143fa11 100644 --- a/tests/draft2020-12/anchor.json +++ b/tests/draft2020-12/anchor.json @@ -81,64 +81,6 @@ } ] }, - { - "description": "$anchor inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $anchor buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "anchor_in_enum": { - "enum": [ - { - "$anchor": "my_anchor", - "type": "null" - } - ] - }, - "real_identifier_in_schema": { - "$anchor": "my_anchor", - "type": "string" - }, - "zzz_anchor_in_const": { - "const": { - "$anchor": "my_anchor", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/anchor_in_enum" }, - { "$ref": "#my_anchor" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$anchor": "my_anchor", - "type": "null" - }, - "valid": true - }, - { - "description": "in implementations that strip $anchor, this may match either $def", - "data": { - "type": "null" - }, - "valid": false - }, - { - "description": "match $ref to $anchor", - "data": "a string to match #/$defs/anchor_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $anchor", - "data": 1, - "valid": false - } - ] - }, { "description": "same $anchor with different base uri", "schema": { @@ -174,62 +116,5 @@ "valid": false } ] - }, - { - "description": "non-schema object containing an $anchor property", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "const_not_anchor": { - "const": { - "$anchor": "not_a_real_anchor" - } - } - }, - "if": { - "const": "skip not_a_real_anchor" - }, - "then": true, - "else" : { - "$ref": "#/$defs/const_not_anchor" - } - }, - "tests": [ - { - "description": "skip traversing definition for a valid result", - "data": "skip not_a_real_anchor", - "valid": true - }, - { - "description": "const at const_not_anchor does not match", - "data": 1, - "valid": false - } - ] - }, - { - "description": "invalid anchors", - "comment": "Section 8.2.2", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, - "tests": [ - { - "description": "MUST start with a letter (and not #)", - "data": { "$anchor" : "#foo" }, - "valid": false - }, - { - "description": "JSON pointers are not valid", - "data": { "$anchor" : "/a/b" }, - "valid": false - }, - { - "description": "invalid with valid beginning", - "data": { "$anchor" : "foo#something" }, - "valid": false - } - ] } ] diff --git a/tests/draft2020-12/dependentSchemas.json b/tests/draft2020-12/dependentSchemas.json index 66ac0eb43..1c5f0574a 100644 --- a/tests/draft2020-12/dependentSchemas.json +++ b/tests/draft2020-12/dependentSchemas.json @@ -132,6 +132,7 @@ { "description": "dependent subschema incompatible with root", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "foo": {} }, diff --git a/tests/draft2020-12/dynamicRef.json b/tests/draft2020-12/dynamicRef.json index c1c56cb8a..ffa211ba2 100644 --- a/tests/draft2020-12/dynamicRef.json +++ b/tests/draft2020-12/dynamicRef.json @@ -726,5 +726,90 @@ "valid": false } ] + }, + { + "description": "$dynamicRef points to a boolean schema", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "true": true, + "false": false + }, + "properties": { + "true": { + "$dynamicRef": "#/$defs/true" + }, + "false": { + "$dynamicRef": "#/$defs/false" + } + } + }, + "tests": [ + { + "description": "follow $dynamicRef to a true schema", + "data": { "true": 1 }, + "valid": true + }, + { + "description": "follow $dynamicRef to a false schema", + "data": { "false": 1 }, + "valid": false + } + ] + }, + { + "description": "$dynamicRef skips over intermediate resources - direct reference", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/main", + "type": "object", + "properties": { + "bar-item": { + "$ref": "item" + } + }, + "$defs": { + "bar": { + "$id": "bar", + "type": "array", + "items": { + "$ref": "item" + }, + "$defs": { + "item": { + "$id": "item", + "type": "object", + "properties": { + "content": { + "$dynamicRef": "#content" + } + }, + "$defs": { + "defaultContent": { + "$dynamicAnchor": "content", + "type": "integer" + } + } + }, + "content": { + "$dynamicAnchor": "content", + "type": "string" + } + } + } + } + }, + "tests": [ + { + "description": "integer property passes", + "data": { "bar-item": { "content": 42 } }, + "valid": true + }, + { + "description": "string property fails", + "data": { "bar-item": { "content": "value" } }, + "valid": false + } + ] } ] diff --git a/tests/draft2020-12/enum.json b/tests/draft2020-12/enum.json index 0d780b2ac..c8f35eacf 100644 --- a/tests/draft2020-12/enum.json +++ b/tests/draft2020-12/enum.json @@ -168,6 +168,30 @@ } ] }, + { + "description": "enum with [false] does not match [0]", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "enum": [[false]] + }, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, { "description": "enum with true does not match 1", "schema": { @@ -192,6 +216,30 @@ } ] }, + { + "description": "enum with [true] does not match [1]", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "enum": [[true]] + }, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, { "description": "enum with 0 does not match false", "schema": { @@ -216,6 +264,30 @@ } ] }, + { + "description": "enum with [0] does not match [false]", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "enum": [[0]] + }, + "tests": [ + { + "description": "[false] is invalid", + "data": [false], + "valid": false + }, + { + "description": "[0] is valid", + "data": [0], + "valid": true + }, + { + "description": "[0.0] is valid", + "data": [0.0], + "valid": true + } + ] + }, { "description": "enum with 1 does not match true", "schema": { @@ -240,6 +312,30 @@ } ] }, + { + "description": "enum with [1] does not match [true]", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "enum": [[1]] + }, + "tests": [ + { + "description": "[true] is invalid", + "data": [true], + "valid": false + }, + { + "description": "[1] is valid", + "data": [1], + "valid": true + }, + { + "description": "[1.0] is valid", + "data": [1.0], + "valid": true + } + ] + }, { "description": "nul characters in strings", "schema": { diff --git a/tests/draft2020-12/id.json b/tests/draft2020-12/id.json deleted file mode 100644 index 0ae5fe68a..000000000 --- a/tests/draft2020-12/id.json +++ /dev/null @@ -1,294 +0,0 @@ -[ - { - "description": "Invalid use of fragments in location-independent $id", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, - "tests": [ - { - "description": "Identifier name", - "data": { - "$ref": "#foo", - "$defs": { - "A": { - "$id": "#foo", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name and no ref", - "data": { - "$defs": { - "A": { "$id": "#foo" } - } - }, - "valid": false - }, - { - "description": "Identifier path", - "data": { - "$ref": "#/a/b", - "$defs": { - "A": { - "$id": "#/a/b", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft2020-12/bar#foo", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2020-12/bar#foo", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier path with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft2020-12/bar#/a/b", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2020-12/bar#/a/b", - "type": "integer" - } - } - }, - "valid": false - }, - { - "description": "Identifier name with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft2020-12/root", - "$ref": "http://localhost:1234/draft2020-12/nested.json#foo", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#foo", - "type": "integer" - } - } - } - } - }, - "valid": false - }, - { - "description": "Identifier path with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft2020-12/root", - "$ref": "http://localhost:1234/draft2020-12/nested.json#/a/b", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#/a/b", - "type": "integer" - } - } - } - } - }, - "valid": false - } - ] - }, - { - "description": "Valid use of empty fragments in location-independent $id", - "comment": "These are allowed but discouraged", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, - "tests": [ - { - "description": "Identifier name with absolute URI", - "data": { - "$ref": "http://localhost:1234/draft2020-12/bar", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2020-12/bar#", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Identifier name with base URI change in subschema", - "data": { - "$id": "http://localhost:1234/draft2020-12/root", - "$ref": "http://localhost:1234/draft2020-12/nested.json#/$defs/B", - "$defs": { - "A": { - "$id": "nested.json", - "$defs": { - "B": { - "$id": "#", - "type": "integer" - } - } - } - } - }, - "valid": true - } - ] - }, - { - "description": "Unnormalized $ids are allowed but discouraged", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, - "tests": [ - { - "description": "Unnormalized identifier", - "data": { - "$ref": "http://localhost:1234/draft2020-12/foo/baz", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier and no ref", - "data": { - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier with empty fragment", - "data": { - "$ref": "http://localhost:1234/draft2020-12/foo/baz", - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz#", - "type": "integer" - } - } - }, - "valid": true - }, - { - "description": "Unnormalized identifier with empty fragment and no ref", - "data": { - "$defs": { - "A": { - "$id": "http://localhost:1234/draft2020-12/foo/bar/../baz#", - "type": "integer" - } - } - }, - "valid": true - } - ] - }, - { - "description": "$id inside an enum is not a real identifier", - "comment": "the implementation must not be confused by an $id buried in the enum", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "id_in_enum": { - "enum": [ - { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "null" - } - ] - }, - "real_id_in_schema": { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "string" - }, - "zzz_id_in_const": { - "const": { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "null" - } - } - }, - "anyOf": [ - { "$ref": "#/$defs/id_in_enum" }, - { "$ref": "https://localhost:1234/draft2020-12/id/my_identifier.json" } - ] - }, - "tests": [ - { - "description": "exact match to enum, and type matches", - "data": { - "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", - "type": "null" - }, - "valid": true - }, - { - "description": "match $ref to $id", - "data": "a string to match #/$defs/id_in_enum", - "valid": true - }, - { - "description": "no match on enum or $ref to $id", - "data": 1, - "valid": false - } - ] - }, - { - "description": "non-schema object containing an $id property", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$defs": { - "const_not_id": { - "const": { - "$id": "not_a_real_id" - } - } - }, - "if": { - "const": "skip not_a_real_id" - }, - "then": true, - "else" : { - "$ref": "#/$defs/const_not_id" - } - }, - "tests": [ - { - "description": "skip traversing definition for a valid result", - "data": "skip not_a_real_id", - "valid": true - }, - { - "description": "const at const_not_id does not match", - "data": 1, - "valid": false - } - ] - } -] diff --git a/tests/draft2020-12/items.json b/tests/draft2020-12/items.json index 1ef18bdd0..6a3e1cf26 100644 --- a/tests/draft2020-12/items.json +++ b/tests/draft2020-12/items.json @@ -265,6 +265,26 @@ } ] }, + { + "description": "items with heterogeneous array", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "prefixItems": [{}], + "items": false + }, + "tests": [ + { + "description": "heterogeneous invalid instance", + "data": [ "foo", "bar", 37 ], + "valid": false + }, + { + "description": "valid instance", + "data": [ null ], + "valid": true + } + ] + }, { "description": "items with null instance elements", "schema": { diff --git a/tests/draft2020-12/maxLength.json b/tests/draft2020-12/maxLength.json index b6eb03401..7462726d7 100644 --- a/tests/draft2020-12/maxLength.json +++ b/tests/draft2020-12/maxLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "two supplementary Unicode code points is long enough", + "description": "two graphemes is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft2020-12/minLength.json b/tests/draft2020-12/minLength.json index e0930b6fb..5076c5a92 100644 --- a/tests/draft2020-12/minLength.json +++ b/tests/draft2020-12/minLength.json @@ -27,7 +27,7 @@ "valid": true }, { - "description": "one supplementary Unicode code point is not long enough", + "description": "one grapheme is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft2020-12/not.json b/tests/draft2020-12/not.json index 57e45ba39..d0f2b6e84 100644 --- a/tests/draft2020-12/not.json +++ b/tests/draft2020-12/not.json @@ -97,25 +97,173 @@ ] }, { - "description": "not with boolean schema true", + "description": "forbid everything with empty schema", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "not": {} + }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": true }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false } ] }, { - "description": "not with boolean schema false", + "description": "allow everything with boolean schema false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true + } + ] + }, + { + "description": "double negation", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "not": { "not": {} } + }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft2020-12/oneOf.json b/tests/draft2020-12/oneOf.json index 416c8e570..7a7c7ffe3 100644 --- a/tests/draft2020-12/oneOf.json +++ b/tests/draft2020-12/oneOf.json @@ -220,7 +220,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", diff --git a/tests/draft2020-12/optional/anchor.json b/tests/draft2020-12/optional/anchor.json new file mode 100644 index 000000000..6d6713be5 --- /dev/null +++ b/tests/draft2020-12/optional/anchor.json @@ -0,0 +1,60 @@ +[ + { + "description": "$anchor inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $anchor buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "anchor_in_enum": { + "enum": [ + { + "$anchor": "my_anchor", + "type": "null" + } + ] + }, + "real_identifier_in_schema": { + "$anchor": "my_anchor", + "type": "string" + }, + "zzz_anchor_in_const": { + "const": { + "$anchor": "my_anchor", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/anchor_in_enum" }, + { "$ref": "#my_anchor" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$anchor": "my_anchor", + "type": "null" + }, + "valid": true + }, + { + "description": "in implementations that strip $anchor, this may match either $def", + "data": { + "type": "null" + }, + "valid": false + }, + { + "description": "match $ref to $anchor", + "data": "a string to match #/$defs/anchor_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $anchor", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft2020-12/optional/dynamicRef.json b/tests/draft2020-12/optional/dynamicRef.json new file mode 100644 index 000000000..7e63f209a --- /dev/null +++ b/tests/draft2020-12/optional/dynamicRef.json @@ -0,0 +1,56 @@ +[ + { + "description": "$dynamicRef skips over intermediate resources - pointer reference across resource boundary", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://test.json-schema.org/dynamic-ref-skips-intermediate-resource/optional/main", + "type": "object", + "properties": { + "bar-item": { + "$ref": "bar#/$defs/item" + } + }, + "$defs": { + "bar": { + "$id": "bar", + "type": "array", + "items": { + "$ref": "item" + }, + "$defs": { + "item": { + "$id": "item", + "type": "object", + "properties": { + "content": { + "$dynamicRef": "#content" + } + }, + "$defs": { + "defaultContent": { + "$dynamicAnchor": "content", + "type": "integer" + } + } + }, + "content": { + "$dynamicAnchor": "content", + "type": "string" + } + } + } + } + }, + "tests": [ + { + "description": "integer property passes", + "data": { "bar-item": { "content": 42 } }, + "valid": true + }, + { + "description": "string property fails", + "data": { "bar-item": { "content": "value" } }, + "valid": false + } + ] + }] \ No newline at end of file diff --git a/tests/draft2020-12/optional/ecmascript-regex.json b/tests/draft2020-12/optional/ecmascript-regex.json index 23b962e4b..a4d62e0cf 100644 --- a/tests/draft2020-12/optional/ecmascript-regex.json +++ b/tests/draft2020-12/optional/ecmascript-regex.json @@ -405,20 +405,6 @@ } ] }, - { - "description": "\\a is not an ECMA 262 control escape", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, - "tests": [ - { - "description": "when used as a pattern", - "data": { "pattern": "\\a" }, - "valid": false - } - ] - }, { "description": "pattern with non-ASCII digits", "schema": { diff --git a/tests/draft2020-12/optional/format/duration.json b/tests/draft2020-12/optional/format/duration.json index a3af56ef0..a09fec5ef 100644 --- a/tests/draft2020-12/optional/format/duration.json +++ b/tests/draft2020-12/optional/format/duration.json @@ -46,6 +46,11 @@ "data": "PT1D", "valid": false }, + { + "description": "must start with P", + "data": "4DT12H30M5S", + "valid": false + }, { "description": "no elements present", "data": "P", diff --git a/tests/draft2020-12/optional/format/ecmascript-regex.json b/tests/draft2020-12/optional/format/ecmascript-regex.json new file mode 100644 index 000000000..b0648084a --- /dev/null +++ b/tests/draft2020-12/optional/format/ecmascript-regex.json @@ -0,0 +1,16 @@ +[ + { + "description": "\\a is not an ECMA 262 control escape", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "format": "regex" + }, + "tests": [ + { + "description": "when used as a pattern", + "data": "\\a", + "valid": false + } + ] + } +] \ No newline at end of file diff --git a/tests/draft2020-12/optional/format/hostname.json b/tests/draft2020-12/optional/format/hostname.json index 41418dd4a..57827c4d4 100644 --- a/tests/draft2020-12/optional/format/hostname.json +++ b/tests/draft2020-12/optional/format/hostname.json @@ -120,6 +120,16 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft2020-12/optional/format/idn-hostname.json b/tests/draft2020-12/optional/format/idn-hostname.json index 5549c0550..f42ae969b 100644 --- a/tests/draft2020-12/optional/format/idn-hostname.json +++ b/tests/draft2020-12/optional/format/idn-hostname.json @@ -257,7 +257,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -301,6 +301,88 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true + }, + { + "description": "single label", + "data": "hostname", + "valid": true + }, + { + "description": "single label with hyphen", + "data": "host-name", + "valid": true + }, + { + "description": "single label with digits", + "data": "h0stn4me", + "valid": true + }, + { + "description": "single label starting with digit", + "data": "1host", + "valid": true + }, + { + "description": "single label ending with digit", + "data": "hostnam3", + "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "format": "idn-hostname" + }, + "tests": [ + { + "description": "single dot", + "data": ".", + "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft2020-12/optional/format/ipv4.json b/tests/draft2020-12/optional/format/ipv4.json index c72b6fc22..86d27bdb7 100644 --- a/tests/draft2020-12/optional/format/ipv4.json +++ b/tests/draft2020-12/optional/format/ipv4.json @@ -81,6 +81,11 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false + }, + { + "description": "netmask is not a part of ipv4 address", + "data": "192.168.1.0/24", + "valid": false } ] } diff --git a/tests/draft2020-12/optional/id.json b/tests/draft2020-12/optional/id.json new file mode 100644 index 000000000..0b7df4e80 --- /dev/null +++ b/tests/draft2020-12/optional/id.json @@ -0,0 +1,53 @@ +[ + { + "description": "$id inside an enum is not a real identifier", + "comment": "the implementation must not be confused by an $id buried in the enum", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "id_in_enum": { + "enum": [ + { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "null" + } + ] + }, + "real_id_in_schema": { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "string" + }, + "zzz_id_in_const": { + "const": { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "null" + } + } + }, + "anyOf": [ + { "$ref": "#/$defs/id_in_enum" }, + { "$ref": "https://localhost:1234/draft2020-12/id/my_identifier.json" } + ] + }, + "tests": [ + { + "description": "exact match to enum, and type matches", + "data": { + "$id": "https://localhost:1234/draft2020-12/id/my_identifier.json", + "type": "null" + }, + "valid": true + }, + { + "description": "match $ref to $id", + "data": "a string to match #/$defs/id_in_enum", + "valid": true + }, + { + "description": "no match on enum or $ref to $id", + "data": 1, + "valid": false + } + ] + } +] diff --git a/tests/draft2020-12/optional/refOfUnknownKeyword.json b/tests/draft2020-12/optional/refOfUnknownKeyword.json index f91c18884..c2b080a1e 100644 --- a/tests/draft2020-12/optional/refOfUnknownKeyword.json +++ b/tests/draft2020-12/optional/refOfUnknownKeyword.json @@ -42,5 +42,28 @@ "valid": false } ] + }, + { + "description": "reference internals of known non-applicator", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "/base", + "examples": [ + { "type": "string" } + ], + "$ref": "#/examples/0" + }, + "tests": [ + { + "description": "match", + "data": "a string", + "valid": true + }, + { + "description": "mismatch", + "data": 42, + "valid": false + } + ] } ] diff --git a/tests/draft2020-12/unknownKeyword.json b/tests/draft2020-12/optional/unknownKeyword.json similarity index 100% rename from tests/draft2020-12/unknownKeyword.json rename to tests/draft2020-12/optional/unknownKeyword.json diff --git a/tests/draft2020-12/propertyNames.json b/tests/draft2020-12/propertyNames.json index 7ecfb7ec3..b4780088a 100644 --- a/tests/draft2020-12/propertyNames.json +++ b/tests/draft2020-12/propertyNames.json @@ -44,6 +44,36 @@ } ] }, + { + "description": "propertyNames validation with pattern", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "propertyNames": { "pattern": "^a+$" } + }, + "tests": [ + { + "description": "matching property names valid", + "data": { + "a": {}, + "aa": {}, + "aaa": {} + }, + "valid": true + }, + { + "description": "non-matching property name is invalid", + "data": { + "aaA": {} + }, + "valid": false + }, + { + "description": "object without properties is valid", + "data": {}, + "valid": true + } + ] + }, { "description": "propertyNames with boolean schema true", "schema": { @@ -81,5 +111,58 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "propertyNames": {"const": "foo"} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "propertyNames": {"enum": ["foo", "bar"]} + }, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] diff --git a/tests/draft2020-12/ref.json b/tests/draft2020-12/ref.json index 5f6be8c20..a1d3efaf7 100644 --- a/tests/draft2020-12/ref.json +++ b/tests/draft2020-12/ref.json @@ -791,21 +791,6 @@ } ] }, - { - "description": "URN base URI with f-component", - "schema": { - "$comment": "RFC 8141 §2.3.3, but we don't allow fragments", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "https://json-schema.org/draft/2020-12/schema" - }, - "tests": [ - { - "description": "is invalid", - "data": {"$id": "urn:example:foo-bar-baz-qux#somepart"}, - "valid": false - } - ] - }, { "description": "URN base URI with URN and JSON pointer ref", "schema": { @@ -862,6 +847,7 @@ { "description": "URN ref with nested pointer ref", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "urn:uuid:deadbeef-4321-ffff-ffff-1234feebdaed", "$defs": { "foo": { @@ -887,6 +873,7 @@ { "description": "ref to if", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/if", "if": { "$id": "http://example.com/ref/if", @@ -909,6 +896,7 @@ { "description": "ref to then", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/then", "then": { "$id": "http://example.com/ref/then", @@ -931,6 +919,7 @@ { "description": "ref to else", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://example.com/ref/else", "else": { "$id": "http://example.com/ref/else", @@ -953,6 +942,7 @@ { "description": "ref with absolute-path-reference", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://example.com/ref/absref.json", "$defs": { "a": { @@ -982,6 +972,7 @@ { "description": "$id with file URI still resolves pointers - *nix", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "file:///folder/file.json", "$defs": { "foo": { @@ -1006,6 +997,7 @@ { "description": "$id with file URI still resolves pointers - windows", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "file:///c:/folder/file.json", "$defs": { "foo": { @@ -1030,6 +1022,7 @@ { "description": "empty tokens in $ref json-pointer", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "": { "$defs": { diff --git a/tests/draft2020-12/refRemote.json b/tests/draft2020-12/refRemote.json index ea4177f0a..047ac74ca 100644 --- a/tests/draft2020-12/refRemote.json +++ b/tests/draft2020-12/refRemote.json @@ -22,7 +22,7 @@ "description": "fragment within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "http://localhost:1234/draft2020-12/subSchemas-defs.json#/$defs/integer" + "$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/integer" }, "tests": [ { @@ -60,7 +60,7 @@ "description": "ref within remote ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$ref": "http://localhost:1234/draft2020-12/subSchemas-defs.json#/$defs/refToInteger" + "$ref": "http://localhost:1234/draft2020-12/subSchemas.json#/$defs/refToInteger" }, "tests": [ { @@ -265,7 +265,10 @@ }, { "description": "remote HTTP ref with different $id", - "schema": {"$ref": "http://localhost:1234/different-id-ref-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "http://localhost:1234/different-id-ref-string.json" + }, "tests": [ { "description": "number is invalid", @@ -281,7 +284,10 @@ }, { "description": "remote HTTP ref with different URN $id", - "schema": {"$ref": "http://localhost:1234/urn-ref-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "http://localhost:1234/urn-ref-string.json" + }, "tests": [ { "description": "number is invalid", @@ -297,7 +303,10 @@ }, { "description": "remote HTTP ref with nested absolute ref", - "schema": {"$ref": "http://localhost:1234/nested-absolute-ref-to-string.json"}, + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$ref": "http://localhost:1234/nested-absolute-ref-to-string.json" + }, "tests": [ { "description": "number is invalid", @@ -314,6 +323,7 @@ { "description": "$ref to $ref finds detached $anchor", "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": "http://localhost:1234/draft2020-12/detached-ref.json#/$defs/foo" }, "tests": [ diff --git a/tests/draft2020-12/unevaluatedItems.json b/tests/draft2020-12/unevaluatedItems.json index 2615c4c41..f861cefad 100644 --- a/tests/draft2020-12/unevaluatedItems.json +++ b/tests/draft2020-12/unevaluatedItems.json @@ -461,6 +461,86 @@ } ] }, + { + "description": "unevaluatedItems before $ref", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "unevaluatedItems": false, + "prefixItems": [ + { "type": "string" } + ], + "$ref": "#/$defs/bar", + "$defs": { + "bar": { + "prefixItems": [ + true, + { "type": "string" } + ] + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, + { + "description": "unevaluatedItems with $dynamicRef", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://example.com/unevaluated-items-with-dynamic-ref/derived", + + "$ref": "./baseSchema", + + "$defs": { + "derived": { + "$dynamicAnchor": "addons", + "prefixItems": [ + true, + { "type": "string" } + ] + }, + "baseSchema": { + "$id": "./baseSchema", + + "$comment": "unevaluatedItems comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", + "unevaluatedItems": false, + "type": "array", + "prefixItems": [ + { "type": "string" } + ], + "$dynamicRef": "#addons", + + "$defs": { + "defaultAddons": { + "$comment": "Needed to satisfy the bookending requirement", + "$dynamicAnchor": "addons" + } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", "bar"], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", "bar", "baz"], + "valid": false + } + ] + }, { "description": "unevaluatedItems can't see inside cousins", "schema": { @@ -713,7 +793,6 @@ "data": [ "b" ], "valid": false } - ] } ] diff --git a/tests/draft2020-12/unevaluatedProperties.json b/tests/draft2020-12/unevaluatedProperties.json index f7fb420ff..0da38f679 100644 --- a/tests/draft2020-12/unevaluatedProperties.json +++ b/tests/draft2020-12/unevaluatedProperties.json @@ -3,7 +3,6 @@ "description": "unevaluatedProperties true", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "unevaluatedProperties": true }, "tests": [ @@ -25,7 +24,6 @@ "description": "unevaluatedProperties schema", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "unevaluatedProperties": { "type": "string", "minLength": 3 @@ -57,7 +55,6 @@ "description": "unevaluatedProperties false", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "unevaluatedProperties": false }, "tests": [ @@ -79,7 +76,6 @@ "description": "unevaluatedProperties with adjacent properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -107,7 +103,6 @@ "description": "unevaluatedProperties with adjacent patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "patternProperties": { "^foo": { "type": "string" } }, @@ -132,13 +127,9 @@ ] }, { - "description": "unevaluatedProperties with adjacent additionalProperties", + "description": "unevaluatedProperties with adjacent bool additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "foo": { "type": "string" } - }, "additionalProperties": true, "unevaluatedProperties": false }, @@ -160,11 +151,35 @@ } ] }, + { + "description": "unevaluatedProperties with adjacent non-bool additionalProperties", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": { "type": "string" }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "with only valid additional properties", + "data": { + "foo": "foo" + }, + "valid": true + }, + { + "description": "with invalid additional properties", + "data": { + "foo": "foo", + "bar": 1 + }, + "valid": false + } + ] + }, { "description": "unevaluatedProperties with nested properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -201,7 +216,6 @@ "description": "unevaluatedProperties with nested patternProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -238,7 +252,6 @@ "description": "unevaluatedProperties with nested additionalProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -271,7 +284,6 @@ "description": "unevaluatedProperties with nested unevaluatedProperties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -307,7 +319,6 @@ "description": "unevaluatedProperties with anyOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -376,7 +387,6 @@ "description": "unevaluatedProperties with oneOf", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -420,7 +430,6 @@ "description": "unevaluatedProperties with not", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -449,7 +458,6 @@ "description": "unevaluatedProperties with if/then/else", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "if": { "properties": { "foo": { "const": "then" } @@ -509,7 +517,6 @@ "description": "unevaluatedProperties with if/then/else, then not defined", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "if": { "properties": { "foo": { "const": "then" } @@ -563,7 +570,6 @@ "description": "unevaluatedProperties with if/then/else, else not defined", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "if": { "properties": { "foo": { "const": "then" } @@ -617,7 +623,6 @@ "description": "unevaluatedProperties with dependentSchemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -653,7 +658,6 @@ "description": "unevaluatedProperties with boolean schemas", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -681,7 +685,6 @@ "description": "unevaluatedProperties with $ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "$ref": "#/$defs/bar", "properties": { "foo": { "type": "string" } @@ -715,6 +718,97 @@ } ] }, + { + "description": "unevaluatedProperties before $ref", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "unevaluatedProperties": false, + "properties": { + "foo": { "type": "string" } + }, + "$ref": "#/$defs/bar", + "$defs": { + "bar": { + "properties": { + "bar": { "type": "string" } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, + { + "description": "unevaluatedProperties with $dynamicRef", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://example.com/unevaluated-properties-with-dynamic-ref/derived", + + "$ref": "./baseSchema", + + "$defs": { + "derived": { + "$dynamicAnchor": "addons", + "properties": { + "bar": { "type": "string" } + } + }, + "baseSchema": { + "$id": "./baseSchema", + + "$comment": "unevaluatedProperties comes first so it's more likely to catch bugs with implementations that are sensitive to keyword ordering", + "unevaluatedProperties": false, + "properties": { + "foo": { "type": "string" } + }, + "$dynamicRef": "#addons", + + "$defs": { + "defaultAddons": { + "$comment": "Needed to satisfy the bookending requirement", + "$dynamicAnchor": "addons" + } + } + } + } + }, + "tests": [ + { + "description": "with no unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar" + }, + "valid": true + }, + { + "description": "with unevaluated properties", + "data": { + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "valid": false + } + ] + }, { "description": "unevaluatedProperties can't see inside cousins", "schema": { @@ -769,7 +863,6 @@ "description": "nested unevaluatedProperties, outer false, inner true, properties outside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -802,7 +895,6 @@ "description": "nested unevaluatedProperties, outer false, inner true, properties inside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "allOf": [ { "properties": { @@ -835,7 +927,6 @@ "description": "nested unevaluatedProperties, outer true, inner false, properties outside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { "type": "string" } }, @@ -868,7 +959,6 @@ "description": "nested unevaluatedProperties, outer true, inner false, properties inside", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "allOf": [ { "properties": { @@ -901,7 +991,6 @@ "description": "cousin unevaluatedProperties, true and false, true with properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "allOf": [ { "properties": { @@ -936,7 +1025,6 @@ "description": "cousin unevaluatedProperties, true and false, false with properties", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "allOf": [ { "unevaluatedProperties": true @@ -972,10 +1060,8 @@ "comment": "see https://stackoverflow.com/questions/66936884/deeply-nested-unevaluatedproperties-and-their-expectations", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "foo": { - "type": "object", "properties": { "bar": { "type": "string" @@ -1024,7 +1110,6 @@ "description": "in-place applicator siblings, allOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "allOf": [ { "properties": { @@ -1070,7 +1155,6 @@ "description": "in-place applicator siblings, anyOf has unevaluated", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "allOf": [ { "properties": { @@ -1116,7 +1200,6 @@ "description": "unevaluatedProperties + single cyclic ref", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", "properties": { "x": { "$ref": "#" } }, @@ -1471,5 +1554,38 @@ "valid": false } ] + }, + { + "description": "dependentSchemas with unevaluatedProperties", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "properties": {"foo2": {}}, + "dependentSchemas": { + "foo" : {}, + "foo2": { + "properties": { + "bar":{} + } + } + }, + "unevaluatedProperties": false + }, + "tests": [ + { + "description": "unevaluatedProperties doesn't consider dependentSchemas", + "data": {"foo": ""}, + "valid": false + }, + { + "description": "unevaluatedProperties doesn't see bar when foo2 is absent", + "data": {"bar": ""}, + "valid": false + }, + { + "description": "unevaluatedProperties sees bar when foo2 is present", + "data": { "foo2": "", "bar": ""}, + "valid": true + } + ] } ] diff --git a/tests/draft3/additionalItems.json b/tests/draft3/additionalItems.json index 0cb668701..ab44a2eb3 100644 --- a/tests/draft3/additionalItems.json +++ b/tests/draft3/additionalItems.json @@ -110,6 +110,25 @@ } ] }, + { + "description": "additionalItems with heterogeneous array", + "schema": { + "items": [{}], + "additionalItems": false + }, + "tests": [ + { + "description": "heterogeneous invalid instance", + "data": [ "foo", "bar", 37 ], + "valid": false + }, + { + "description": "valid instance", + "data": [ null ], + "valid": true + } + ] + }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft3/maxLength.json b/tests/draft3/maxLength.json index 4de42bcab..b0a9ea5be 100644 --- a/tests/draft3/maxLength.json +++ b/tests/draft3/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two supplementary Unicode code points is long enough", + "description": "two graphemes is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft3/minLength.json b/tests/draft3/minLength.json index 3f09158de..6652c7509 100644 --- a/tests/draft3/minLength.json +++ b/tests/draft3/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one supplementary Unicode code point is not long enough", + "description": "one grapheme is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft3/optional/ecmascript-regex.json b/tests/draft3/optional/format/ecmascript-regex.json similarity index 100% rename from tests/draft3/optional/ecmascript-regex.json rename to tests/draft3/optional/format/ecmascript-regex.json diff --git a/tests/draft3/optional/format/host-name.json b/tests/draft3/optional/format/host-name.json index d418f3763..9a75c3c20 100644 --- a/tests/draft3/optional/format/host-name.json +++ b/tests/draft3/optional/format/host-name.json @@ -57,6 +57,11 @@ "description": "exceeds maximum label length", "data": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl.com", "valid": false + }, + { + "description": "empty string", + "data": "", + "valid": false } ] } diff --git a/tests/draft3/refRemote.json b/tests/draft3/refRemote.json index de0cb43a5..81a6c5116 100644 --- a/tests/draft3/refRemote.json +++ b/tests/draft3/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "schema": {"$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + "$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft4/additionalItems.json b/tests/draft4/additionalItems.json index deb44fd31..c9e681549 100644 --- a/tests/draft4/additionalItems.json +++ b/tests/draft4/additionalItems.json @@ -146,6 +146,25 @@ } ] }, + { + "description": "additionalItems with heterogeneous array", + "schema": { + "items": [{}], + "additionalItems": false + }, + "tests": [ + { + "description": "heterogeneous invalid instance", + "data": [ "foo", "bar", 37 ], + "valid": false + }, + { + "description": "valid instance", + "data": [ null ], + "valid": true + } + ] + }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft4/enum.json b/tests/draft4/enum.json index f085097be..ce43acc02 100644 --- a/tests/draft4/enum.json +++ b/tests/draft4/enum.json @@ -154,6 +154,27 @@ } ] }, + { + "description": "enum with [false] does not match [0]", + "schema": {"enum": [[false]]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, @@ -175,6 +196,27 @@ } ] }, + { + "description": "enum with [true] does not match [1]", + "schema": {"enum": [[true]]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, @@ -196,6 +238,27 @@ } ] }, + { + "description": "enum with [0] does not match [false]", + "schema": {"enum": [[0]]}, + "tests": [ + { + "description": "[false] is invalid", + "data": [false], + "valid": false + }, + { + "description": "[0] is valid", + "data": [0], + "valid": true + }, + { + "description": "[0.0] is valid", + "data": [0.0], + "valid": true + } + ] + }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, @@ -217,6 +280,27 @@ } ] }, + { + "description": "enum with [1] does not match [true]", + "schema": {"enum": [[1]]}, + "tests": [ + { + "description": "[true] is invalid", + "data": [true], + "valid": false + }, + { + "description": "[1] is valid", + "data": [1], + "valid": true + }, + { + "description": "[1.0] is valid", + "data": [1.0], + "valid": true + } + ] + }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, diff --git a/tests/draft4/maxLength.json b/tests/draft4/maxLength.json index 811d35b25..338795943 100644 --- a/tests/draft4/maxLength.json +++ b/tests/draft4/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two supplementary Unicode code points is long enough", + "description": "two graphemes is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft4/minLength.json b/tests/draft4/minLength.json index 3f09158de..6652c7509 100644 --- a/tests/draft4/minLength.json +++ b/tests/draft4/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one supplementary Unicode code point is not long enough", + "description": "one grapheme is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft4/not.json b/tests/draft4/not.json index cbb7f46bf..525219cf2 100644 --- a/tests/draft4/not.json +++ b/tests/draft4/not.json @@ -91,6 +91,67 @@ "valid": true } ] + }, + { + "description": "forbid everything with empty schema", + "schema": { "not": {} }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "double negation", + "schema": { "not": { "not": {} } }, + "tests": [ + { + "description": "any value is valid", + "data": "foo", + "valid": true + } + ] } - ] diff --git a/tests/draft4/oneOf.json b/tests/draft4/oneOf.json index fb63b0898..2487f0e38 100644 --- a/tests/draft4/oneOf.json +++ b/tests/draft4/oneOf.json @@ -159,7 +159,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "oneOf": [ diff --git a/tests/draft4/optional/format/hostname.json b/tests/draft4/optional/format/hostname.json index a8ecd194f..866a61788 100644 --- a/tests/draft4/optional/format/hostname.json +++ b/tests/draft4/optional/format/hostname.json @@ -112,6 +112,16 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft4/optional/format/ipv4.json b/tests/draft4/optional/format/ipv4.json index 4706581f2..9680fe620 100644 --- a/tests/draft4/optional/format/ipv4.json +++ b/tests/draft4/optional/format/ipv4.json @@ -78,6 +78,11 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false + }, + { + "description": "netmask is not a part of ipv4 address", + "data": "192.168.1.0/24", + "valid": false } ] } diff --git a/tests/draft4/id.json b/tests/draft4/optional/id.json similarity index 100% rename from tests/draft4/id.json rename to tests/draft4/optional/id.json diff --git a/tests/draft4/refRemote.json b/tests/draft4/refRemote.json index 412c9ff83..65e45190c 100644 --- a/tests/draft4/refRemote.json +++ b/tests/draft4/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "schema": {"$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + "$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "name.json#/definitions/orNull"} + "name": {"$ref": "draft4/name.json#/definitions/orNull"} } }, "tests": [ @@ -171,7 +171,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/locationIndependentIdentifierDraft4.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft4/locationIndependentIdentifier.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft6/additionalItems.json b/tests/draft6/additionalItems.json index cae72361c..2c7d15582 100644 --- a/tests/draft6/additionalItems.json +++ b/tests/draft6/additionalItems.json @@ -169,6 +169,25 @@ } ] }, + { + "description": "additionalItems with heterogeneous array", + "schema": { + "items": [{}], + "additionalItems": false + }, + "tests": [ + { + "description": "heterogeneous invalid instance", + "data": [ "foo", "bar", 37 ], + "valid": false + }, + { + "description": "valid instance", + "data": [ null ], + "valid": true + } + ] + }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft6/enum.json b/tests/draft6/enum.json index f085097be..ce43acc02 100644 --- a/tests/draft6/enum.json +++ b/tests/draft6/enum.json @@ -154,6 +154,27 @@ } ] }, + { + "description": "enum with [false] does not match [0]", + "schema": {"enum": [[false]]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, @@ -175,6 +196,27 @@ } ] }, + { + "description": "enum with [true] does not match [1]", + "schema": {"enum": [[true]]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, @@ -196,6 +238,27 @@ } ] }, + { + "description": "enum with [0] does not match [false]", + "schema": {"enum": [[0]]}, + "tests": [ + { + "description": "[false] is invalid", + "data": [false], + "valid": false + }, + { + "description": "[0] is valid", + "data": [0], + "valid": true + }, + { + "description": "[0.0] is valid", + "data": [0.0], + "valid": true + } + ] + }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, @@ -217,6 +280,27 @@ } ] }, + { + "description": "enum with [1] does not match [true]", + "schema": {"enum": [[1]]}, + "tests": [ + { + "description": "[true] is invalid", + "data": [true], + "valid": false + }, + { + "description": "[1] is valid", + "data": [1], + "valid": true + }, + { + "description": "[1.0] is valid", + "data": [1.0], + "valid": true + } + ] + }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, diff --git a/tests/draft6/maxLength.json b/tests/draft6/maxLength.json index 748b4daaf..be60c5407 100644 --- a/tests/draft6/maxLength.json +++ b/tests/draft6/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two supplementary Unicode code points is long enough", + "description": "two graphemes is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft6/minLength.json b/tests/draft6/minLength.json index 64db94805..23c68fe3f 100644 --- a/tests/draft6/minLength.json +++ b/tests/draft6/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one supplementary Unicode code point is not long enough", + "description": "one grapheme is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft6/not.json b/tests/draft6/not.json index 98de0eda8..b46c4ed05 100644 --- a/tests/draft6/not.json +++ b/tests/draft6/not.json @@ -93,19 +93,161 @@ ] }, { - "description": "not with boolean schema true", - "schema": {"not": true}, + "description": "forbid everything with empty schema", + "schema": { "not": {} }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", + "schema": { "not": true }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "allow everything with boolean schema false", + "schema": { "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true } ] }, { - "description": "not with boolean schema false", - "schema": {"not": false}, + "description": "double negation", + "schema": { "not": { "not": {} } }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft6/oneOf.json b/tests/draft6/oneOf.json index eeb7ae866..c30a65c0d 100644 --- a/tests/draft6/oneOf.json +++ b/tests/draft6/oneOf.json @@ -203,7 +203,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "oneOf": [ diff --git a/tests/draft6/optional/format/hostname.json b/tests/draft6/optional/format/hostname.json index a8ecd194f..866a61788 100644 --- a/tests/draft6/optional/format/hostname.json +++ b/tests/draft6/optional/format/hostname.json @@ -112,6 +112,16 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft6/optional/format/ipv4.json b/tests/draft6/optional/format/ipv4.json index 4706581f2..9680fe620 100644 --- a/tests/draft6/optional/format/ipv4.json +++ b/tests/draft6/optional/format/ipv4.json @@ -78,6 +78,11 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false + }, + { + "description": "netmask is not a part of ipv4 address", + "data": "192.168.1.0/24", + "valid": false } ] } diff --git a/tests/draft6/id.json b/tests/draft6/optional/id.json similarity index 100% rename from tests/draft6/id.json rename to tests/draft6/optional/id.json diff --git a/tests/draft6/unknownKeyword.json b/tests/draft6/optional/unknownKeyword.json similarity index 100% rename from tests/draft6/unknownKeyword.json rename to tests/draft6/optional/unknownKeyword.json diff --git a/tests/draft6/propertyNames.json b/tests/draft6/propertyNames.json index f0788e649..7c7b80006 100644 --- a/tests/draft6/propertyNames.json +++ b/tests/draft6/propertyNames.json @@ -103,5 +103,52 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": {"propertyNames": {"const": "foo"}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": {"propertyNames": {"enum": ["foo", "bar"]}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] diff --git a/tests/draft6/refRemote.json b/tests/draft6/refRemote.json index 5d60fae11..49ead6d1f 100644 --- a/tests/draft6/refRemote.json +++ b/tests/draft6/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "schema": {"$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + "$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "$id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "name.json#/definitions/orNull"} + "name": {"$ref": "draft6/name.json#/definitions/orNull"} } }, "tests": [ @@ -173,7 +173,7 @@ "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ - { "$ref": "ref-and-definitions.json" } + { "$ref": "draft6/ref-and-definitions.json" } ] }, "tests": [ @@ -196,7 +196,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft6/locationIndependentIdentifier.json#/definitions/refToInteger" }, "tests": [ { diff --git a/tests/draft7/additionalItems.json b/tests/draft7/additionalItems.json index cae72361c..2c7d15582 100644 --- a/tests/draft7/additionalItems.json +++ b/tests/draft7/additionalItems.json @@ -169,6 +169,25 @@ } ] }, + { + "description": "additionalItems with heterogeneous array", + "schema": { + "items": [{}], + "additionalItems": false + }, + "tests": [ + { + "description": "heterogeneous invalid instance", + "data": [ "foo", "bar", 37 ], + "valid": false + }, + { + "description": "valid instance", + "data": [ null ], + "valid": true + } + ] + }, { "description": "additionalItems with null instance elements", "schema": { diff --git a/tests/draft7/enum.json b/tests/draft7/enum.json index f085097be..ce43acc02 100644 --- a/tests/draft7/enum.json +++ b/tests/draft7/enum.json @@ -154,6 +154,27 @@ } ] }, + { + "description": "enum with [false] does not match [0]", + "schema": {"enum": [[false]]}, + "tests": [ + { + "description": "[false] is valid", + "data": [false], + "valid": true + }, + { + "description": "[0] is invalid", + "data": [0], + "valid": false + }, + { + "description": "[0.0] is invalid", + "data": [0.0], + "valid": false + } + ] + }, { "description": "enum with true does not match 1", "schema": {"enum": [true]}, @@ -175,6 +196,27 @@ } ] }, + { + "description": "enum with [true] does not match [1]", + "schema": {"enum": [[true]]}, + "tests": [ + { + "description": "[true] is valid", + "data": [true], + "valid": true + }, + { + "description": "[1] is invalid", + "data": [1], + "valid": false + }, + { + "description": "[1.0] is invalid", + "data": [1.0], + "valid": false + } + ] + }, { "description": "enum with 0 does not match false", "schema": {"enum": [0]}, @@ -196,6 +238,27 @@ } ] }, + { + "description": "enum with [0] does not match [false]", + "schema": {"enum": [[0]]}, + "tests": [ + { + "description": "[false] is invalid", + "data": [false], + "valid": false + }, + { + "description": "[0] is valid", + "data": [0], + "valid": true + }, + { + "description": "[0.0] is valid", + "data": [0.0], + "valid": true + } + ] + }, { "description": "enum with 1 does not match true", "schema": {"enum": [1]}, @@ -217,6 +280,27 @@ } ] }, + { + "description": "enum with [1] does not match [true]", + "schema": {"enum": [[1]]}, + "tests": [ + { + "description": "[true] is invalid", + "data": [true], + "valid": false + }, + { + "description": "[1] is valid", + "data": [1], + "valid": true + }, + { + "description": "[1.0] is valid", + "data": [1.0], + "valid": true + } + ] + }, { "description": "nul characters in strings", "schema": { "enum": [ "hello\u0000there" ] }, diff --git a/tests/draft7/maxLength.json b/tests/draft7/maxLength.json index 748b4daaf..be60c5407 100644 --- a/tests/draft7/maxLength.json +++ b/tests/draft7/maxLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "two supplementary Unicode code points is long enough", + "description": "two graphemes is long enough", "data": "\uD83D\uDCA9\uD83D\uDCA9", "valid": true } diff --git a/tests/draft7/minLength.json b/tests/draft7/minLength.json index 64db94805..23c68fe3f 100644 --- a/tests/draft7/minLength.json +++ b/tests/draft7/minLength.json @@ -24,7 +24,7 @@ "valid": true }, { - "description": "one supplementary Unicode code point is not long enough", + "description": "one grapheme is not long enough", "data": "\uD83D\uDCA9", "valid": false } diff --git a/tests/draft7/not.json b/tests/draft7/not.json index 98de0eda8..b46c4ed05 100644 --- a/tests/draft7/not.json +++ b/tests/draft7/not.json @@ -93,19 +93,161 @@ ] }, { - "description": "not with boolean schema true", - "schema": {"not": true}, + "description": "forbid everything with empty schema", + "schema": { "not": {} }, "tests": [ { - "description": "any value is invalid", + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", "data": "foo", "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "forbid everything with boolean schema true", + "schema": { "not": true }, + "tests": [ + { + "description": "number is invalid", + "data": 1, + "valid": false + }, + { + "description": "string is invalid", + "data": "foo", + "valid": false + }, + { + "description": "boolean true is invalid", + "data": true, + "valid": false + }, + { + "description": "boolean false is invalid", + "data": false, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + }, + { + "description": "object is invalid", + "data": {"foo": "bar"}, + "valid": false + }, + { + "description": "empty object is invalid", + "data": {}, + "valid": false + }, + { + "description": "array is invalid", + "data": ["foo"], + "valid": false + }, + { + "description": "empty array is invalid", + "data": [], + "valid": false + } + ] + }, + { + "description": "allow everything with boolean schema false", + "schema": { "not": false }, + "tests": [ + { + "description": "number is valid", + "data": 1, + "valid": true + }, + { + "description": "string is valid", + "data": "foo", + "valid": true + }, + { + "description": "boolean true is valid", + "data": true, + "valid": true + }, + { + "description": "boolean false is valid", + "data": false, + "valid": true + }, + { + "description": "null is valid", + "data": null, + "valid": true + }, + { + "description": "object is valid", + "data": {"foo": "bar"}, + "valid": true + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + }, + { + "description": "array is valid", + "data": ["foo"], + "valid": true + }, + { + "description": "empty array is valid", + "data": [], + "valid": true } ] }, { - "description": "not with boolean schema false", - "schema": {"not": false}, + "description": "double negation", + "schema": { "not": { "not": {} } }, "tests": [ { "description": "any value is valid", diff --git a/tests/draft7/oneOf.json b/tests/draft7/oneOf.json index eeb7ae866..c30a65c0d 100644 --- a/tests/draft7/oneOf.json +++ b/tests/draft7/oneOf.json @@ -203,7 +203,7 @@ } ] }, - { + { "description": "oneOf with missing optional property", "schema": { "oneOf": [ diff --git a/tests/draft7/optional/format/hostname.json b/tests/draft7/optional/format/hostname.json index a8ecd194f..866a61788 100644 --- a/tests/draft7/optional/format/hostname.json +++ b/tests/draft7/optional/format/hostname.json @@ -112,6 +112,16 @@ "description": "single label ending with digit", "data": "hostnam3", "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + }, + { + "description": "single dot", + "data": ".", + "valid": false } ] } diff --git a/tests/draft7/optional/format/idn-hostname.json b/tests/draft7/optional/format/idn-hostname.json index 6c8f86a3a..5c8cdc77b 100644 --- a/tests/draft7/optional/format/idn-hostname.json +++ b/tests/draft7/optional/format/idn-hostname.json @@ -254,7 +254,7 @@ { "description": "Arabic-Indic digits mixed with Extended Arabic-Indic digits", "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8", - "data": "\u0660\u06f0", + "data": "\u0628\u0660\u06f0", "valid": false }, { @@ -298,6 +298,80 @@ "comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.1 https://www.w3.org/TR/alreq/#h_disjoining_enforcement", "data": "\u0628\u064a\u200c\u0628\u064a", "valid": true + }, + { + "description": "single label", + "data": "hostname", + "valid": true + }, + { + "description": "single label with hyphen", + "data": "host-name", + "valid": true + }, + { + "description": "single label with digits", + "data": "h0stn4me", + "valid": true + }, + { + "description": "single label ending with digit", + "data": "hostnam3", + "valid": true + }, + { + "description": "empty string", + "data": "", + "valid": false + } + ] + }, + { + "description": "validation of separators in internationalized host names", + "specification": [ + {"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"} + ], + "schema": { "format": "idn-hostname" }, + "tests": [ + { + "description": "single dot", + "data": ".", + "valid": false + }, + { + "description": "single ideographic full stop", + "data": "\u3002", + "valid": false + }, + { + "description": "single fullwidth full stop", + "data": "\uff0e", + "valid": false + }, + { + "description": "single halfwidth ideographic full stop", + "data": "\uff61", + "valid": false + }, + { + "description": "dot as label separator", + "data": "a.b", + "valid": true + }, + { + "description": "ideographic full stop as label separator", + "data": "a\u3002b", + "valid": true + }, + { + "description": "fullwidth full stop as label separator", + "data": "a\uff0eb", + "valid": true + }, + { + "description": "halfwidth ideographic full stop as label separator", + "data": "a\uff61b", + "valid": true } ] } diff --git a/tests/draft7/optional/format/ipv4.json b/tests/draft7/optional/format/ipv4.json index 4706581f2..9680fe620 100644 --- a/tests/draft7/optional/format/ipv4.json +++ b/tests/draft7/optional/format/ipv4.json @@ -78,6 +78,11 @@ "description": "invalid non-ASCII '২' (a Bengali 2)", "data": "1২7.0.0.1", "valid": false + }, + { + "description": "netmask is not a part of ipv4 address", + "data": "192.168.1.0/24", + "valid": false } ] } diff --git a/tests/draft7/id.json b/tests/draft7/optional/id.json similarity index 100% rename from tests/draft7/id.json rename to tests/draft7/optional/id.json diff --git a/tests/draft7/unknownKeyword.json b/tests/draft7/optional/unknownKeyword.json similarity index 100% rename from tests/draft7/unknownKeyword.json rename to tests/draft7/optional/unknownKeyword.json diff --git a/tests/draft7/propertyNames.json b/tests/draft7/propertyNames.json index f0788e649..7c7b80006 100644 --- a/tests/draft7/propertyNames.json +++ b/tests/draft7/propertyNames.json @@ -103,5 +103,52 @@ "valid": true } ] + }, + { + "description": "propertyNames with const", + "schema": {"propertyNames": {"const": "foo"}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"bar": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] + }, + { + "description": "propertyNames with enum", + "schema": {"propertyNames": {"enum": ["foo", "bar"]}}, + "tests": [ + { + "description": "object with property foo is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "object with property foo and bar is valid", + "data": {"foo": 1, "bar": 1}, + "valid": true + }, + { + "description": "object with any other property is invalid", + "data": {"baz": 1}, + "valid": false + }, + { + "description": "empty object is valid", + "data": {}, + "valid": true + } + ] } ] diff --git a/tests/draft7/refRemote.json b/tests/draft7/refRemote.json index 115e12e74..450787af6 100644 --- a/tests/draft7/refRemote.json +++ b/tests/draft7/refRemote.json @@ -17,7 +17,7 @@ }, { "description": "fragment within remote ref", - "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "schema": {"$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/integer"}, "tests": [ { "description": "remote fragment valid", @@ -34,7 +34,7 @@ { "description": "ref within remote ref", "schema": { - "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + "$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/refToInteger" }, "tests": [ { @@ -139,7 +139,7 @@ "$id": "http://localhost:1234/object", "type": "object", "properties": { - "name": {"$ref": "name.json#/definitions/orNull"} + "name": {"$ref": "draft7/name.json#/definitions/orNull"} } }, "tests": [ @@ -173,7 +173,7 @@ "schema": { "$id": "http://localhost:1234/schema-remote-ref-ref-defs1.json", "allOf": [ - { "$ref": "ref-and-definitions.json" } + { "$ref": "draft7/ref-and-definitions.json" } ] }, "tests": [ @@ -196,7 +196,7 @@ { "description": "Location-independent identifier in remote ref", "schema": { - "$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger" + "$ref": "http://localhost:1234/draft7/locationIndependentIdentifier.json#/definitions/refToInteger" }, "tests": [ { From 36623dd80683aa4b4d2a70337410595191203a35 Mon Sep 17 00:00:00 2001 From: "Kai A. Hiller" Date: Mon, 26 May 2025 11:33:17 +0200 Subject: [PATCH 095/212] Revert "Adapt test case generation from suite" This reverts commit e3bc2dcda731844a21b4b20633386f65efd9c3f3. --- jsonschema/tests/test_jsonschema_test_suite.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py index 9ff067f33..41c982553 100644 --- a/jsonschema/tests/test_jsonschema_test_suite.py +++ b/jsonschema/tests/test_jsonschema_test_suite.py @@ -136,6 +136,7 @@ def leap_second(test): DRAFT4.format_cases(), DRAFT4.optional_cases_of(name="bignum"), DRAFT4.optional_cases_of(name="float-overflow"), + DRAFT4.optional_cases_of(name="id"), DRAFT4.optional_cases_of(name="non-bmp-regex"), DRAFT4.optional_cases_of(name="zeroTerminatedFloats"), Validator=jsonschema.Draft4Validator, @@ -154,6 +155,7 @@ def leap_second(test): DRAFT6.format_cases(), DRAFT6.optional_cases_of(name="bignum"), DRAFT6.optional_cases_of(name="float-overflow"), + DRAFT6.optional_cases_of(name="id"), DRAFT6.optional_cases_of(name="non-bmp-regex"), Validator=jsonschema.Draft6Validator, format_checker=jsonschema.Draft6Validator.FORMAT_CHECKER, @@ -172,7 +174,9 @@ def leap_second(test): DRAFT7.optional_cases_of(name="bignum"), DRAFT7.optional_cases_of(name="cross-draft"), DRAFT7.optional_cases_of(name="float-overflow"), + DRAFT6.optional_cases_of(name="id"), DRAFT7.optional_cases_of(name="non-bmp-regex"), + DRAFT7.optional_cases_of(name="unknownKeyword"), Validator=jsonschema.Draft7Validator, format_checker=jsonschema.Draft7Validator.FORMAT_CHECKER, skip=lambda test: ( @@ -186,12 +190,15 @@ def leap_second(test): TestDraft201909 = DRAFT201909.to_unittest_testcase( DRAFT201909.cases(), + DRAFT201909.optional_cases_of(name="anchor"), DRAFT201909.optional_cases_of(name="bignum"), DRAFT201909.optional_cases_of(name="cross-draft"), DRAFT201909.optional_cases_of(name="float-overflow"), + DRAFT201909.optional_cases_of(name="id"), DRAFT201909.optional_cases_of(name="no-schema"), DRAFT201909.optional_cases_of(name="non-bmp-regex"), DRAFT201909.optional_cases_of(name="refOfUnknownKeyword"), + DRAFT201909.optional_cases_of(name="unknownKeyword"), Validator=jsonschema.Draft201909Validator, skip=skip( message="Vocabulary support is still in-progress.", @@ -220,12 +227,15 @@ def leap_second(test): TestDraft202012 = DRAFT202012.to_unittest_testcase( DRAFT202012.cases(), + DRAFT201909.optional_cases_of(name="anchor"), DRAFT202012.optional_cases_of(name="bignum"), DRAFT202012.optional_cases_of(name="cross-draft"), DRAFT202012.optional_cases_of(name="float-overflow"), + DRAFT202012.optional_cases_of(name="id"), DRAFT202012.optional_cases_of(name="no-schema"), DRAFT202012.optional_cases_of(name="non-bmp-regex"), DRAFT202012.optional_cases_of(name="refOfUnknownKeyword"), + DRAFT202012.optional_cases_of(name="unknownKeyword"), Validator=jsonschema.Draft202012Validator, skip=skip( message="Vocabulary support is still in-progress.", From 6d973b543030be9b53a67739d08c6f8b19f45119 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 12:44:54 -0400 Subject: [PATCH 096/212] Update pre-commit hooks. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 985a60eef..53ac18db9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.8" + rev: "v0.11.11" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 8290667beb239282529430b59e2d4ea51777b33e Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 12:45:35 -0400 Subject: [PATCH 097/212] We still need to ditch pip-licenses... --- noxfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/noxfile.py b/noxfile.py index b64d5a8b7..be4820d88 100644 --- a/noxfile.py +++ b/noxfile.py @@ -128,6 +128,7 @@ def license_check(session): "jsonschema", "jsonschema-specifications", "referencing", + "types-python-dateutil", "--allow-only", ";".join(NONGPL_LICENSES), From c64ef846095b9d790749152367c8b12bea69a116 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 12:54:58 -0400 Subject: [PATCH 098/212] This is less true than it once was... --- README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.rst b/README.rst index 4889438ab..29381f41e 100644 --- a/README.rst +++ b/README.rst @@ -134,8 +134,6 @@ I'm Julian Berman. Get in touch, via GitHub or otherwise, if you've got something to contribute, it'd be most welcome! -You can also generally find me on Libera (nick: ``Julian``) in various channels, including ``#python``. - If you feel overwhelmingly grateful, you can also `sponsor me `_. And for companies who appreciate ``jsonschema`` and its continued support and growth, ``jsonschema`` is also now supportable via `TideLift `_. From af9a8578767ca70380ca2a2f7f6c2311b702d663 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 12:56:38 -0400 Subject: [PATCH 099/212] Drop a dead pyproject section. --- pyproject.toml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bd0f00403..3c7c40c2a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -129,17 +129,10 @@ skip_covered = true [tool.doc8] ignore = [ - "D000", # see PyCQA/doc8#125 - "D001", # one sentence per line, so max length doesn't make sense + "D000", # see PyCQA/doc8#125 + "D001", # one sentence per line, so max length doesn't make sense ] -[tool.isort] -combine_as_imports = true -ensure_newline_before_comments = true -from_first = true -include_trailing_comma = true -multi_line_output = 3 - [tool.mypy] ignore_missing_imports = true show_error_codes = true @@ -155,6 +148,7 @@ ignore = [ "A001", # It's fine to shadow builtins "A002", "A003", + "A005", "ARG", # This is all wrong whenever an interface is involved "ANN", # Just let the type checker do this "B006", # Mutable arguments require care but are OK if you don't abuse them From d6c2ad7bbbdea0b2c3e627c304ad4dd325aaa254 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 12:56:48 -0400 Subject: [PATCH 100/212] Add the zizmor setup here as well. --- .github/workflows/ci.yml | 23 +++++++++------ .github/workflows/documentation-links.yml | 4 +-- .github/workflows/zizmor.yml | 35 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa9e6f8a1..57edddb57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,8 @@ on: - cron: "21 3 * * *" workflow_dispatch: +permissions: {} + jobs: list: runs-on: ubuntu-latest @@ -19,10 +21,12 @@ jobs: noxenvs: ${{ steps.noxenvs-matrix.outputs.noxenvs }} steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb with: - enable-cache: true + enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix run: | echo >>$GITHUB_OUTPUT noxenvs=$( @@ -72,6 +76,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Install dependencies run: sudo apt-get update && sudo apt-get install -y libenchant-2-dev if: runner.os == 'Linux' && startsWith(matrix.noxenv, 'docs') @@ -94,12 +100,12 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb with: enable-cache: true - name: Run nox - run: uvx nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }} + run: uvx nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }} # zizmor: ignore[template-injection] packaging: needs: ci @@ -116,8 +122,9 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb with: enable-cache: true @@ -126,10 +133,10 @@ jobs: - name: Publish to PyPI if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: pypa/gh-action-pypi-publish@release/v1 - - name: Create a Release + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc + - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 with: files: | dist/* diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml index 5757faf47..2e02d13cb 100644 --- a/.github/workflows/documentation-links.yml +++ b/.github/workflows/documentation-links.yml @@ -1,6 +1,6 @@ name: Read the Docs Pull Request Preview on: - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] types: - opened @@ -11,6 +11,6 @@ jobs: documentation-links: runs-on: ubuntu-latest steps: - - uses: readthedocs/actions/preview@v1 + - uses: readthedocs/actions/preview@b8bba1484329bda1a3abe986df7ebc80a8950333 with: project-slug: "python-jsonschema" diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 000000000..bbdd9c791 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,35 @@ +name: GitHub Actions Security Analysis with zizmor 🌈 + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +jobs: + zizmor: + name: Run zizmor + runs-on: ubuntu-latest + permissions: + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install uv + uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb + + - name: Run zizmor 🌈 + run: uvx zizmor --format=sarif .github > results.sarif + + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif + category: zizmor From 57e5e034cb0c8662995494ed4a833febf9b581a4 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 13:00:57 -0400 Subject: [PATCH 101/212] Test via PyPy 3.11. --- .github/workflows/ci.yml | 2 +- noxfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57edddb57..1890cf19f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,7 +93,7 @@ jobs: 3.11 3.12 3.13 - pypy3.10 + pypy3.11 allow-prereleases: true - name: Enable UTF-8 on Windows run: echo "PYTHONUTF8=1" >> $env:GITHUB_ENV diff --git a/noxfile.py b/noxfile.py index be4820d88..2f750385c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -36,7 +36,7 @@ "The Unlicense (Unlicense)", ] -SUPPORTED = ["3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"] +SUPPORTED = ["3.9", "3.10", "pypy3.11", "3.11", "3.12", "3.13"] LATEST_STABLE = SUPPORTED[-1] nox.options.default_venv_backend = "uv|virtualenv" From 737e5ed536db806d97879ef3681f695ddc75a32d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 13:01:37 -0400 Subject: [PATCH 102/212] Rely on ruff in pre-commit. --- .pre-commit-config.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 53ac18db9..eaa2cc878 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,12 +20,3 @@ repos: hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - - repo: https://github.com/PyCQA/isort - rev: 6.0.1 - hooks: - - id: isort - - repo: https://github.com/pre-commit/mirrors-prettier - rev: "v4.0.0-alpha.8" - hooks: - - id: prettier - exclude: "^jsonschema/benchmarks/issue232/issue.json$" From 8917e85c6549b2b2a0dfcae48fd512aaaebae836 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 13:02:23 -0400 Subject: [PATCH 103/212] Stop running CIFuzz. It isn't useful here, and isn't something I look at or maintain. --- .github/workflows/fuzz.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 .github/workflows/fuzz.yml diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml deleted file mode 100644 index eaabb4fb5..000000000 --- a/.github/workflows/fuzz.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: CIFuzz - -on: - pull_request: - branches: - - main - -jobs: - Fuzzing: - runs-on: ubuntu-latest - steps: - - name: Build Fuzzers - id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: "jsonschema" - language: python - continue-on-error: true - - name: Run Fuzzers - if: steps.build.outcome == 'success' - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: "jsonschema" - fuzz-seconds: 30 - - name: Upload Crash - uses: actions/upload-artifact@v4 - if: failure() && steps.build.outcome == 'success' - with: - name: artifacts - path: ./out/artifacts From 3e23ee5e695f84565f4175fb972073d787e1ab24 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 26 May 2025 12:55:10 -0400 Subject: [PATCH 104/212] Add the bugfix to the changelog. --- CHANGELOG.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 070573bb5..ce75f77ed 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,8 @@ v4.24.0 ======= -* Support for Python 3.8 has been dropped, as it is nearing end-of-life. +* Fix improper handling of ``unevaluatedProperties`` in the presence of ``additionalProperties`` (#1351). +* Support for Python 3.8 has been dropped, as it is end-of-life. v4.23.0 ======= From 2ca72adb08d6d4474fda7e4149b91625c6a1b7ac Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 18:03:05 +0000 Subject: [PATCH 105/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.11 → v0.11.12](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.11...v0.11.12) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eaa2cc878..e206e8933 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.11" + rev: "v0.11.12" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From d38e3bc29cd9c59b06c46fafac3c9b6afea58a5c Mon Sep 17 00:00:00 2001 From: Noah Jackowitz Date: Tue, 3 Jun 2025 18:00:22 -0600 Subject: [PATCH 106/212] since `python-requires = >=3.9`, we can cut the <3.9 backports --- jsonschema/cli.py | 6 +--- pyproject.toml | 81 +++++++++++++++++++++++------------------------ 2 files changed, 40 insertions(+), 47 deletions(-) diff --git a/jsonschema/cli.py b/jsonschema/cli.py index cf6298eb0..f3ca4d6ad 100644 --- a/jsonschema/cli.py +++ b/jsonschema/cli.py @@ -4,6 +4,7 @@ from importlib import metadata from json import JSONDecodeError +from pkgutil import resolve_name from textwrap import dedent import argparse import json @@ -11,11 +12,6 @@ import traceback import warnings -try: - from pkgutil import resolve_name -except ImportError: - from pkgutil_resolve_name import resolve_name # type: ignore[no-redef] - from attrs import define, field from jsonschema.exceptions import SchemaError diff --git a/pyproject.toml b/pyproject.toml index 3c7c40c2a..705a464a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,11 +12,11 @@ requires-python = ">=3.9" license = "MIT" license-files = ["COPYING"] keywords = [ - "validation", - "data validation", - "jsonschema", - "json", - "json schema", + "validation", + "data validation", + "jsonschema", + "json", + "json schema", ] authors = [ { name = "Julian Berman", email = "Julian+jsonschema@GrayVines.com" }, @@ -42,9 +42,6 @@ dependencies = [ "jsonschema-specifications>=2023.03.6", "referencing>=0.28.4", "rpds-py>=0.7.1", - - "importlib_resources>=1.4.0;python_version<'3.9'", - "pkgutil_resolve_name>=1.3.10;python_version<'3.9'", ] [project.optional-dependencies] @@ -129,8 +126,8 @@ skip_covered = true [tool.doc8] ignore = [ - "D000", # see PyCQA/doc8#125 - "D001", # one sentence per line, so max length doesn't make sense + "D000", # see PyCQA/doc8#125 + "D001", # one sentence per line, so max length doesn't make sense ] [tool.mypy] @@ -145,53 +142,53 @@ extend-exclude = ["json"] [tool.ruff.lint] select = ["ALL"] ignore = [ - "A001", # It's fine to shadow builtins + "A001", # It's fine to shadow builtins "A002", "A003", "A005", - "ARG", # This is all wrong whenever an interface is involved - "ANN", # Just let the type checker do this - "B006", # Mutable arguments require care but are OK if you don't abuse them - "B008", # It's totally OK to call functions for default arguments. - "B904", # raise SomeException(...) is fine. - "B905", # No need for explicit strict, this is simply zip's default behavior - "C408", # Calling dict is fine when it saves quoting the keys - "C901", # Not really something to focus on - "D105", # It's fine to not have docstrings for magic methods. - "D107", # __init__ especially doesn't need a docstring - "D200", # This rule makes diffs uglier when expanding docstrings - "D203", # No blank lines before docstrings. - "D212", # Start docstrings on the second line. - "D400", # This rule misses sassy docstrings ending with ! or ? - "D401", # This rule is too flaky. - "D406", # Section headers should end with a colon not a newline - "D407", # Underlines aren't needed - "D412", # Plz spaces after section headers - "EM101", # These don't bother me. + "ARG", # This is all wrong whenever an interface is involved + "ANN", # Just let the type checker do this + "B006", # Mutable arguments require care but are OK if you don't abuse them + "B008", # It's totally OK to call functions for default arguments. + "B904", # raise SomeException(...) is fine. + "B905", # No need for explicit strict, this is simply zip's default behavior + "C408", # Calling dict is fine when it saves quoting the keys + "C901", # Not really something to focus on + "D105", # It's fine to not have docstrings for magic methods. + "D107", # __init__ especially doesn't need a docstring + "D200", # This rule makes diffs uglier when expanding docstrings + "D203", # No blank lines before docstrings. + "D212", # Start docstrings on the second line. + "D400", # This rule misses sassy docstrings ending with ! or ? + "D401", # This rule is too flaky. + "D406", # Section headers should end with a colon not a newline + "D407", # Underlines aren't needed + "D412", # Plz spaces after section headers + "EM101", # These don't bother me. "EM102", - "FBT", # It's worth avoiding boolean args but I don't care to enforce it - "FIX", # Yes thanks, if I could it wouldn't be there - "N", # These naming rules are silly - "PERF203", # try/excepts in loops are sometimes needed - "PLR0911", # These metrics are fine to be aware of but not to enforce + "FBT", # It's worth avoiding boolean args but I don't care to enforce it + "FIX", # Yes thanks, if I could it wouldn't be there + "N", # These naming rules are silly + "PERF203", # try/excepts in loops are sometimes needed + "PLR0911", # These metrics are fine to be aware of but not to enforce "PLR0912", "PLR0913", "PLR0915", - "PLR1714", # This makes for uglier comparisons sometimes - "PLW0642", # Shadowing self also isn't a big deal. - "PLW2901", # Shadowing for loop variables is occasionally fine. - "PT", # We use unittest + "PLR1714", # This makes for uglier comparisons sometimes + "PLW0642", # Shadowing self also isn't a big deal. + "PLW2901", # Shadowing for loop variables is occasionally fine. + "PT", # We use unittest "PYI025", # wat, I'm not confused, thanks. "RET502", # Returning None implicitly is fine "RET503", "RET505", # These push you to use `if` instead of `elif`, but for no reason "RET506", "RSE102", # Ha, what, who even knew you could leave the parens off. But no. - "SIM300", # Not sure what heuristic this uses, but it's easily incorrect + "SIM300", # Not sure what heuristic this uses, but it's easily incorrect "SLF001", # Private usage within this package itself is fine - "TD", # These TODO style rules are also silly + "TD", # These TODO style rules are also silly "TRY003", # Some exception classes are essentially intended for free-form - "UP007", # We support 3.9 + "UP007", # We support 3.9 ] [tool.ruff.lint.flake8-pytest-style] From 3695022b23483efa68b24740b084618c5b45b7ef Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 17:59:02 +0000 Subject: [PATCH 107/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.12 → v0.11.13](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.12...v0.11.13) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e206e8933..5253310d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.12" + rev: "v0.11.13" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From a4f47c8d5c000e1d5651f63fac107cca45307d77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 10:16:54 +0000 Subject: [PATCH 108/212] Bump softprops/action-gh-release from 2.2.2 to 2.3.2 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.2.2 to 2.3.2. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/da05d552573ad5aba039eaac05058a918a7bf631...72f2c25fcb47643c292f7107632f7a47c1df5cd8) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 2.3.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1890cf19f..43ff772e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 + uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 with: files: | dist/* From 5fdb8044607ef3e3b8bec9c1f091150ce9978de0 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 23 Jun 2025 14:19:09 -0400 Subject: [PATCH 109/212] Update pre-commit hooks. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5253310d7..522ce58a6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.11.13" + rev: "v0.12.0" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 5e959e5868ae660d913bb6814781fc47623e99eb Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 23 Jun 2025 14:19:15 -0400 Subject: [PATCH 110/212] Quiet some style noise. --- jsonschema/exceptions.py | 2 +- pyproject.toml | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 3dcd29667..083a423f7 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -210,7 +210,7 @@ class SchemaError(_Error): @define(slots=False) -class _RefResolutionError(Exception): +class _RefResolutionError(Exception): # noqa: PLW1641 """ A ref could not be resolved. """ diff --git a/pyproject.toml b/pyproject.toml index 705a464a2..fc176a531 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -170,6 +170,7 @@ ignore = [ "FIX", # Yes thanks, if I could it wouldn't be there "N", # These naming rules are silly "PERF203", # try/excepts in loops are sometimes needed + "PLC0415", # too noisy, there are too many cases this is fine "PLR0911", # These metrics are fine to be aware of but not to enforce "PLR0912", "PLR0913", @@ -204,6 +205,15 @@ from-first = true [tool.ruff.lint.per-file-ignores] "noxfile.py" = ["ANN", "D100", "S101", "T201"] "docs/*" = ["ANN", "D", "INP001"] -"jsonschema/tests/*" = ["ANN", "D", "RUF012", "S", "PLR", "PYI024", "TRY"] +"jsonschema/tests/*" = [ + "ANN", + "D", + "RUF012", + "S", + "PLR", + "PLW1641", + "PYI024", + "TRY", +] "jsonschema/tests/test_format.py" = ["ERA001"] "jsonschema/benchmarks/*" = ["ANN", "D", "INP001", "S101"] From ac1d8e7c6c27a0df29ee3d6beb47c58946eb31d8 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 23 Jun 2025 14:20:02 -0400 Subject: [PATCH 111/212] Update docs requirements. --- docs/requirements.txt | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8d5743117..bac8d739b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,7 +2,7 @@ # uv pip compile --output-file /Users/julian/Development/jsonschema/docs/requirements.txt docs/requirements.in alabaster==1.0.0 # via sphinx -astroid==3.3.9 +astroid==3.3.10 # via sphinx-autoapi attrs==25.3.0 # via @@ -10,11 +10,11 @@ attrs==25.3.0 # referencing babel==2.17.0 # via sphinx -beautifulsoup4==4.13.3 +beautifulsoup4==4.13.4 # via furo -certifi==2025.1.31 +certifi==2025.6.15 # via requests -charset-normalizer==3.4.1 +charset-normalizer==3.4.2 # via requests docutils==0.21.2 # via sphinx @@ -30,19 +30,19 @@ jinja2==3.1.6 # sphinx-autoapi jsonschema @ file:. # via -r docs/requirements.in -jsonschema-specifications==2024.10.1 +jsonschema-specifications==2025.4.1 # via jsonschema -lxml==5.3.1 +lxml==5.4.0 # via # -r docs/requirements.in # sphinx-json-schema-spec markupsafe==3.0.2 # via jinja2 -packaging==24.2 +packaging==25.0 # via sphinx pyenchant==3.2.2 # via sphinxcontrib-spelling -pygments==2.19.1 +pygments==2.19.2 # via # furo # sphinx @@ -52,19 +52,19 @@ referencing==0.36.2 # via # jsonschema # jsonschema-specifications -requests==2.32.3 +requests==2.32.4 # via # sphinx # sphinxcontrib-spelling roman-numerals-py==3.1.0 # via sphinx -rpds-py==0.24.0 +rpds-py==0.25.1 # via # jsonschema # referencing -snowballstemmer==2.2.0 +snowballstemmer==3.0.1 # via sphinx -soupsieve==2.6 +soupsieve==2.7 # via beautifulsoup4 sphinx==8.2.3 # via @@ -79,7 +79,7 @@ sphinx==8.2.3 # sphinxext-opengraph sphinx-autoapi==3.6.0 # via -r docs/requirements.in -sphinx-autodoc-typehints==3.1.0 +sphinx-autodoc-typehints==3.2.0 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo @@ -101,9 +101,9 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphinxcontrib-spelling==8.0.1 # via -r docs/requirements.in -sphinxext-opengraph==0.9.1 +sphinxext-opengraph==0.10.0 # via -r docs/requirements.in -typing-extensions==4.13.0 +typing-extensions==4.14.0 # via beautifulsoup4 -urllib3==2.3.0 +urllib3==2.5.0 # via requests From 2edd98e3dc0f32e908fad9cbfdd7432c6e0421f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 18:24:04 +0000 Subject: [PATCH 112/212] Bump astral-sh/setup-uv from 6.1.0 to 6.3.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.1.0 to 6.3.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb...445689ea25e0de0a23313031f5fe577c74ae45a1) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 43ff772e3..2d8a5e0d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb + uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb + uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb + uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index bbdd9c791..c329fb59f 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb + uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 680f3f2bb0105cd86b259bf5c8625bdf5072bc6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:03:32 +0000 Subject: [PATCH 113/212] Bump astral-sh/setup-uv from 6.3.0 to 6.3.1 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.3.0 to 6.3.1. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/445689ea25e0de0a23313031f5fe577c74ae45a1...bd01e18f51369d5a26f1651c3cb451d3417e3bba) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 6.3.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d8a5e0d1..0782a1bd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 + uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 + uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 + uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index c329fb59f..17f2bd11c 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 + uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 22ba56b2432b2d738e3c6620076dc2703045fbca Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 17:55:38 +0000 Subject: [PATCH 114/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.0 → v0.12.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.0...v0.12.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 522ce58a6..df39f42c5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.0" + rev: "v0.12.1" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 64346c989d9cee69aea7edbc09d794983d12d906 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Tue, 1 Jul 2025 11:32:52 -0400 Subject: [PATCH 115/212] Update docs requirements. --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index bac8d739b..cdd004539 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -32,7 +32,7 @@ jsonschema @ file:. # via -r docs/requirements.in jsonschema-specifications==2025.4.1 # via jsonschema -lxml==5.4.0 +lxml==6.0.0 # via # -r docs/requirements.in # sphinx-json-schema-spec From c3f0d1a09b5b1ef0a3a1aa077e7b164325183d58 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 18:12:58 +0000 Subject: [PATCH 116/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.1 → v0.12.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.1...v0.12.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index df39f42c5..54a6fad7e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.1" + rev: "v0.12.2" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 51f34b20acefa517312f96579baeb09cc3d255ba Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 18:01:03 +0000 Subject: [PATCH 117/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.2 → v0.12.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.2...v0.12.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 54a6fad7e..77b36341c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.2" + rev: "v0.12.3" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 8dd4f567caffc8b7e27eeebc8f23a889a3168bbb Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 16 Jul 2025 13:05:32 +0200 Subject: [PATCH 118/212] feat: use non-GPL validator for rfc3987 Signed-off-by: Jan Kowalleck --- docs/validate.rst | 7 +++---- jsonschema/_format.py | 25 +++++++++++++++++++++++++ pyproject.toml | 1 + 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/docs/validate.rst b/docs/validate.rst index 91f0577b9..bc740e340 100644 --- a/docs/validate.rst +++ b/docs/validate.rst @@ -206,8 +206,6 @@ Or if you want to avoid GPL dependencies, a second extra is available: $ pip install jsonschema[format-nongpl] -At the moment, it supports all the available checkers except for ``iri`` and ``iri-reference``. - .. warning:: It is your own responsibility ultimately to ensure you are license-compliant, so you should be double checking your own dependencies if you rely on this extra. @@ -230,8 +228,8 @@ Checker Notes ``idn-hostname`` requires idna_ ``ipv4`` ``ipv6`` OS must have `socket.inet_pton` function -``iri`` requires rfc3987_ -``iri-reference`` requires rfc3987_ +``iri`` requires rfc3987_ or rfc3987-syntax_ +``iri-reference`` requires rfc3987_ or rfc3987-syntax_ ``json-pointer`` requires jsonpointer_ ``regex`` ``relative-json-pointer`` requires jsonpointer_ @@ -249,6 +247,7 @@ Checker Notes .. _rfc3339-validator: https://pypi.org/project/rfc3339-validator/ .. _rfc3986-validator: https://pypi.org/project/rfc3986-validator/ .. _rfc3987: https://pypi.org/pypi/rfc3987/ +.. _rfc3987-syntax: https://pypi.org/pypi/rfc3987-syntax/ .. _uri-template: https://pypi.org/pypi/uri-template/ .. _webcolors: https://pypi.org/pypi/webcolors/ diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 9b4e67b63..6fc7a01e1 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -324,6 +324,31 @@ def is_uri_reference(instance: object) -> bool: return True return validate_rfc3986(instance, rule="URI_reference") + with suppress(ImportError): + from rfc3987_syntax import is_valid_syntax as _rfc3987_is_valid_syntax + + @_checks_drafts( + draft7="iri", + draft201909="iri", + draft202012="iri", + raises=ValueError, + ) + def is_iri(instance: object) -> bool: + if not isinstance(instance, str): + return True + return _rfc3987_is_valid_syntax("iri", instance) + + @_checks_drafts( + draft7="iri-reference", + draft201909="iri-reference", + draft202012="iri-reference", + raises=ValueError, + ) + def is_iri_reference(instance: object) -> bool: + if not isinstance(instance, str): + return True + return _rfc3987_is_valid_syntax("iri_reference", instance) + else: @_checks_drafts( diff --git a/pyproject.toml b/pyproject.toml index fc176a531..eef060cb5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,6 +62,7 @@ format-nongpl = [ "jsonpointer>1.13", "rfc3339-validator", "rfc3986-validator>0.1.0", + "rfc3987-syntax", "uri_template", "webcolors>=24.6.0", ] From 9a957d770d6e63646f4fc874bf8df6be4593f8c8 Mon Sep 17 00:00:00 2001 From: Kurt McKee Date: Wed, 16 Jul 2025 12:03:12 -0500 Subject: [PATCH 119/212] Unambiguously quote and escape properties in JSON path rendering Fixes #1389 --- jsonschema/exceptions.py | 8 +- jsonschema/tests/test_exceptions.py | 119 ++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 083a423f7..ec280ff2e 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -8,6 +8,7 @@ from textwrap import dedent, indent from typing import TYPE_CHECKING, Any, ClassVar import heapq +import re import warnings from attrs import define @@ -23,6 +24,8 @@ WEAK_MATCHES: frozenset[str] = frozenset(["anyOf", "oneOf"]) STRONG_MATCHES: frozenset[str] = frozenset() +JSON_PATH_COMPATIBLE_PROPERTY_PATTERN = re.compile("^[a-zA-Z][a-zA-Z0-9_]*$") + _unset = _utils.Unset() @@ -152,8 +155,11 @@ def json_path(self) -> str: for elem in self.absolute_path: if isinstance(elem, int): path += "[" + str(elem) + "]" - else: + elif JSON_PATH_COMPATIBLE_PROPERTY_PATTERN.match(elem): path += "." + elem + else: + escaped_elem = elem.replace("\\", "\\\\").replace("'", r"\'") + path += "['" + escaped_elem + "']" return path def _set( diff --git a/jsonschema/tests/test_exceptions.py b/jsonschema/tests/test_exceptions.py index 69114e182..2a3a5f25f 100644 --- a/jsonschema/tests/test_exceptions.py +++ b/jsonschema/tests/test_exceptions.py @@ -700,3 +700,122 @@ class TestHashable(TestCase): def test_hashable(self): {exceptions.ValidationError("")} {exceptions.SchemaError("")} + + +class TestJsonPathRendering(TestCase): + def test_str(self): + e = exceptions.ValidationError( + path=["x"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$.x") + + def test_empty_str(self): + e = exceptions.ValidationError( + path=[""], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$['']") + + def test_numeric_str(self): + e = exceptions.ValidationError( + path=["1"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$['1']") + + def test_period_str(self): + e = exceptions.ValidationError( + path=["."], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$['.']") + + def test_single_quote_str(self): + e = exceptions.ValidationError( + path=["'"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, r"$['\'']") + + def test_space_str(self): + e = exceptions.ValidationError( + path=[" "], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$[' ']") + + def test_backslash_str(self): + e = exceptions.ValidationError( + path=["\\"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, r"$['\\']") + + def test_backslash_single_quote(self): + e = exceptions.ValidationError( + path=[r"\'"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, r"$['\\\'']") + + def test_underscore(self): + e = exceptions.ValidationError( + path=["_"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, r"$['_']") + + def test_double_quote(self): + e = exceptions.ValidationError( + path=['"'], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, """$['"']""") + + def test_hyphen(self): + e = exceptions.ValidationError( + path=["-"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$['-']") + + def test_json_path_injection(self): + e = exceptions.ValidationError( + path=["a[0]"], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$['a[0]']") + + def test_open_bracket(self): + e = exceptions.ValidationError( + path=["["], + message="1", + validator="foo", + instance="i1", + ) + self.assertEqual(e.json_path, "$['[']") From 2680f6ab44d6fe36d321fef6ee626608a5f0ec7a Mon Sep 17 00:00:00 2001 From: Kurt McKee Date: Thu, 17 Jul 2025 08:20:46 -0500 Subject: [PATCH 120/212] Feedback: Make a compiled regex pattern private --- jsonschema/exceptions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index ec280ff2e..d955e356e 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -24,7 +24,7 @@ WEAK_MATCHES: frozenset[str] = frozenset(["anyOf", "oneOf"]) STRONG_MATCHES: frozenset[str] = frozenset() -JSON_PATH_COMPATIBLE_PROPERTY_PATTERN = re.compile("^[a-zA-Z][a-zA-Z0-9_]*$") +_JSON_PATH_COMPATIBLE_PROPERTY_PATTERN = re.compile("^[a-zA-Z][a-zA-Z0-9_]*$") _unset = _utils.Unset() @@ -155,7 +155,7 @@ def json_path(self) -> str: for elem in self.absolute_path: if isinstance(elem, int): path += "[" + str(elem) + "]" - elif JSON_PATH_COMPATIBLE_PROPERTY_PATTERN.match(elem): + elif _JSON_PATH_COMPATIBLE_PROPERTY_PATTERN.match(elem): path += "." + elem else: escaped_elem = elem.replace("\\", "\\\\").replace("'", r"\'") From 4cf45b95de90191b02396bd04d41760d9798ecd6 Mon Sep 17 00:00:00 2001 From: Kurt McKee Date: Thu, 17 Jul 2025 08:21:22 -0500 Subject: [PATCH 121/212] Feedback: Use jsonpath-ng to re-parse the rendered JSON path --- jsonschema/tests/test_exceptions.py | 126 +++++++--------------------- noxfile.py | 1 + 2 files changed, 33 insertions(+), 94 deletions(-) diff --git a/jsonschema/tests/test_exceptions.py b/jsonschema/tests/test_exceptions.py index 2a3a5f25f..8d515a998 100644 --- a/jsonschema/tests/test_exceptions.py +++ b/jsonschema/tests/test_exceptions.py @@ -1,6 +1,8 @@ from unittest import TestCase import textwrap +import jsonpath_ng + from jsonschema import exceptions from jsonschema.validators import _LATEST_VERSION @@ -703,119 +705,55 @@ def test_hashable(self): class TestJsonPathRendering(TestCase): - def test_str(self): - e = exceptions.ValidationError( - path=["x"], + def validate_json_path_rendering(self, property_name, expected_path): + error = exceptions.ValidationError( + path=[property_name], message="1", validator="foo", instance="i1", ) - self.assertEqual(e.json_path, "$.x") - def test_empty_str(self): - e = exceptions.ValidationError( - path=[""], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, "$['']") + rendered_json_path = error.json_path + self.assertEqual(rendered_json_path, expected_path) - def test_numeric_str(self): - e = exceptions.ValidationError( - path=["1"], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, "$['1']") + re_parsed_name = jsonpath_ng.parse(rendered_json_path).right.fields[0] + self.assertEqual(re_parsed_name, property_name) - def test_period_str(self): - e = exceptions.ValidationError( - path=["."], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, "$['.']") + def test_basic(self): + self.validate_json_path_rendering("x", "$.x") - def test_single_quote_str(self): - e = exceptions.ValidationError( - path=["'"], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, r"$['\'']") + def test_empty(self): + self.validate_json_path_rendering("", "$['']") - def test_space_str(self): - e = exceptions.ValidationError( - path=[" "], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, "$[' ']") + def test_number(self): + self.validate_json_path_rendering("1", "$['1']") - def test_backslash_str(self): - e = exceptions.ValidationError( - path=["\\"], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, r"$['\\']") + def test_period(self): + self.validate_json_path_rendering(".", "$['.']") + + def test_single_quote(self): + self.validate_json_path_rendering("'", r"$['\'']") + + def test_space(self): + self.validate_json_path_rendering(" ", "$[' ']") + + def test_backslash(self): + self.validate_json_path_rendering("\\", r"$['\\']") def test_backslash_single_quote(self): - e = exceptions.ValidationError( - path=[r"\'"], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, r"$['\\\'']") + self.validate_json_path_rendering(r"\'", r"$['\\\'']") def test_underscore(self): - e = exceptions.ValidationError( - path=["_"], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, r"$['_']") + self.validate_json_path_rendering("_", r"$['_']") def test_double_quote(self): - e = exceptions.ValidationError( - path=['"'], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, """$['"']""") + self.validate_json_path_rendering('"', """$['"']""") def test_hyphen(self): - e = exceptions.ValidationError( - path=["-"], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, "$['-']") + self.validate_json_path_rendering("-", "$['-']") def test_json_path_injection(self): - e = exceptions.ValidationError( - path=["a[0]"], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, "$['a[0]']") + self.validate_json_path_rendering("a[0]", "$['a[0]']") def test_open_bracket(self): - e = exceptions.ValidationError( - path=["["], - message="1", - validator="foo", - instance="i1", - ) - self.assertEqual(e.json_path, "$['[']") + self.validate_json_path_rendering("[", "$['[']") diff --git a/noxfile.py b/noxfile.py index 2f750385c..f9869a35c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -61,6 +61,7 @@ def tests(session, installable): env = dict(JSON_SCHEMA_TEST_SUITE=str(ROOT / "json")) session.install("virtue", installable) + session.install("jsonpath-ng", installable) if session.posargs and session.posargs[0] == "coverage": if len(session.posargs) > 1 and session.posargs[1] == "github": From dc547341f2a3304d73114b1d18da063be7fc43e0 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 17 Jul 2025 09:52:13 -0400 Subject: [PATCH 122/212] Add a uv.lock. --- .github/workflows/ci.yml | 2 +- pyproject.toml | 2 +- uv.lock | 385 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 387 insertions(+), 2 deletions(-) create mode 100644 uv.lock diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0782a1bd0..a45d18101 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,7 +129,7 @@ jobs: enable-cache: true - name: Build our distributions - run: uv run --with 'build[uv]' -m build --installer=uv + run: uv run --frozen --with 'build[uv]' -m build --installer=uv - name: Publish to PyPI if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') diff --git a/pyproject.toml b/pyproject.toml index fc176a531..a8830b603 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -164,7 +164,7 @@ ignore = [ "D406", # Section headers should end with a colon not a newline "D407", # Underlines aren't needed "D412", # Plz spaces after section headers - "EM101", # These don't bother me. + "EM101", # These don't bother me, it's fine there's some duplication. "EM102", "FBT", # It's worth avoiding boolean args but I don't care to enforce it "FIX", # Yes thanks, if I could it wouldn't be there diff --git a/uv.lock b/uv.lock new file mode 100644 index 000000000..dae43e742 --- /dev/null +++ b/uv.lock @@ -0,0 +1,385 @@ +version = 1 +revision = 2 +requires-python = ">=3.9" + +[[package]] +name = "arrow" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "types-python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" }, +] + +[[package]] +name = "attrs" +version = "25.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, +] + +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" }, +] + +[[package]] +name = "jsonschema" +source = { editable = "." } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] + +[package.optional-dependencies] +format = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3987" }, + { name = "uri-template" }, + { name = "webcolors" }, +] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + +[package.metadata] +requires-dist = [ + { name = "attrs", specifier = ">=22.2.0" }, + { name = "fqdn", marker = "extra == 'format'" }, + { name = "fqdn", marker = "extra == 'format-nongpl'" }, + { name = "idna", marker = "extra == 'format'" }, + { name = "idna", marker = "extra == 'format-nongpl'" }, + { name = "isoduration", marker = "extra == 'format'" }, + { name = "isoduration", marker = "extra == 'format-nongpl'" }, + { name = "jsonpointer", marker = "extra == 'format'", specifier = ">1.13" }, + { name = "jsonpointer", marker = "extra == 'format-nongpl'", specifier = ">1.13" }, + { name = "jsonschema-specifications", specifier = ">=2023.3.6" }, + { name = "referencing", specifier = ">=0.28.4" }, + { name = "rfc3339-validator", marker = "extra == 'format'" }, + { name = "rfc3339-validator", marker = "extra == 'format-nongpl'" }, + { name = "rfc3986-validator", marker = "extra == 'format-nongpl'", specifier = ">0.1.0" }, + { name = "rfc3987", marker = "extra == 'format'" }, + { name = "rpds-py", specifier = ">=0.7.1" }, + { name = "uri-template", marker = "extra == 'format'" }, + { name = "uri-template", marker = "extra == 'format-nongpl'" }, + { name = "webcolors", marker = "extra == 'format'", specifier = ">=1.11" }, + { name = "webcolors", marker = "extra == 'format-nongpl'", specifier = ">=24.6.0" }, +] +provides-extras = ["format", "format-nongpl"] + +[[package]] +name = "jsonschema-specifications" +version = "2025.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "referencing" +version = "0.36.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, +] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, +] + +[[package]] +name = "rfc3987" +version = "1.3.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/14/bb/f1395c4b62f251a1cb503ff884500ebd248eed593f41b469f89caa3547bd/rfc3987-1.3.8.tar.gz", hash = "sha256:d3c4d257a560d544e9826b38bc81db676890c79ab9d7ac92b39c7a253d5ca733", size = 20700, upload-time = "2018-07-29T17:23:47.954Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/d4/f7407c3d15d5ac779c3dd34fbbc6ea2090f77bd7dd12f207ccf881551208/rfc3987-1.3.8-py2.py3-none-any.whl", hash = "sha256:10702b1e51e5658843460b189b185c0366d2cf4cff716f13111b0ea9fd2dce53", size = 13377, upload-time = "2018-07-29T17:23:45.313Z" }, +] + +[[package]] +name = "rpds-py" +version = "0.26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/aa/4456d84bbb54adc6a916fb10c9b374f78ac840337644e4a5eda229c81275/rpds_py-0.26.0.tar.gz", hash = "sha256:20dae58a859b0906f0685642e591056f1e787f3a8b39c8e8749a45dc7d26bdb0", size = 27385, upload-time = "2025-07-01T15:57:13.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/31/1459645f036c3dfeacef89e8e5825e430c77dde8489f3b99eaafcd4a60f5/rpds_py-0.26.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4c70c70f9169692b36307a95f3d8c0a9fcd79f7b4a383aad5eaa0e9718b79b37", size = 372466, upload-time = "2025-07-01T15:53:40.55Z" }, + { url = "https://files.pythonhosted.org/packages/dd/ff/3d0727f35836cc8773d3eeb9a46c40cc405854e36a8d2e951f3a8391c976/rpds_py-0.26.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:777c62479d12395bfb932944e61e915741e364c843afc3196b694db3d669fcd0", size = 357825, upload-time = "2025-07-01T15:53:42.247Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ce/badc5e06120a54099ae287fa96d82cbb650a5f85cf247ffe19c7b157fd1f/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec671691e72dff75817386aa02d81e708b5a7ec0dec6669ec05213ff6b77e1bd", size = 381530, upload-time = "2025-07-01T15:53:43.585Z" }, + { url = "https://files.pythonhosted.org/packages/1e/a5/fa5d96a66c95d06c62d7a30707b6a4cfec696ab8ae280ee7be14e961e118/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a1cb5d6ce81379401bbb7f6dbe3d56de537fb8235979843f0d53bc2e9815a79", size = 396933, upload-time = "2025-07-01T15:53:45.78Z" }, + { url = "https://files.pythonhosted.org/packages/00/a7/7049d66750f18605c591a9db47d4a059e112a0c9ff8de8daf8fa0f446bba/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f789e32fa1fb6a7bf890e0124e7b42d1e60d28ebff57fe806719abb75f0e9a3", size = 513973, upload-time = "2025-07-01T15:53:47.085Z" }, + { url = "https://files.pythonhosted.org/packages/0e/f1/528d02c7d6b29d29fac8fd784b354d3571cc2153f33f842599ef0cf20dd2/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c55b0a669976cf258afd718de3d9ad1b7d1fe0a91cd1ab36f38b03d4d4aeaaf", size = 402293, upload-time = "2025-07-01T15:53:48.117Z" }, + { url = "https://files.pythonhosted.org/packages/15/93/fde36cd6e4685df2cd08508f6c45a841e82f5bb98c8d5ecf05649522acb5/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70d9ec912802ecfd6cd390dadb34a9578b04f9bcb8e863d0a7598ba5e9e7ccc", size = 383787, upload-time = "2025-07-01T15:53:50.874Z" }, + { url = "https://files.pythonhosted.org/packages/69/f2/5007553aaba1dcae5d663143683c3dfd03d9395289f495f0aebc93e90f24/rpds_py-0.26.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3021933c2cb7def39d927b9862292e0f4c75a13d7de70eb0ab06efed4c508c19", size = 416312, upload-time = "2025-07-01T15:53:52.046Z" }, + { url = "https://files.pythonhosted.org/packages/8f/a7/ce52c75c1e624a79e48a69e611f1c08844564e44c85db2b6f711d76d10ce/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a7898b6ca3b7d6659e55cdac825a2e58c638cbf335cde41f4619e290dd0ad11", size = 558403, upload-time = "2025-07-01T15:53:53.192Z" }, + { url = "https://files.pythonhosted.org/packages/79/d5/e119db99341cc75b538bf4cb80504129fa22ce216672fb2c28e4a101f4d9/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:12bff2ad9447188377f1b2794772f91fe68bb4bbfa5a39d7941fbebdbf8c500f", size = 588323, upload-time = "2025-07-01T15:53:54.336Z" }, + { url = "https://files.pythonhosted.org/packages/93/94/d28272a0b02f5fe24c78c20e13bbcb95f03dc1451b68e7830ca040c60bd6/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:191aa858f7d4902e975d4cf2f2d9243816c91e9605070aeb09c0a800d187e323", size = 554541, upload-time = "2025-07-01T15:53:55.469Z" }, + { url = "https://files.pythonhosted.org/packages/93/e0/8c41166602f1b791da892d976057eba30685486d2e2c061ce234679c922b/rpds_py-0.26.0-cp310-cp310-win32.whl", hash = "sha256:b37a04d9f52cb76b6b78f35109b513f6519efb481d8ca4c321f6a3b9580b3f45", size = 220442, upload-time = "2025-07-01T15:53:56.524Z" }, + { url = "https://files.pythonhosted.org/packages/87/f0/509736bb752a7ab50fb0270c2a4134d671a7b3038030837e5536c3de0e0b/rpds_py-0.26.0-cp310-cp310-win_amd64.whl", hash = "sha256:38721d4c9edd3eb6670437d8d5e2070063f305bfa2d5aa4278c51cedcd508a84", size = 231314, upload-time = "2025-07-01T15:53:57.842Z" }, + { url = "https://files.pythonhosted.org/packages/09/4c/4ee8f7e512030ff79fda1df3243c88d70fc874634e2dbe5df13ba4210078/rpds_py-0.26.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9e8cb77286025bdb21be2941d64ac6ca016130bfdcd228739e8ab137eb4406ed", size = 372610, upload-time = "2025-07-01T15:53:58.844Z" }, + { url = "https://files.pythonhosted.org/packages/fa/9d/3dc16be00f14fc1f03c71b1d67c8df98263ab2710a2fbd65a6193214a527/rpds_py-0.26.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e09330b21d98adc8ccb2dbb9fc6cb434e8908d4c119aeaa772cb1caab5440a0", size = 358032, upload-time = "2025-07-01T15:53:59.985Z" }, + { url = "https://files.pythonhosted.org/packages/e7/5a/7f1bf8f045da2866324a08ae80af63e64e7bfaf83bd31f865a7b91a58601/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9c1b92b774b2e68d11193dc39620d62fd8ab33f0a3c77ecdabe19c179cdbc1", size = 381525, upload-time = "2025-07-01T15:54:01.162Z" }, + { url = "https://files.pythonhosted.org/packages/45/8a/04479398c755a066ace10e3d158866beb600867cacae194c50ffa783abd0/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:824e6d3503ab990d7090768e4dfd9e840837bae057f212ff9f4f05ec6d1975e7", size = 397089, upload-time = "2025-07-01T15:54:02.319Z" }, + { url = "https://files.pythonhosted.org/packages/72/88/9203f47268db488a1b6d469d69c12201ede776bb728b9d9f29dbfd7df406/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ad7fd2258228bf288f2331f0a6148ad0186b2e3643055ed0db30990e59817a6", size = 514255, upload-time = "2025-07-01T15:54:03.38Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b4/01ce5d1e853ddf81fbbd4311ab1eff0b3cf162d559288d10fd127e2588b5/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dc23bbb3e06ec1ea72d515fb572c1fea59695aefbffb106501138762e1e915e", size = 402283, upload-time = "2025-07-01T15:54:04.923Z" }, + { url = "https://files.pythonhosted.org/packages/34/a2/004c99936997bfc644d590a9defd9e9c93f8286568f9c16cdaf3e14429a7/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d80bf832ac7b1920ee29a426cdca335f96a2b5caa839811803e999b41ba9030d", size = 383881, upload-time = "2025-07-01T15:54:06.482Z" }, + { url = "https://files.pythonhosted.org/packages/05/1b/ef5fba4a8f81ce04c427bfd96223f92f05e6cd72291ce9d7523db3b03a6c/rpds_py-0.26.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0919f38f5542c0a87e7b4afcafab6fd2c15386632d249e9a087498571250abe3", size = 415822, upload-time = "2025-07-01T15:54:07.605Z" }, + { url = "https://files.pythonhosted.org/packages/16/80/5c54195aec456b292f7bd8aa61741c8232964063fd8a75fdde9c1e982328/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d422b945683e409000c888e384546dbab9009bb92f7c0b456e217988cf316107", size = 558347, upload-time = "2025-07-01T15:54:08.591Z" }, + { url = "https://files.pythonhosted.org/packages/f2/1c/1845c1b1fd6d827187c43afe1841d91678d7241cbdb5420a4c6de180a538/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a7711fa562ba2da1aa757e11024ad6d93bad6ad7ede5afb9af144623e5f76a", size = 587956, upload-time = "2025-07-01T15:54:09.963Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ff/9e979329dd131aa73a438c077252ddabd7df6d1a7ad7b9aacf6261f10faa/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238e8c8610cb7c29460e37184f6799547f7e09e6a9bdbdab4e8edb90986a2318", size = 554363, upload-time = "2025-07-01T15:54:11.073Z" }, + { url = "https://files.pythonhosted.org/packages/00/8b/d78cfe034b71ffbe72873a136e71acc7a831a03e37771cfe59f33f6de8a2/rpds_py-0.26.0-cp311-cp311-win32.whl", hash = "sha256:893b022bfbdf26d7bedb083efeea624e8550ca6eb98bf7fea30211ce95b9201a", size = 220123, upload-time = "2025-07-01T15:54:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/94/c1/3c8c94c7dd3905dbfde768381ce98778500a80db9924731d87ddcdb117e9/rpds_py-0.26.0-cp311-cp311-win_amd64.whl", hash = "sha256:87a5531de9f71aceb8af041d72fc4cab4943648d91875ed56d2e629bef6d4c03", size = 231732, upload-time = "2025-07-01T15:54:13.434Z" }, + { url = "https://files.pythonhosted.org/packages/67/93/e936fbed1b734eabf36ccb5d93c6a2e9246fbb13c1da011624b7286fae3e/rpds_py-0.26.0-cp311-cp311-win_arm64.whl", hash = "sha256:de2713f48c1ad57f89ac25b3cb7daed2156d8e822cf0eca9b96a6f990718cc41", size = 221917, upload-time = "2025-07-01T15:54:14.559Z" }, + { url = "https://files.pythonhosted.org/packages/ea/86/90eb87c6f87085868bd077c7a9938006eb1ce19ed4d06944a90d3560fce2/rpds_py-0.26.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:894514d47e012e794f1350f076c427d2347ebf82f9b958d554d12819849a369d", size = 363933, upload-time = "2025-07-01T15:54:15.734Z" }, + { url = "https://files.pythonhosted.org/packages/63/78/4469f24d34636242c924626082b9586f064ada0b5dbb1e9d096ee7a8e0c6/rpds_py-0.26.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc921b96fa95a097add244da36a1d9e4f3039160d1d30f1b35837bf108c21136", size = 350447, upload-time = "2025-07-01T15:54:16.922Z" }, + { url = "https://files.pythonhosted.org/packages/ad/91/c448ed45efdfdade82348d5e7995e15612754826ea640afc20915119734f/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e1157659470aa42a75448b6e943c895be8c70531c43cb78b9ba990778955582", size = 384711, upload-time = "2025-07-01T15:54:18.101Z" }, + { url = "https://files.pythonhosted.org/packages/ec/43/e5c86fef4be7f49828bdd4ecc8931f0287b1152c0bb0163049b3218740e7/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:521ccf56f45bb3a791182dc6b88ae5f8fa079dd705ee42138c76deb1238e554e", size = 400865, upload-time = "2025-07-01T15:54:19.295Z" }, + { url = "https://files.pythonhosted.org/packages/55/34/e00f726a4d44f22d5c5fe2e5ddd3ac3d7fd3f74a175607781fbdd06fe375/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9def736773fd56b305c0eef698be5192c77bfa30d55a0e5885f80126c4831a15", size = 517763, upload-time = "2025-07-01T15:54:20.858Z" }, + { url = "https://files.pythonhosted.org/packages/52/1c/52dc20c31b147af724b16104500fba13e60123ea0334beba7b40e33354b4/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdad4ea3b4513b475e027be79e5a0ceac8ee1c113a1a11e5edc3c30c29f964d8", size = 406651, upload-time = "2025-07-01T15:54:22.508Z" }, + { url = "https://files.pythonhosted.org/packages/2e/77/87d7bfabfc4e821caa35481a2ff6ae0b73e6a391bb6b343db2c91c2b9844/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82b165b07f416bdccf5c84546a484cc8f15137ca38325403864bfdf2b5b72f6a", size = 386079, upload-time = "2025-07-01T15:54:23.987Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d4/7f2200c2d3ee145b65b3cddc4310d51f7da6a26634f3ac87125fd789152a/rpds_py-0.26.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d04cab0a54b9dba4d278fe955a1390da3cf71f57feb78ddc7cb67cbe0bd30323", size = 421379, upload-time = "2025-07-01T15:54:25.073Z" }, + { url = "https://files.pythonhosted.org/packages/ae/13/9fdd428b9c820869924ab62236b8688b122baa22d23efdd1c566938a39ba/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:79061ba1a11b6a12743a2b0f72a46aa2758613d454aa6ba4f5a265cc48850158", size = 562033, upload-time = "2025-07-01T15:54:26.225Z" }, + { url = "https://files.pythonhosted.org/packages/f3/e1/b69686c3bcbe775abac3a4c1c30a164a2076d28df7926041f6c0eb5e8d28/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f405c93675d8d4c5ac87364bb38d06c988e11028a64b52a47158a355079661f3", size = 591639, upload-time = "2025-07-01T15:54:27.424Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c9/1e3d8c8863c84a90197ac577bbc3d796a92502124c27092413426f670990/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dafd4c44b74aa4bed4b250f1aed165b8ef5de743bcca3b88fc9619b6087093d2", size = 557105, upload-time = "2025-07-01T15:54:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/9f/c5/90c569649057622959f6dcc40f7b516539608a414dfd54b8d77e3b201ac0/rpds_py-0.26.0-cp312-cp312-win32.whl", hash = "sha256:3da5852aad63fa0c6f836f3359647870e21ea96cf433eb393ffa45263a170d44", size = 223272, upload-time = "2025-07-01T15:54:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/16/19f5d9f2a556cfed454eebe4d354c38d51c20f3db69e7b4ce6cff904905d/rpds_py-0.26.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf47cfdabc2194a669dcf7a8dbba62e37a04c5041d2125fae0233b720da6f05c", size = 234995, upload-time = "2025-07-01T15:54:32.195Z" }, + { url = "https://files.pythonhosted.org/packages/83/f0/7935e40b529c0e752dfaa7880224771b51175fce08b41ab4a92eb2fbdc7f/rpds_py-0.26.0-cp312-cp312-win_arm64.whl", hash = "sha256:20ab1ae4fa534f73647aad289003f1104092890849e0266271351922ed5574f8", size = 223198, upload-time = "2025-07-01T15:54:33.271Z" }, + { url = "https://files.pythonhosted.org/packages/6a/67/bb62d0109493b12b1c6ab00de7a5566aa84c0e44217c2d94bee1bd370da9/rpds_py-0.26.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:696764a5be111b036256c0b18cd29783fab22154690fc698062fc1b0084b511d", size = 363917, upload-time = "2025-07-01T15:54:34.755Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f3/34e6ae1925a5706c0f002a8d2d7f172373b855768149796af87bd65dcdb9/rpds_py-0.26.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1e6c15d2080a63aaed876e228efe4f814bc7889c63b1e112ad46fdc8b368b9e1", size = 350073, upload-time = "2025-07-01T15:54:36.292Z" }, + { url = "https://files.pythonhosted.org/packages/75/83/1953a9d4f4e4de7fd0533733e041c28135f3c21485faaef56a8aadbd96b5/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390e3170babf42462739a93321e657444f0862c6d722a291accc46f9d21ed04e", size = 384214, upload-time = "2025-07-01T15:54:37.469Z" }, + { url = "https://files.pythonhosted.org/packages/48/0e/983ed1b792b3322ea1d065e67f4b230f3b96025f5ce3878cc40af09b7533/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7da84c2c74c0f5bc97d853d9e17bb83e2dcafcff0dc48286916001cc114379a1", size = 400113, upload-time = "2025-07-01T15:54:38.954Z" }, + { url = "https://files.pythonhosted.org/packages/69/7f/36c0925fff6f660a80be259c5b4f5e53a16851f946eb080351d057698528/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c5fe114a6dd480a510b6d3661d09d67d1622c4bf20660a474507aaee7eeeee9", size = 515189, upload-time = "2025-07-01T15:54:40.57Z" }, + { url = "https://files.pythonhosted.org/packages/13/45/cbf07fc03ba7a9b54662c9badb58294ecfb24f828b9732970bd1a431ed5c/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3100b3090269f3a7ea727b06a6080d4eb7439dca4c0e91a07c5d133bb1727ea7", size = 406998, upload-time = "2025-07-01T15:54:43.025Z" }, + { url = "https://files.pythonhosted.org/packages/6c/b0/8fa5e36e58657997873fd6a1cf621285ca822ca75b4b3434ead047daa307/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c03c9b0c64afd0320ae57de4c982801271c0c211aa2d37f3003ff5feb75bb04", size = 385903, upload-time = "2025-07-01T15:54:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f7/b25437772f9f57d7a9fbd73ed86d0dcd76b4c7c6998348c070d90f23e315/rpds_py-0.26.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5963b72ccd199ade6ee493723d18a3f21ba7d5b957017607f815788cef50eaf1", size = 419785, upload-time = "2025-07-01T15:54:46.043Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6b/63ffa55743dfcb4baf2e9e77a0b11f7f97ed96a54558fcb5717a4b2cd732/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da4e873860ad5bab3291438525cae80169daecbfafe5657f7f5fb4d6b3f96b9", size = 561329, upload-time = "2025-07-01T15:54:47.64Z" }, + { url = "https://files.pythonhosted.org/packages/2f/07/1f4f5e2886c480a2346b1e6759c00278b8a69e697ae952d82ae2e6ee5db0/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5afaddaa8e8c7f1f7b4c5c725c0070b6eed0228f705b90a1732a48e84350f4e9", size = 590875, upload-time = "2025-07-01T15:54:48.9Z" }, + { url = "https://files.pythonhosted.org/packages/cc/bc/e6639f1b91c3a55f8c41b47d73e6307051b6e246254a827ede730624c0f8/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4916dc96489616a6f9667e7526af8fa693c0fdb4f3acb0e5d9f4400eb06a47ba", size = 556636, upload-time = "2025-07-01T15:54:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/05/4c/b3917c45566f9f9a209d38d9b54a1833f2bb1032a3e04c66f75726f28876/rpds_py-0.26.0-cp313-cp313-win32.whl", hash = "sha256:2a343f91b17097c546b93f7999976fd6c9d5900617aa848c81d794e062ab302b", size = 222663, upload-time = "2025-07-01T15:54:52.023Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0b/0851bdd6025775aaa2365bb8de0697ee2558184c800bfef8d7aef5ccde58/rpds_py-0.26.0-cp313-cp313-win_amd64.whl", hash = "sha256:0a0b60701f2300c81b2ac88a5fb893ccfa408e1c4a555a77f908a2596eb875a5", size = 234428, upload-time = "2025-07-01T15:54:53.692Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e8/a47c64ed53149c75fb581e14a237b7b7cd18217e969c30d474d335105622/rpds_py-0.26.0-cp313-cp313-win_arm64.whl", hash = "sha256:257d011919f133a4746958257f2c75238e3ff54255acd5e3e11f3ff41fd14256", size = 222571, upload-time = "2025-07-01T15:54:54.822Z" }, + { url = "https://files.pythonhosted.org/packages/89/bf/3d970ba2e2bcd17d2912cb42874107390f72873e38e79267224110de5e61/rpds_py-0.26.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:529c8156d7506fba5740e05da8795688f87119cce330c244519cf706a4a3d618", size = 360475, upload-time = "2025-07-01T15:54:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/82/9f/283e7e2979fc4ec2d8ecee506d5a3675fce5ed9b4b7cb387ea5d37c2f18d/rpds_py-0.26.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f53ec51f9d24e9638a40cabb95078ade8c99251945dad8d57bf4aabe86ecee35", size = 346692, upload-time = "2025-07-01T15:54:58.561Z" }, + { url = "https://files.pythonhosted.org/packages/e3/03/7e50423c04d78daf391da3cc4330bdb97042fc192a58b186f2d5deb7befd/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab504c4d654e4a29558eaa5bb8cea5fdc1703ea60a8099ffd9c758472cf913f", size = 379415, upload-time = "2025-07-01T15:54:59.751Z" }, + { url = "https://files.pythonhosted.org/packages/57/00/d11ee60d4d3b16808432417951c63df803afb0e0fc672b5e8d07e9edaaae/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd0641abca296bc1a00183fe44f7fced8807ed49d501f188faa642d0e4975b83", size = 391783, upload-time = "2025-07-01T15:55:00.898Z" }, + { url = "https://files.pythonhosted.org/packages/08/b3/1069c394d9c0d6d23c5b522e1f6546b65793a22950f6e0210adcc6f97c3e/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b312fecc1d017b5327afa81d4da1480f51c68810963a7336d92203dbb3d4f1", size = 512844, upload-time = "2025-07-01T15:55:02.201Z" }, + { url = "https://files.pythonhosted.org/packages/08/3b/c4fbf0926800ed70b2c245ceca99c49f066456755f5d6eb8863c2c51e6d0/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c741107203954f6fc34d3066d213d0a0c40f7bb5aafd698fb39888af277c70d8", size = 402105, upload-time = "2025-07-01T15:55:03.698Z" }, + { url = "https://files.pythonhosted.org/packages/1c/b0/db69b52ca07413e568dae9dc674627a22297abb144c4d6022c6d78f1e5cc/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc3e55a7db08dc9a6ed5fb7103019d2c1a38a349ac41901f9f66d7f95750942f", size = 383440, upload-time = "2025-07-01T15:55:05.398Z" }, + { url = "https://files.pythonhosted.org/packages/4c/e1/c65255ad5b63903e56b3bb3ff9dcc3f4f5c3badde5d08c741ee03903e951/rpds_py-0.26.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e851920caab2dbcae311fd28f4313c6953993893eb5c1bb367ec69d9a39e7ed", size = 412759, upload-time = "2025-07-01T15:55:08.316Z" }, + { url = "https://files.pythonhosted.org/packages/e4/22/bb731077872377a93c6e93b8a9487d0406c70208985831034ccdeed39c8e/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dfbf280da5f876d0b00c81f26bedce274e72a678c28845453885a9b3c22ae632", size = 556032, upload-time = "2025-07-01T15:55:09.52Z" }, + { url = "https://files.pythonhosted.org/packages/e0/8b/393322ce7bac5c4530fb96fc79cc9ea2f83e968ff5f6e873f905c493e1c4/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1cc81d14ddfa53d7f3906694d35d54d9d3f850ef8e4e99ee68bc0d1e5fed9a9c", size = 585416, upload-time = "2025-07-01T15:55:11.216Z" }, + { url = "https://files.pythonhosted.org/packages/49/ae/769dc372211835bf759319a7aae70525c6eb523e3371842c65b7ef41c9c6/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dca83c498b4650a91efcf7b88d669b170256bf8017a5db6f3e06c2bf031f57e0", size = 554049, upload-time = "2025-07-01T15:55:13.004Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f9/4c43f9cc203d6ba44ce3146246cdc38619d92c7bd7bad4946a3491bd5b70/rpds_py-0.26.0-cp313-cp313t-win32.whl", hash = "sha256:4d11382bcaf12f80b51d790dee295c56a159633a8e81e6323b16e55d81ae37e9", size = 218428, upload-time = "2025-07-01T15:55:14.486Z" }, + { url = "https://files.pythonhosted.org/packages/7e/8b/9286b7e822036a4a977f2f1e851c7345c20528dbd56b687bb67ed68a8ede/rpds_py-0.26.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff110acded3c22c033e637dd8896e411c7d3a11289b2edf041f86663dbc791e9", size = 231524, upload-time = "2025-07-01T15:55:15.745Z" }, + { url = "https://files.pythonhosted.org/packages/55/07/029b7c45db910c74e182de626dfdae0ad489a949d84a468465cd0ca36355/rpds_py-0.26.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:da619979df60a940cd434084355c514c25cf8eb4cf9a508510682f6c851a4f7a", size = 364292, upload-time = "2025-07-01T15:55:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/13/d1/9b3d3f986216b4d1f584878dca15ce4797aaf5d372d738974ba737bf68d6/rpds_py-0.26.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ea89a2458a1a75f87caabefe789c87539ea4e43b40f18cff526052e35bbb4fdf", size = 350334, upload-time = "2025-07-01T15:55:18.922Z" }, + { url = "https://files.pythonhosted.org/packages/18/98/16d5e7bc9ec715fa9668731d0cf97f6b032724e61696e2db3d47aeb89214/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feac1045b3327a45944e7dcbeb57530339f6b17baff154df51ef8b0da34c8c12", size = 384875, upload-time = "2025-07-01T15:55:20.399Z" }, + { url = "https://files.pythonhosted.org/packages/f9/13/aa5e2b1ec5ab0e86a5c464d53514c0467bec6ba2507027d35fc81818358e/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b818a592bd69bfe437ee8368603d4a2d928c34cffcdf77c2e761a759ffd17d20", size = 399993, upload-time = "2025-07-01T15:55:21.729Z" }, + { url = "https://files.pythonhosted.org/packages/17/03/8021810b0e97923abdbab6474c8b77c69bcb4b2c58330777df9ff69dc559/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a8b0dd8648709b62d9372fc00a57466f5fdeefed666afe3fea5a6c9539a0331", size = 516683, upload-time = "2025-07-01T15:55:22.918Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b1/da8e61c87c2f3d836954239fdbbfb477bb7b54d74974d8f6fcb34342d166/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d3498ad0df07d81112aa6ec6c95a7e7b1ae00929fb73e7ebee0f3faaeabad2f", size = 408825, upload-time = "2025-07-01T15:55:24.207Z" }, + { url = "https://files.pythonhosted.org/packages/38/bc/1fc173edaaa0e52c94b02a655db20697cb5fa954ad5a8e15a2c784c5cbdd/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a4146ccb15be237fdef10f331c568e1b0e505f8c8c9ed5d67759dac58ac246", size = 387292, upload-time = "2025-07-01T15:55:25.554Z" }, + { url = "https://files.pythonhosted.org/packages/7c/eb/3a9bb4bd90867d21916f253caf4f0d0be7098671b6715ad1cead9fe7bab9/rpds_py-0.26.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a9a63785467b2d73635957d32a4f6e73d5e4df497a16a6392fa066b753e87387", size = 420435, upload-time = "2025-07-01T15:55:27.798Z" }, + { url = "https://files.pythonhosted.org/packages/cd/16/e066dcdb56f5632713445271a3f8d3d0b426d51ae9c0cca387799df58b02/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:de4ed93a8c91debfd5a047be327b7cc8b0cc6afe32a716bbbc4aedca9e2a83af", size = 562410, upload-time = "2025-07-01T15:55:29.057Z" }, + { url = "https://files.pythonhosted.org/packages/60/22/ddbdec7eb82a0dc2e455be44c97c71c232983e21349836ce9f272e8a3c29/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:caf51943715b12af827696ec395bfa68f090a4c1a1d2509eb4e2cb69abbbdb33", size = 590724, upload-time = "2025-07-01T15:55:30.719Z" }, + { url = "https://files.pythonhosted.org/packages/2c/b4/95744085e65b7187d83f2fcb0bef70716a1ea0a9e5d8f7f39a86e5d83424/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4a59e5bc386de021f56337f757301b337d7ab58baa40174fb150accd480bc953", size = 558285, upload-time = "2025-07-01T15:55:31.981Z" }, + { url = "https://files.pythonhosted.org/packages/37/37/6309a75e464d1da2559446f9c811aa4d16343cebe3dbb73701e63f760caa/rpds_py-0.26.0-cp314-cp314-win32.whl", hash = "sha256:92c8db839367ef16a662478f0a2fe13e15f2227da3c1430a782ad0f6ee009ec9", size = 223459, upload-time = "2025-07-01T15:55:33.312Z" }, + { url = "https://files.pythonhosted.org/packages/d9/6f/8e9c11214c46098b1d1391b7e02b70bb689ab963db3b19540cba17315291/rpds_py-0.26.0-cp314-cp314-win_amd64.whl", hash = "sha256:b0afb8cdd034150d4d9f53926226ed27ad15b7f465e93d7468caaf5eafae0d37", size = 236083, upload-time = "2025-07-01T15:55:34.933Z" }, + { url = "https://files.pythonhosted.org/packages/47/af/9c4638994dd623d51c39892edd9d08e8be8220a4b7e874fa02c2d6e91955/rpds_py-0.26.0-cp314-cp314-win_arm64.whl", hash = "sha256:ca3f059f4ba485d90c8dc75cb5ca897e15325e4e609812ce57f896607c1c0867", size = 223291, upload-time = "2025-07-01T15:55:36.202Z" }, + { url = "https://files.pythonhosted.org/packages/4d/db/669a241144460474aab03e254326b32c42def83eb23458a10d163cb9b5ce/rpds_py-0.26.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:5afea17ab3a126006dc2f293b14ffc7ef3c85336cf451564a0515ed7648033da", size = 361445, upload-time = "2025-07-01T15:55:37.483Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/133f61cc5807c6c2fd086a46df0eb8f63a23f5df8306ff9f6d0fd168fecc/rpds_py-0.26.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:69f0c0a3df7fd3a7eec50a00396104bb9a843ea6d45fcc31c2d5243446ffd7a7", size = 347206, upload-time = "2025-07-01T15:55:38.828Z" }, + { url = "https://files.pythonhosted.org/packages/05/bf/0e8fb4c05f70273469eecf82f6ccf37248558526a45321644826555db31b/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:801a71f70f9813e82d2513c9a96532551fce1e278ec0c64610992c49c04c2dad", size = 380330, upload-time = "2025-07-01T15:55:40.175Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a8/060d24185d8b24d3923322f8d0ede16df4ade226a74e747b8c7c978e3dd3/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df52098cde6d5e02fa75c1f6244f07971773adb4a26625edd5c18fee906fa84d", size = 392254, upload-time = "2025-07-01T15:55:42.015Z" }, + { url = "https://files.pythonhosted.org/packages/b9/7b/7c2e8a9ee3e6bc0bae26bf29f5219955ca2fbb761dca996a83f5d2f773fe/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bc596b30f86dc6f0929499c9e574601679d0341a0108c25b9b358a042f51bca", size = 516094, upload-time = "2025-07-01T15:55:43.603Z" }, + { url = "https://files.pythonhosted.org/packages/75/d6/f61cafbed8ba1499b9af9f1777a2a199cd888f74a96133d8833ce5eaa9c5/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dfbe56b299cf5875b68eb6f0ebaadc9cac520a1989cac0db0765abfb3709c19", size = 402889, upload-time = "2025-07-01T15:55:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/92/19/c8ac0a8a8df2dd30cdec27f69298a5c13e9029500d6d76718130f5e5be10/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac64f4b2bdb4ea622175c9ab7cf09444e412e22c0e02e906978b3b488af5fde8", size = 384301, upload-time = "2025-07-01T15:55:47.098Z" }, + { url = "https://files.pythonhosted.org/packages/41/e1/6b1859898bc292a9ce5776016c7312b672da00e25cec74d7beced1027286/rpds_py-0.26.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:181ef9b6bbf9845a264f9aa45c31836e9f3c1f13be565d0d010e964c661d1e2b", size = 412891, upload-time = "2025-07-01T15:55:48.412Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b9/ceb39af29913c07966a61367b3c08b4f71fad841e32c6b59a129d5974698/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:49028aa684c144ea502a8e847d23aed5e4c2ef7cadfa7d5eaafcb40864844b7a", size = 557044, upload-time = "2025-07-01T15:55:49.816Z" }, + { url = "https://files.pythonhosted.org/packages/2f/27/35637b98380731a521f8ec4f3fd94e477964f04f6b2f8f7af8a2d889a4af/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e5d524d68a474a9688336045bbf76cb0def88549c1b2ad9dbfec1fb7cfbe9170", size = 585774, upload-time = "2025-07-01T15:55:51.192Z" }, + { url = "https://files.pythonhosted.org/packages/52/d9/3f0f105420fecd18551b678c9a6ce60bd23986098b252a56d35781b3e7e9/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c1851f429b822831bd2edcbe0cfd12ee9ea77868f8d3daf267b189371671c80e", size = 554886, upload-time = "2025-07-01T15:55:52.541Z" }, + { url = "https://files.pythonhosted.org/packages/6b/c5/347c056a90dc8dd9bc240a08c527315008e1b5042e7a4cf4ac027be9d38a/rpds_py-0.26.0-cp314-cp314t-win32.whl", hash = "sha256:7bdb17009696214c3b66bb3590c6d62e14ac5935e53e929bcdbc5a495987a84f", size = 219027, upload-time = "2025-07-01T15:55:53.874Z" }, + { url = "https://files.pythonhosted.org/packages/75/04/5302cea1aa26d886d34cadbf2dc77d90d7737e576c0065f357b96dc7a1a6/rpds_py-0.26.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f14440b9573a6f76b4ee4770c13f0b5921f71dde3b6fcb8dabbefd13b7fe05d7", size = 232821, upload-time = "2025-07-01T15:55:55.167Z" }, + { url = "https://files.pythonhosted.org/packages/fb/74/846ab687119c9d31fc21ab1346ef9233c31035ce53c0e2d43a130a0c5a5e/rpds_py-0.26.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:7a48af25d9b3c15684059d0d1fc0bc30e8eee5ca521030e2bffddcab5be40226", size = 372786, upload-time = "2025-07-01T15:55:56.512Z" }, + { url = "https://files.pythonhosted.org/packages/33/02/1f9e465cb1a6032d02b17cd117c7bd9fb6156bc5b40ffeb8053d8a2aa89c/rpds_py-0.26.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c71c2f6bf36e61ee5c47b2b9b5d47e4d1baad6426bfed9eea3e858fc6ee8806", size = 358062, upload-time = "2025-07-01T15:55:58.084Z" }, + { url = "https://files.pythonhosted.org/packages/2a/49/81a38e3c67ac943907a9711882da3d87758c82cf26b2120b8128e45d80df/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d815d48b1804ed7867b539236b6dd62997850ca1c91cad187f2ddb1b7bbef19", size = 381576, upload-time = "2025-07-01T15:55:59.422Z" }, + { url = "https://files.pythonhosted.org/packages/14/37/418f030a76ef59f41e55f9dc916af8afafa3c9e3be38df744b2014851474/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84cfbd4d4d2cdeb2be61a057a258d26b22877266dd905809e94172dff01a42ae", size = 397062, upload-time = "2025-07-01T15:56:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/47/e3/9090817a8f4388bfe58e28136e9682fa7872a06daff2b8a2f8c78786a6e1/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fbaa70553ca116c77717f513e08815aec458e6b69a028d4028d403b3bc84ff37", size = 516277, upload-time = "2025-07-01T15:56:02.672Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3a/1ec3dd93250fb8023f27d49b3f92e13f679141f2e59a61563f88922c2821/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39bfea47c375f379d8e87ab4bb9eb2c836e4f2069f0f65731d85e55d74666387", size = 402604, upload-time = "2025-07-01T15:56:04.453Z" }, + { url = "https://files.pythonhosted.org/packages/f2/98/9133c06e42ec3ce637936263c50ac647f879b40a35cfad2f5d4ad418a439/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1533b7eb683fb5f38c1d68a3c78f5fdd8f1412fa6b9bf03b40f450785a0ab915", size = 383664, upload-time = "2025-07-01T15:56:05.823Z" }, + { url = "https://files.pythonhosted.org/packages/a9/10/a59ce64099cc77c81adb51f06909ac0159c19a3e2c9d9613bab171f4730f/rpds_py-0.26.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c5ab0ee51f560d179b057555b4f601b7df909ed31312d301b99f8b9fc6028284", size = 415944, upload-time = "2025-07-01T15:56:07.132Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f1/ae0c60b3be9df9d5bef3527d83b8eb4b939e3619f6dd8382840e220a27df/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e5162afc9e0d1f9cae3b577d9c29ddbab3505ab39012cb794d94a005825bde21", size = 558311, upload-time = "2025-07-01T15:56:08.484Z" }, + { url = "https://files.pythonhosted.org/packages/fb/2b/bf1498ebb3ddc5eff2fe3439da88963d1fc6e73d1277fa7ca0c72620d167/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:43f10b007033f359bc3fa9cd5e6c1e76723f056ffa9a6b5c117cc35720a80292", size = 587928, upload-time = "2025-07-01T15:56:09.946Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/e6b949edf7af5629848c06d6e544a36c9f2781e2d8d03b906de61ada04d0/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e3730a48e5622e598293eee0762b09cff34dd3f271530f47b0894891281f051d", size = 554554, upload-time = "2025-07-01T15:56:11.775Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1c/aa0298372ea898620d4706ad26b5b9e975550a4dd30bd042b0fe9ae72cce/rpds_py-0.26.0-cp39-cp39-win32.whl", hash = "sha256:4b1f66eb81eab2e0ff5775a3a312e5e2e16bf758f7b06be82fb0d04078c7ac51", size = 220273, upload-time = "2025-07-01T15:56:13.273Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b0/8b3bef6ad0b35c172d1c87e2e5c2bb027d99e2a7bc7a16f744e66cf318f3/rpds_py-0.26.0-cp39-cp39-win_amd64.whl", hash = "sha256:519067e29f67b5c90e64fb1a6b6e9d2ec0ba28705c51956637bac23a2f4ddae1", size = 231627, upload-time = "2025-07-01T15:56:14.853Z" }, + { url = "https://files.pythonhosted.org/packages/ef/9a/1f033b0b31253d03d785b0cd905bc127e555ab496ea6b4c7c2e1f951f2fd/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3c0909c5234543ada2515c05dc08595b08d621ba919629e94427e8e03539c958", size = 373226, upload-time = "2025-07-01T15:56:16.578Z" }, + { url = "https://files.pythonhosted.org/packages/58/29/5f88023fd6aaaa8ca3c4a6357ebb23f6f07da6079093ccf27c99efce87db/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c1fb0cda2abcc0ac62f64e2ea4b4e64c57dfd6b885e693095460c61bde7bb18e", size = 359230, upload-time = "2025-07-01T15:56:17.978Z" }, + { url = "https://files.pythonhosted.org/packages/6c/6c/13eaebd28b439da6964dde22712b52e53fe2824af0223b8e403249d10405/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d142d2d6cf9b31c12aa4878d82ed3b2324226270b89b676ac62ccd7df52d08", size = 382363, upload-time = "2025-07-01T15:56:19.977Z" }, + { url = "https://files.pythonhosted.org/packages/55/fc/3bb9c486b06da19448646f96147796de23c5811ef77cbfc26f17307b6a9d/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a547e21c5610b7e9093d870be50682a6a6cf180d6da0f42c47c306073bfdbbf6", size = 397146, upload-time = "2025-07-01T15:56:21.39Z" }, + { url = "https://files.pythonhosted.org/packages/15/18/9d1b79eb4d18e64ba8bba9e7dec6f9d6920b639f22f07ee9368ca35d4673/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35e9a70a0f335371275cdcd08bc5b8051ac494dd58bff3bbfb421038220dc871", size = 514804, upload-time = "2025-07-01T15:56:22.78Z" }, + { url = "https://files.pythonhosted.org/packages/4f/5a/175ad7191bdbcd28785204621b225ad70e85cdfd1e09cc414cb554633b21/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dfa6115c6def37905344d56fb54c03afc49104e2ca473d5dedec0f6606913b4", size = 402820, upload-time = "2025-07-01T15:56:24.584Z" }, + { url = "https://files.pythonhosted.org/packages/11/45/6a67ecf6d61c4d4aff4bc056e864eec4b2447787e11d1c2c9a0242c6e92a/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:313cfcd6af1a55a286a3c9a25f64af6d0e46cf60bc5798f1db152d97a216ff6f", size = 384567, upload-time = "2025-07-01T15:56:26.064Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ba/16589da828732b46454c61858950a78fe4c931ea4bf95f17432ffe64b241/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7bf2496fa563c046d05e4d232d7b7fd61346e2402052064b773e5c378bf6f73", size = 416520, upload-time = "2025-07-01T15:56:27.608Z" }, + { url = "https://files.pythonhosted.org/packages/81/4b/00092999fc7c0c266045e984d56b7314734cc400a6c6dc4d61a35f135a9d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:aa81873e2c8c5aa616ab8e017a481a96742fdf9313c40f14338ca7dbf50cb55f", size = 559362, upload-time = "2025-07-01T15:56:29.078Z" }, + { url = "https://files.pythonhosted.org/packages/96/0c/43737053cde1f93ac4945157f7be1428724ab943e2132a0d235a7e161d4e/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:68ffcf982715f5b5b7686bdd349ff75d422e8f22551000c24b30eaa1b7f7ae84", size = 588113, upload-time = "2025-07-01T15:56:30.485Z" }, + { url = "https://files.pythonhosted.org/packages/46/46/8e38f6161466e60a997ed7e9951ae5de131dedc3cf778ad35994b4af823d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6188de70e190847bb6db3dc3981cbadff87d27d6fe9b4f0e18726d55795cee9b", size = 555429, upload-time = "2025-07-01T15:56:31.956Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ac/65da605e9f1dd643ebe615d5bbd11b6efa1d69644fc4bf623ea5ae385a82/rpds_py-0.26.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1c962145c7473723df9722ba4c058de12eb5ebedcb4e27e7d902920aa3831ee8", size = 231950, upload-time = "2025-07-01T15:56:33.337Z" }, + { url = "https://files.pythonhosted.org/packages/51/f2/b5c85b758a00c513bb0389f8fc8e61eb5423050c91c958cdd21843faa3e6/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f61a9326f80ca59214d1cceb0a09bb2ece5b2563d4e0cd37bfd5515c28510674", size = 373505, upload-time = "2025-07-01T15:56:34.716Z" }, + { url = "https://files.pythonhosted.org/packages/23/e0/25db45e391251118e915e541995bb5f5ac5691a3b98fb233020ba53afc9b/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:183f857a53bcf4b1b42ef0f57ca553ab56bdd170e49d8091e96c51c3d69ca696", size = 359468, upload-time = "2025-07-01T15:56:36.219Z" }, + { url = "https://files.pythonhosted.org/packages/0b/73/dd5ee6075bb6491be3a646b301dfd814f9486d924137a5098e61f0487e16/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:941c1cfdf4799d623cf3aa1d326a6b4fdb7a5799ee2687f3516738216d2262fb", size = 382680, upload-time = "2025-07-01T15:56:37.644Z" }, + { url = "https://files.pythonhosted.org/packages/2f/10/84b522ff58763a5c443f5bcedc1820240e454ce4e620e88520f04589e2ea/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72a8d9564a717ee291f554eeb4bfeafe2309d5ec0aa6c475170bdab0f9ee8e88", size = 397035, upload-time = "2025-07-01T15:56:39.241Z" }, + { url = "https://files.pythonhosted.org/packages/06/ea/8667604229a10a520fcbf78b30ccc278977dcc0627beb7ea2c96b3becef0/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:511d15193cbe013619dd05414c35a7dedf2088fcee93c6bbb7c77859765bd4e8", size = 514922, upload-time = "2025-07-01T15:56:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/24/e6/9ed5b625c0661c4882fc8cdf302bf8e96c73c40de99c31e0b95ed37d508c/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aea1f9741b603a8d8fedb0ed5502c2bc0accbc51f43e2ad1337fe7259c2b77a5", size = 402822, upload-time = "2025-07-01T15:56:42.137Z" }, + { url = "https://files.pythonhosted.org/packages/8a/58/212c7b6fd51946047fb45d3733da27e2fa8f7384a13457c874186af691b1/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4019a9d473c708cf2f16415688ef0b4639e07abaa569d72f74745bbeffafa2c7", size = 384336, upload-time = "2025-07-01T15:56:44.239Z" }, + { url = "https://files.pythonhosted.org/packages/aa/f5/a40ba78748ae8ebf4934d4b88e77b98497378bc2c24ba55ebe87a4e87057/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:093d63b4b0f52d98ebae33b8c50900d3d67e0666094b1be7a12fffd7f65de74b", size = 416871, upload-time = "2025-07-01T15:56:46.284Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a6/33b1fc0c9f7dcfcfc4a4353daa6308b3ece22496ceece348b3e7a7559a09/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2abe21d8ba64cded53a2a677e149ceb76dcf44284202d737178afe7ba540c1eb", size = 559439, upload-time = "2025-07-01T15:56:48.549Z" }, + { url = "https://files.pythonhosted.org/packages/71/2d/ceb3f9c12f8cfa56d34995097f6cd99da1325642c60d1b6680dd9df03ed8/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:4feb7511c29f8442cbbc28149a92093d32e815a28aa2c50d333826ad2a20fdf0", size = 588380, upload-time = "2025-07-01T15:56:50.086Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ed/9de62c2150ca8e2e5858acf3f4f4d0d180a38feef9fdab4078bea63d8dba/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e99685fc95d386da368013e7fb4269dd39c30d99f812a8372d62f244f662709c", size = 555334, upload-time = "2025-07-01T15:56:51.703Z" }, + { url = "https://files.pythonhosted.org/packages/7e/78/a08e2f28e91c7e45db1150813c6d760a0fb114d5652b1373897073369e0d/rpds_py-0.26.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a90a13408a7a856b87be8a9f008fff53c5080eea4e4180f6c2e546e4a972fb5d", size = 373157, upload-time = "2025-07-01T15:56:53.291Z" }, + { url = "https://files.pythonhosted.org/packages/52/01/ddf51517497c8224fb0287e9842b820ed93748bc28ea74cab56a71e3dba4/rpds_py-0.26.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ac51b65e8dc76cf4949419c54c5528adb24fc721df722fd452e5fbc236f5c40", size = 358827, upload-time = "2025-07-01T15:56:54.963Z" }, + { url = "https://files.pythonhosted.org/packages/4d/f4/acaefa44b83705a4fcadd68054280127c07cdb236a44a1c08b7c5adad40b/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59b2093224a18c6508d95cfdeba8db9cbfd6f3494e94793b58972933fcee4c6d", size = 382182, upload-time = "2025-07-01T15:56:56.474Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a2/d72ac03d37d33f6ff4713ca4c704da0c3b1b3a959f0bf5eb738c0ad94ea2/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f01a5d6444a3258b00dc07b6ea4733e26f8072b788bef750baa37b370266137", size = 397123, upload-time = "2025-07-01T15:56:58.272Z" }, + { url = "https://files.pythonhosted.org/packages/74/58/c053e9d1da1d3724434dd7a5f506623913e6404d396ff3cf636a910c0789/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6e2c12160c72aeda9d1283e612f68804621f448145a210f1bf1d79151c47090", size = 516285, upload-time = "2025-07-01T15:57:00.283Z" }, + { url = "https://files.pythonhosted.org/packages/94/41/c81e97ee88b38b6d1847c75f2274dee8d67cb8d5ed7ca8c6b80442dead75/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb28c1f569f8d33b2b5dcd05d0e6ef7005d8639c54c2f0be824f05aedf715255", size = 402182, upload-time = "2025-07-01T15:57:02.587Z" }, + { url = "https://files.pythonhosted.org/packages/74/74/38a176b34ce5197b4223e295f36350dd90713db13cf3c3b533e8e8f7484e/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1766b5724c3f779317d5321664a343c07773c8c5fd1532e4039e6cc7d1a815be", size = 384436, upload-time = "2025-07-01T15:57:04.125Z" }, + { url = "https://files.pythonhosted.org/packages/e4/21/f40b9a5709d7078372c87fd11335469dc4405245528b60007cd4078ed57a/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b6d9e5a2ed9c4988c8f9b28b3bc0e3e5b1aaa10c28d210a594ff3a8c02742daf", size = 417039, upload-time = "2025-07-01T15:57:05.608Z" }, + { url = "https://files.pythonhosted.org/packages/02/ee/ed835925731c7e87306faa80a3a5e17b4d0f532083155e7e00fe1cd4e242/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:b5f7a446ddaf6ca0fad9a5535b56fbfc29998bf0e0b450d174bbec0d600e1d72", size = 559111, upload-time = "2025-07-01T15:57:07.371Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/d6e9e686b8ffb6139b82eb1c319ef32ae99aeb21f7e4bf45bba44a760d09/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:eed5ac260dd545fbc20da5f4f15e7efe36a55e0e7cf706e4ec005b491a9546a0", size = 588609, upload-time = "2025-07-01T15:57:09.319Z" }, + { url = "https://files.pythonhosted.org/packages/e5/96/09bcab08fa12a69672716b7f86c672ee7f79c5319f1890c5a79dcb8e0df2/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:582462833ba7cee52e968b0341b85e392ae53d44c0f9af6a5927c80e539a8b67", size = 555212, upload-time = "2025-07-01T15:57:10.905Z" }, + { url = "https://files.pythonhosted.org/packages/2c/07/c554b6ed0064b6e0350a622714298e930b3cf5a3d445a2e25c412268abcf/rpds_py-0.26.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:69a607203441e07e9a8a529cff1d5b73f6a160f22db1097211e6212a68567d11", size = 232048, upload-time = "2025-07-01T15:57:12.473Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20250708" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/95/6bdde7607da2e1e99ec1c1672a759d42f26644bbacf939916e086db34870/types_python_dateutil-2.9.0.20250708.tar.gz", hash = "sha256:ccdbd75dab2d6c9696c350579f34cffe2c281e4c5f27a585b2a2438dd1d5c8ab", size = 15834, upload-time = "2025-07-08T03:14:03.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/52/43e70a8e57fefb172c22a21000b03ebcc15e47e97f5cb8495b9c2832efb4/types_python_dateutil-2.9.0.20250708-py3-none-any.whl", hash = "sha256:4d6d0cc1cc4d24a2dc3816024e502564094497b713f7befda4d5bc7a8e3fd21f", size = 17724, upload-time = "2025-07-08T03:14:02.593Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.14.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, +] + +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, +] + +[[package]] +name = "webcolors" +version = "24.11.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" }, +] From 785741e73b63d97eda3973442b109df3f8aa5892 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 17 Jul 2025 10:04:06 -0400 Subject: [PATCH 123/212] Add a dependency group for our new test dependency. And remove the minor duplicate install of the package which was happening. --- noxfile.py | 3 +-- pyproject.toml | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index f9869a35c..3a306c383 100644 --- a/noxfile.py +++ b/noxfile.py @@ -60,8 +60,7 @@ def tests(session, installable): """ env = dict(JSON_SCHEMA_TEST_SUITE=str(ROOT / "json")) - session.install("virtue", installable) - session.install("jsonpath-ng", installable) + session.install("--group=test", installable) if session.posargs and session.posargs[0] == "coverage": if len(session.posargs) > 1 and session.posargs[1] == "github": diff --git a/pyproject.toml b/pyproject.toml index a8830b603..e2c128ccc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,9 @@ Tidelift = "https://tidelift.com/subscription/pkg/pypi-jsonschema?utm_source=pyp Changelog = "https://github.com/python-jsonschema/jsonschema/blob/main/CHANGELOG.rst" Source = "https://github.com/python-jsonschema/jsonschema" +[dependency-groups] +test = ["virtue", "jsonpath-ng"] + [tool.hatch.metadata.hooks.fancy-pypi-readme] content-type = "text/x-rst" From 6aadb8b7ad7f9d5eee58eed73df5a7d865dad34c Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 17 Jul 2025 10:22:55 -0400 Subject: [PATCH 124/212] Add the fix to the CHANGELOG. --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ce75f77ed..ed0fa3b66 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +v4.24.1 +======= + +* Properly escape segments in ``ValidationError.json_path`` (#139). + v4.24.0 ======= From 1a6067fc441177d1911446c7325eee7c776007ae Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 18 Jul 2025 09:33:47 +0200 Subject: [PATCH 125/212] adjust rfc3987-syntax min-version Signed-off-by: Jan Kowalleck --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index eef060cb5..cccf2ea54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,7 @@ format-nongpl = [ "jsonpointer>1.13", "rfc3339-validator", "rfc3986-validator>0.1.0", - "rfc3987-syntax", + "rfc3987-syntax>=1.1.0", "uri_template", "webcolors>=24.6.0", ] From 9889f69eb5ccb532e2147465697f30c82b2a8bb0 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 18 Jul 2025 11:23:09 -0400 Subject: [PATCH 126/212] Add the new functionality to the CHANGELOG. --- CHANGELOG.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ed0fa3b66..0d59e4e95 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,9 @@ +v4.25.0 +======= + +* Add support for the ``iri`` and ``iri-reference`` formats to the ``format-nongpl`` extra via the MIT-licensed ``rfc3987-syntax``. + They were alread supported by the ``format`` extra. (#1388). + v4.24.1 ======= From 03bd9505f178e7a8d5845411064a07365699e19d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:07:37 +0000 Subject: [PATCH 127/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.3 → v0.12.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.3...v0.12.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 77b36341c..98448d86b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.3" + rev: "v0.12.4" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From c959d96ee13e3442c9560218a4aeb6867c887928 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 18:05:15 +0000 Subject: [PATCH 128/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.4 → v0.12.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.4...v0.12.5) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 98448d86b..b364f5fdf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.4" + rev: "v0.12.5" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 57b3b4d027ecb938e96a5580c456835c6cdb0db4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Aug 2025 12:37:05 +0000 Subject: [PATCH 129/212] Bump astral-sh/setup-uv from 6.3.1 to 6.4.3 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.3.1 to 6.4.3. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/bd01e18f51369d5a26f1651c3cb451d3417e3bba...e92bafb6253dcd438e0484186d7669ea7a8ca1cc) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 6.4.3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a45d18101..72a291dfc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba + uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba + uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba + uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 17f2bd11c..71ce97c3b 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@bd01e18f51369d5a26f1651c3cb451d3417e3bba + uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 2e91ceb8bb87d7803a2b1c132bb08abc29b175e2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Aug 2025 18:21:23 +0000 Subject: [PATCH 130/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.5 → v0.12.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.5...v0.12.7) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b364f5fdf..284c63f21 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.5" + rev: "v0.12.7" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 4be1093aab15a1ccdca6a842c1cf695e99f44527 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 18:28:10 +0000 Subject: [PATCH 131/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v5.0.0 → v6.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v5.0.0...v6.0.0) - [github.com/astral-sh/ruff-pre-commit: v0.12.7 → v0.12.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.7...v0.12.8) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 284c63f21..dbfdf0012 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ exclude: json/ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: check-ast - id: check-json @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.7" + rev: "v0.12.8" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 7c808cbbf291abd4e202b20819d9fd760c0eff84 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Tue, 12 Aug 2025 07:09:52 -0400 Subject: [PATCH 132/212] Again ignore a license check until we rewrite checkgpl. --- noxfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/noxfile.py b/noxfile.py index 3a306c383..411ac185e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -128,6 +128,7 @@ def license_check(session): "jsonschema", "jsonschema-specifications", "referencing", + "rpds-py", "types-python-dateutil", "--allow-only", From a916d8f8253baa11bacc60f0868f0bab1e42d526 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Mon, 11 Aug 2025 10:45:03 -0500 Subject: [PATCH 133/212] Fix `Validator` protocol init to match runtime The runtime init signature of a validator can be seen with `inspect`: ```pycon >>> import inspect, jsonschema >>> inspect.signature(jsonschema.validators.Draft7Validator.__init__) , _resolver=None) -> None> ``` This aligns the protocol's declared signature with that behavior more exactly with the following changes: `registry` is now keyword-only, not keyword-or-positional, and has a default. `resolver` is added to the declared signature, so users who are using it won't see typing-time discrepancies with the runtime. It is marked as `Any` and commented inline as deprecated, since it's unclear what else we could do to indicate its status. This means that code passing a resolver will continue to type check (previously it would not). `resolver` is the second keyword-or-positional and `format_checker` is the third, meaning that a positional-only caller who passes, for example: `Draft202012Validator(foo, None, bar)` will have `foo` slotted as the schema and `bar` as the `format_checker` This would primarily impact callers with positional-args calling conventions, but is more reflective of what they'll see at runtime. In order to remove `resolver` from the protocol signature, but match the runtime signatures well, some kind of placeholder is needed to indicate `format_checker` as positional-or-keyword. Or else, a large number of overloads for `__init__` could be declared to try to simulate its removal. --- jsonschema/protocols.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/jsonschema/protocols.py b/jsonschema/protocols.py index 0fd993eec..b6288dcc2 100644 --- a/jsonschema/protocols.py +++ b/jsonschema/protocols.py @@ -108,10 +108,11 @@ class Validator(Protocol): def __init__( self, schema: Mapping | bool, - registry: referencing.jsonschema.SchemaRegistry, + resolver: Any = None, # deprecated format_checker: jsonschema.FormatChecker | None = None, - ) -> None: - ... + *, + registry: referencing.jsonschema.SchemaRegistry = ..., + ) -> None: ... @classmethod def check_schema(cls, schema: Mapping | bool) -> None: From bf603d59117f840916709fc87c6625df43d1fe72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 13:28:39 +0000 Subject: [PATCH 134/212] Bump astral-sh/setup-uv from 6.4.3 to 6.5.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.4.3 to 6.5.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/e92bafb6253dcd438e0484186d7669ea7a8ca1cc...d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 6.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72a291dfc..cb5629f9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc + uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc + uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc + uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 71ce97c3b..240a0fbc5 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc + uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 6c25741bff889477680f9b0d1aa967ae35c38f43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 13:44:41 +0000 Subject: [PATCH 135/212] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72a291dfc..940feb700 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: outputs: noxenvs: ${{ steps.noxenvs-matrix.outputs.noxenvs }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: persist-credentials: false - name: Set up uv @@ -75,7 +75,7 @@ jobs: noxenv: "docs(style)" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: persist-credentials: false - name: Install dependencies @@ -119,7 +119,7 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 71ce97c3b..98ac2809c 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false From 64bc2171624ef201bdbf35e47780348ce30935c5 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Mon, 18 Aug 2025 10:56:49 -0500 Subject: [PATCH 136/212] Add a typing test for the Validator protocol The typing tests are a new subdirectory of `jsonschema/tests/` which are checked under a more stringent mypy configuration (`--warn-unused-ignores`) in order to allow certain kinds of negative tests against the declared types. [^1] The first new test confirms that each validator matches the Validator protocol, and furthermore that this is not vacuously true by way of `Any`. The test failed at first, as the return type of `create()` was not annotated, and therefore under the declared types in `jsonschema`, all of the validators were of type `Any`. To resolve, the return type of `create` is now annotated as `type[Validator]`. [^1]: Technically, the new nox configuration checks these files twice, but only the second check, with `--warn-unused-ignores`, is doing all of the necessary work. --- jsonschema/tests/typing/__init__.py | 0 ..._all_concrete_validators_match_protocol.py | 38 +++++++++++++++++++ jsonschema/validators.py | 4 +- noxfile.py | 4 ++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 jsonschema/tests/typing/__init__.py create mode 100644 jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py diff --git a/jsonschema/tests/typing/__init__.py b/jsonschema/tests/typing/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py b/jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py new file mode 100644 index 000000000..63e8bd405 --- /dev/null +++ b/jsonschema/tests/typing/test_all_concrete_validators_match_protocol.py @@ -0,0 +1,38 @@ +""" +This module acts as a test that type checkers will allow each validator +class to be assigned to a variable of type `type[Validator]` + +The assignation is only valid if type checkers recognize each Validator +implementation as a valid implementer of the protocol. +""" +from jsonschema.protocols import Validator +from jsonschema.validators import ( + Draft3Validator, + Draft4Validator, + Draft6Validator, + Draft7Validator, + Draft201909Validator, + Draft202012Validator, +) + +my_validator: type[Validator] + +my_validator = Draft3Validator +my_validator = Draft4Validator +my_validator = Draft6Validator +my_validator = Draft7Validator +my_validator = Draft201909Validator +my_validator = Draft202012Validator + + +# in order to confirm that none of the above were incorrectly typed as 'Any' +# ensure that each of these assignments to a non-validator variable requires an +# ignore +none_var: None + +none_var = Draft3Validator # type: ignore[assignment] +none_var = Draft4Validator # type: ignore[assignment] +none_var = Draft6Validator # type: ignore[assignment] +none_var = Draft7Validator # type: ignore[assignment] +none_var = Draft201909Validator # type: ignore[assignment] +none_var = Draft202012Validator # type: ignore[assignment] diff --git a/jsonschema/validators.py b/jsonschema/validators.py index b8ca3bd45..dbc029fc0 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -147,7 +147,7 @@ def create( applicable_validators: _typing.ApplicableValidators = methodcaller( "items", ), -): +) -> type[Validator]: """ Create a new validator class. @@ -511,7 +511,7 @@ def is_valid(self, instance, _schema=None): Validator.__name__ = Validator.__qualname__ = f"{safe}Validator" Validator = validates(version)(Validator) # type: ignore[misc] - return Validator + return Validator # type: ignore[return-value] def extend( diff --git a/noxfile.py b/noxfile.py index 411ac185e..3765637b8 100644 --- a/noxfile.py +++ b/noxfile.py @@ -6,6 +6,7 @@ ROOT = Path(__file__).parent PACKAGE = ROOT / "jsonschema" +TYPING_TESTS= ROOT / "jsonschema" / "tests" / "typing" BENCHMARKS = PACKAGE / "benchmarks" PYPROJECT = ROOT / "pyproject.toml" CHANGELOG = ROOT / "CHANGELOG.rst" @@ -181,6 +182,9 @@ def typing(session): """ session.install("mypy", "types-requests", ROOT) session.run("mypy", "--config", PYPROJECT, PACKAGE) + session.run( + "mypy", "--config", PYPROJECT, "--warn-unused-ignores", TYPING_TESTS + ) @session(tags=["docs"]) From 1e58409b71a9696b7bf9938ae8a3a48ef95ab29e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 16:02:25 +0000 Subject: [PATCH 137/212] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 3765637b8..05a238459 100644 --- a/noxfile.py +++ b/noxfile.py @@ -183,7 +183,7 @@ def typing(session): session.install("mypy", "types-requests", ROOT) session.run("mypy", "--config", PYPROJECT, PACKAGE) session.run( - "mypy", "--config", PYPROJECT, "--warn-unused-ignores", TYPING_TESTS + "mypy", "--config", PYPROJECT, "--warn-unused-ignores", TYPING_TESTS, ) From 331c38425519b69118d22ebe467ad230fb83a010 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 18 Aug 2025 12:45:28 -0400 Subject: [PATCH 138/212] Add the fix to the changelog. --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0d59e4e95..836fdcdc0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +v4.25.1 +======= + +* Fix an incorrect required argument in the ``Validator`` protocol's type annotations (#1396). + v4.25.0 ======= From 64f7bad007a5caafe38cccd89c60bf61ed71d240 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 18:13:29 +0000 Subject: [PATCH 139/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.8 → v0.12.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.8...v0.12.9) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dbfdf0012..a7af106f7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.8" + rev: "v0.12.9" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 4aab977188f86ec2653d931cc376cf6e31297c1e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 18:10:10 +0000 Subject: [PATCH 140/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.9 → v0.12.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.9...v0.12.10) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a7af106f7..b03f27ec9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.9" + rev: "v0.12.10" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 3aa122930f5346a76a09d326563365b990cad3ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 18:13:40 +0000 Subject: [PATCH 141/212] Bump astral-sh/setup-uv from 6.5.0 to 6.6.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.5.0 to 6.6.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1...4959332f0f014c5280e7eac8b70c90cb574c9f9b) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 6.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f3029955..927d72f7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 + uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 + uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 + uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 4bebbe96c..d4c837beb 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@d9e0f98d3fc6adb07d1e3d37f3043649ddad06a1 + uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From d2e8cf40faf11112c7bc367b2a256f7bf3a29760 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Sep 2025 18:11:47 +0000 Subject: [PATCH 142/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.10 → v0.12.11](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.10...v0.12.11) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b03f27ec9..bacdab7b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.10" + rev: "v0.12.11" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From a24e0d87022c72ef43b1832f1836f815f01ba92a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 09:10:28 +0000 Subject: [PATCH 143/212] Bump softprops/action-gh-release from 2.3.2 to 2.3.3 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.3.2 to 2.3.3. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/72f2c25fcb47643c292f7107632f7a47c1df5cd8...6cbd405e2c4e67a21c47fa9e383d020e4e28b836) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 2.3.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 927d72f7e..336f48ba5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 + uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 with: files: | dist/* From 96c5d042ad825f5f97d27d154858acf8cee763fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 09:10:30 +0000 Subject: [PATCH 144/212] Bump pypa/gh-action-pypi-publish from 1.12.4 to 1.13.0 Bumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.12.4 to 1.13.0. - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/76f52bc884231f62b9a034ebfe128415bbaabdfc...ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-version: 1.13.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 927d72f7e..05e64d039 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -133,7 +133,7 @@ jobs: - name: Publish to PyPI if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 From 55b8fbbcb9c75090942b175f83cdebf8d67627dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 09:11:34 +0000 Subject: [PATCH 145/212] Bump actions/setup-python from 5 to 6 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 927d72f7e..712b6785f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,7 +85,7 @@ jobs: run: brew install enchant if: runner.os == 'macOS' && startsWith(matrix.noxenv, 'docs') - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: | 3.9 From f204f2a471a6e065ba4620760193dbad2dfe60c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 09:11:41 +0000 Subject: [PATCH 146/212] Bump astral-sh/setup-uv from 6.6.0 to 6.6.1 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.6.0 to 6.6.1. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/4959332f0f014c5280e7eac8b70c90cb574c9f9b...557e51de59eb14aaaba2ed9621916900a91d50c6) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 6.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 927d72f7e..9da8e8c5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b + uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b + uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b + uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index d4c837beb..121c14c1a 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@4959332f0f014c5280e7eac8b70c90cb574c9f9b + uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 3d66e88d180a4eba1b3b55f7b8e2143805a1e7e9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 18:17:00 +0000 Subject: [PATCH 147/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.11 → v0.12.12](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.11...v0.12.12) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bacdab7b4..5eae75bc3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.11" + rev: "v0.12.12" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From c3855b9bc9cc7264c3ea4d0eb056720f48eac654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sun, 5 Oct 2025 17:24:24 +0000 Subject: [PATCH 148/212] Fix a style issue raised in CI RUF059 Unpacked variable `error` is never used --- jsonschema/tests/test_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema/tests/test_exceptions.py b/jsonschema/tests/test_exceptions.py index 8d515a998..358b92425 100644 --- a/jsonschema/tests/test_exceptions.py +++ b/jsonschema/tests/test_exceptions.py @@ -321,7 +321,7 @@ def test_boolean_schemas(self): def test_one_error(self): validator = _LATEST_VERSION({"minProperties": 2}) - error, = validator.iter_errors({}) + validator.iter_errors({}) self.assertEqual( exceptions.best_match(validator.iter_errors({})).validator, "minProperties", From 1cab18fef6eab8d5befaa3e3b815561f5967070a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sun, 5 Oct 2025 15:32:25 +0000 Subject: [PATCH 149/212] validators: avoid urllib.request at import-time This change improves jsonschema import time by ~50ms. On my end calling: python -X importtime -c "import jsonschema" * Before: 234ms * After: 173ms --- jsonschema/validators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema/validators.py b/jsonschema/validators.py index dbc029fc0..98ddf6bfb 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -9,7 +9,6 @@ from operator import methodcaller from typing import TYPE_CHECKING from urllib.parse import unquote, urldefrag, urljoin, urlsplit -from urllib.request import urlopen from warnings import warn import contextlib import json @@ -1225,6 +1224,7 @@ def resolve_remote(self, uri): result = requests.get(uri).json() else: # Otherwise, pass off to urllib and assume utf-8 + from urllib.request import urlopen with urlopen(uri) as url: # noqa: S310 result = json.loads(url.read().decode("utf-8")) From a236135cd520a32ed4bf496fef0aa27d048b453f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sun, 5 Oct 2025 16:21:57 +0000 Subject: [PATCH 150/212] Fix test mocking urlopen --- jsonschema/tests/test_validators.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 28cc40273..d419ddf8e 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -2379,11 +2379,9 @@ def fake_urlopen(url): self.assertEqual(url, "http://bar") yield BytesIO(json.dumps(schema).encode("utf8")) - self.addCleanup(setattr, validators, "urlopen", validators.urlopen) - validators.urlopen = fake_urlopen - - with self.resolver.resolving(ref) as resolved: - pass + with mock.patch("urllib.request.urlopen", new=fake_urlopen): # noqa: SIM117 + with self.resolver.resolving(ref) as resolved: + pass self.assertEqual(resolved, 12) def test_it_retrieves_local_refs_via_urlopen(self): From 1f3616b5446267401b4067c5b41fec1999a2d1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gu=C3=B0ni=20M=C3=A1r=20Gilbert?= Date: Sun, 5 Oct 2025 22:24:21 +0000 Subject: [PATCH 151/212] Add benchmark for import time --- jsonschema/benchmarks/import_benchmark.py | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 jsonschema/benchmarks/import_benchmark.py diff --git a/jsonschema/benchmarks/import_benchmark.py b/jsonschema/benchmarks/import_benchmark.py new file mode 100644 index 000000000..59fa921dd --- /dev/null +++ b/jsonschema/benchmarks/import_benchmark.py @@ -0,0 +1,31 @@ +""" +A benchmark which measures the import time of jsonschema +""" + +import subprocess +import sys + + +def import_time(loops): + total_us = 0 + for _ in range(loops): + p = subprocess.run( # noqa: S603 (arguments are static) + [sys.executable, "-X", "importtime", "-c", "import jsonschema"], + stderr=subprocess.PIPE, + stdout=subprocess.DEVNULL, + check=True, + ) + + line = p.stderr.splitlines()[-1] + field = line.split(b"|")[-2].strip() + us = int(field) # microseconds + total_us += us + + # pyperf expects seconds + return total_us / 1_000_000.0 + +if __name__ == "__main__": + from pyperf import Runner + runner = Runner() + + runner.bench_time_func("Import time (cumulative)", import_time) From f7e6f777198e6d95e54b3133a95138f4c03752ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 09:08:34 +0000 Subject: [PATCH 152/212] Bump astral-sh/setup-uv from 6.6.1 to 6.8.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.6.1 to 6.8.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/557e51de59eb14aaaba2ed9621916900a91d50c6...d0cc045d04ccac9d8b7881df0226f9e82c39688e) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 6.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78b03cce7..cdf2ed433 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 121c14c1a..dfb238fe7 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 + uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 20e86d6941eb6ad5ba0b86a1f4bdf00a68ebbaf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Oct 2025 09:09:20 +0000 Subject: [PATCH 153/212] Bump softprops/action-gh-release from 2.3.3 to 2.3.4 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.3.3 to 2.3.4. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/6cbd405e2c4e67a21c47fa9e383d020e4e28b836...62c96d0c4e8a889135c1f3a25910db8dbe0e85f7) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 2.3.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78b03cce7..df7f92e27 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 + uses: softprops/action-gh-release@62c96d0c4e8a889135c1f3a25910db8dbe0e85f7 with: files: | dist/* From 88c8ff206349a38a2b84f5ff765dd504b32aed26 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 6 Oct 2025 07:29:45 -0400 Subject: [PATCH 154/212] Get CI passing again by ignoring the pip CVE. It's not relevant to us, pip isn't a dependency. This fix isn't quite right though as clearly we should run pip-audit in a way where we don't get false positives when its own dependencies (here pip) have vulnerabilities. Running pip-audit on a library (as opposed to an end-user application) isn't the most common use however, so it doesn't appear there's a straightforward way to do this unless we come up with one ourselves. --- noxfile.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 05a238459..de93c7c31 100644 --- a/noxfile.py +++ b/noxfile.py @@ -104,7 +104,14 @@ def audit(session, installable): Audit dependencies for vulnerabilities. """ session.install("pip-audit", installable) - session.run("python", "-m", "pip_audit") + session.run( + "python", + "-m", + "pip_audit", + "--ignore-vuln", + "GHSA-4xh5-x5gv-qwph", # pip vuln, not relevant, but we need to figure + # out how to properly run pip-audit + ) @session() From 35b5889d493e52323b02fb85da71c11681d0b1db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 09:22:59 +0000 Subject: [PATCH 155/212] Bump softprops/action-gh-release from 2.3.4 to 2.4.1 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.3.4 to 2.4.1. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/62c96d0c4e8a889135c1f3a25910db8dbe0e85f7...6da8fa9354ddfdc4aeace5fc48d7f679b5214090) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 2.4.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8544aab37..f6c966dac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: softprops/action-gh-release@62c96d0c4e8a889135c1f3a25910db8dbe0e85f7 + uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 with: files: | dist/* From dbfe96711a447cd5d03e27f4e75c0d1d0ed9b0ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 09:23:15 +0000 Subject: [PATCH 156/212] Bump github/codeql-action from 3 to 4 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/zizmor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index dfb238fe7..6f74530c5 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -29,7 +29,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v4 with: sarif_file: results.sarif category: zizmor From f32e4828b4cc9c009f6c9bf7eacd2f43bffc9c92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 09:23:25 +0000 Subject: [PATCH 157/212] Bump astral-sh/setup-uv from 6.8.0 to 7.1.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 6.8.0 to 7.1.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/d0cc045d04ccac9d8b7881df0226f9e82c39688e...3259c6206f993105e3a61b142c2d97bf4b9ef83d) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8544aab37..00bf341f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e + uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e + uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e + uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index dfb238fe7..ab9f144c4 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e + uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 9df882ae9a37593399219d38fce531a1c8c9f2f4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 18:23:33 +0000 Subject: [PATCH 158/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.12 → v0.14.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.12...v0.14.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5eae75bc3..6ebc1baa9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.12.12" + rev: "v0.14.0" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 082a04eb2c8db8ed63723d4a4b8f95f9a6ce5392 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Mon, 13 Oct 2025 18:17:34 -0400 Subject: [PATCH 159/212] idna moved to PEP 639 as well (and is MIT). --- noxfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/noxfile.py b/noxfile.py index de93c7c31..dbc7abf1e 100644 --- a/noxfile.py +++ b/noxfile.py @@ -133,6 +133,7 @@ def license_check(session): # because pip-licenses doesn't yet support PEP 639 :/ "attrs", + "idna", "jsonschema", "jsonschema-specifications", "referencing", From 6be2cfd10870eece5f0be31aec6a2939845e9f48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 09:59:08 +0000 Subject: [PATCH 160/212] Bump astral-sh/setup-uv from 7.1.0 to 7.1.1 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.1.0 to 7.1.1. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/3259c6206f993105e3a61b142c2d97bf4b9ef83d...2ddd2b9cb38ad8efd50337e8ab201519a34c9f24) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.1.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77ca61801..6303417e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d + uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -100,7 +100,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d + uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 with: enable-cache: true @@ -124,7 +124,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d + uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 with: enable-cache: true diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index c9f0f4aad..84542e0f2 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d + uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 2b5659fc57ec385e4a42b46638fd36774d2cec63 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 20:23:51 +0000 Subject: [PATCH 161/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.0 → v0.14.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.0...v0.14.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ebc1baa9..19a98ef48 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.0" + rev: "v0.14.1" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From cebe4c7a3719f06473125ae97802e1de0aa810bd Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 24 Oct 2025 10:18:30 -0400 Subject: [PATCH 162/212] Remove running pip-audit from CI. pip has had a recent CVE, and as a library (and not an app) it is difficult to run pip-audit in a way that has value but is segregated from pip-audit's own deps such that we don't encounter this kind of false positive. Downstream applications should themselves run pip-audit as it is more suited for being run by applications rather than libraries. --- noxfile.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/noxfile.py b/noxfile.py index dbc7abf1e..f3cd34fd3 100644 --- a/noxfile.py +++ b/noxfile.py @@ -97,23 +97,6 @@ def tests(session, installable): session.run("virtue", *session.posargs, PACKAGE, env=env) -@session() -@nox.parametrize("installable", INSTALLABLE) -def audit(session, installable): - """ - Audit dependencies for vulnerabilities. - """ - session.install("pip-audit", installable) - session.run( - "python", - "-m", - "pip_audit", - "--ignore-vuln", - "GHSA-4xh5-x5gv-qwph", # pip vuln, not relevant, but we need to figure - # out how to properly run pip-audit - ) - - @session() def license_check(session): """ From 7a749329061d4e88da6b07ee19b5a674a9e97ba8 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 24 Oct 2025 10:19:13 -0400 Subject: [PATCH 163/212] Drop support for 3.9, which is EOL, add 3.14 to CI. --- .github/workflows/ci.yml | 7 +- jsonschema/_format.py | 2 +- jsonschema/_types.py | 4 +- jsonschema/_typing.py | 6 +- noxfile.py | 2 +- pyproject.toml | 5 +- uv.lock | 586 +++++++++++++++++++++++++++------------ 7 files changed, 427 insertions(+), 185 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 77ca61801..487735de6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,10 +45,10 @@ jobs: posargs: [""] include: - os: ubuntu-latest - noxenv: "tests-3.13(format)" + noxenv: "tests-3.14(format)" posargs: coverage github - os: ubuntu-latest - noxenv: "tests-3.13(no-extras)" + noxenv: "tests-3.14(no-extras)" posargs: coverage github exclude: - os: macos-latest @@ -88,11 +88,12 @@ jobs: uses: actions/setup-python@v6 with: python-version: | - 3.9 3.10 3.11 3.12 3.13 + 3.14 + 3.14t pypy3.11 allow-prereleases: true - name: Enable UTF-8 on Windows diff --git a/jsonschema/_format.py b/jsonschema/_format.py index 6fc7a01e1..5efda86e6 100644 --- a/jsonschema/_format.py +++ b/jsonschema/_format.py @@ -13,7 +13,7 @@ _FormatCheckCallable = typing.Callable[[object], bool] #: A format checker callable. _F = typing.TypeVar("_F", bound=_FormatCheckCallable) -_RaisesType = typing.Union[type[Exception], tuple[type[Exception], ...]] +_RaisesType = type[Exception] | tuple[type[Exception], ...] _RE_DATE = re.compile(r"^\d{4}-\d{2}-\d{2}$", re.ASCII) diff --git a/jsonschema/_types.py b/jsonschema/_types.py index d3ce9d667..fcfe3f09c 100644 --- a/jsonschema/_types.py +++ b/jsonschema/_types.py @@ -9,8 +9,8 @@ from jsonschema.exceptions import UndefinedTypeCheck if TYPE_CHECKING: - from collections.abc import Mapping - from typing import Any, Callable + from collections.abc import Callable, Mapping + from typing import Any # unfortunately, the type of HashTrieMap is generic, and if used as an attrs diff --git a/jsonschema/_typing.py b/jsonschema/_typing.py index 1d091d70c..f8dda63a7 100644 --- a/jsonschema/_typing.py +++ b/jsonschema/_typing.py @@ -1,8 +1,8 @@ """ Some (initially private) typing helpers for jsonschema's types. """ -from collections.abc import Iterable -from typing import Any, Callable, Protocol, Union +from collections.abc import Callable, Iterable +from typing import Any, Protocol import referencing.jsonschema @@ -20,7 +20,7 @@ def __call__( ... -id_of = Callable[[referencing.jsonschema.Schema], Union[str, None]] +id_of = Callable[[referencing.jsonschema.Schema], str | None] ApplicableValidators = Callable[ diff --git a/noxfile.py b/noxfile.py index f3cd34fd3..dad6cd562 100644 --- a/noxfile.py +++ b/noxfile.py @@ -37,7 +37,7 @@ "The Unlicense (Unlicense)", ] -SUPPORTED = ["3.9", "3.10", "pypy3.11", "3.11", "3.12", "3.13"] +SUPPORTED = ["3.10", "pypy3.11", "3.11", "3.12", "3.13", "3.14t", "3.14"] LATEST_STABLE = SUPPORTED[-1] nox.options.default_venv_backend = "uv|virtualenv" diff --git a/pyproject.toml b/pyproject.toml index ad98e9f50..213f89bcd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ source = "vcs" [project] name = "jsonschema" description = "An implementation of JSON Schema validation for Python" -requires-python = ">=3.9" +requires-python = ">=3.10" license = "MIT" license-files = ["COPYING"] keywords = [ @@ -26,11 +26,11 @@ classifiers = [ "Intended Audience :: Developers", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: File Formats :: JSON", @@ -193,7 +193,6 @@ ignore = [ "SLF001", # Private usage within this package itself is fine "TD", # These TODO style rules are also silly "TRY003", # Some exception classes are essentially intended for free-form - "UP007", # We support 3.9 ] [tool.ruff.lint.flake8-pytest-style] diff --git a/uv.lock b/uv.lock index dae43e742..e6271a86c 100644 --- a/uv.lock +++ b/uv.lock @@ -1,27 +1,66 @@ version = 1 -revision = 2 -requires-python = ">=3.9" +revision = 3 +requires-python = ">=3.10" [[package]] name = "arrow" -version = "1.3.0" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, - { name = "types-python-dateutil" }, + { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931, upload-time = "2025-10-18T17:46:46.761Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" }, ] [[package]] name = "attrs" -version = "25.3.0" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "automat" +version = "25.4.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/0f/d40bbe294bbf004d436a8bcbcfaadca8b5140d39ad0ad3d73d1a8ba15f14/automat-25.4.16.tar.gz", hash = "sha256:0017591a5477066e90d26b0e696ddc143baafd87b588cfac8100bc6be9634de0", size = 129977, upload-time = "2025-04-16T20:12:16.002Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/ff/1175b0b7371e46244032d43a56862d0af455823b5280a50c63d99cc50f18/automat-25.4.16-py3-none-any.whl", hash = "sha256:04e9bce696a8d5671ee698005af6e5a9fa15354140a87f4870744604dcdd3ba1", size = 42842, upload-time = "2025-04-16T20:12:14.447Z" }, +] + +[[package]] +name = "click" +version = "8.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "constantly" +version = "23.10.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/6f/cb2a94494ff74aa9528a36c5b1422756330a75a8367bf20bd63171fc324d/constantly-23.10.4.tar.gz", hash = "sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd", size = 13300, upload-time = "2023-10-28T23:18:24.316Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/40/c199d095151addf69efdb4b9ca3a4f20f70e20508d6222bffb9b76f58573/constantly-23.10.4-py3-none-any.whl", hash = "sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9", size = 13547, upload-time = "2023-10-28T23:18:23.038Z" }, ] [[package]] @@ -33,13 +72,38 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" }, ] +[[package]] +name = "hyperlink" +version = "21.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/51/1947bd81d75af87e3bb9e34593a4cf118115a8feb451ce7a69044ef1412e/hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b", size = 140743, upload-time = "2021-01-08T05:51:20.972Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/aa/8caf6a0a3e62863cbb9dab27135660acba46903b703e224f14f447e57934/hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4", size = 74638, upload-time = "2021-01-08T05:51:22.906Z" }, +] + [[package]] name = "idna" -version = "3.10" +version = "3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "incremental" +version = "24.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/87/156b374ff6578062965afe30cc57627d35234369b3336cf244b240c8d8e6/incremental-24.7.2.tar.gz", hash = "sha256:fb4f1d47ee60efe87d4f6f0ebb5f70b9760db2b2574c59c8e8912be4ebd464c9", size = 28157, upload-time = "2024-07-29T20:03:55.441Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/38/221e5b2ae676a3938c2c1919131410c342b6efc2baffeda395dd66eeca8f/incremental-24.7.2-py3-none-any.whl", hash = "sha256:8cb2c3431530bec48ad70513931a760f446ad6c25e8333ca5d95e24b0ed7b8fe", size = 20516, upload-time = "2024-07-29T20:03:53.677Z" }, ] [[package]] @@ -54,6 +118,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, ] +[[package]] +name = "jsonpath-ng" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ply" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/86/08646239a313f895186ff0a4573452038eed8c86f54380b3ebac34d32fb2/jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c", size = 37838, upload-time = "2024-10-11T15:41:42.404Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/5a/73ecb3d82f8615f32ccdadeb9356726d6cae3a4bbc840b437ceb95708063/jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6", size = 30105, upload-time = "2024-11-20T17:58:30.418Z" }, +] + [[package]] name = "jsonpointer" version = "3.0.0" @@ -91,10 +167,17 @@ format-nongpl = [ { name = "jsonpointer" }, { name = "rfc3339-validator" }, { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, { name = "uri-template" }, { name = "webcolors" }, ] +[package.dev-dependencies] +test = [ + { name = "jsonpath-ng" }, + { name = "virtue" }, +] + [package.metadata] requires-dist = [ { name = "attrs", specifier = ">=22.2.0" }, @@ -112,6 +195,7 @@ requires-dist = [ { name = "rfc3339-validator", marker = "extra == 'format-nongpl'" }, { name = "rfc3986-validator", marker = "extra == 'format-nongpl'", specifier = ">0.1.0" }, { name = "rfc3987", marker = "extra == 'format'" }, + { name = "rfc3987-syntax", marker = "extra == 'format-nongpl'", specifier = ">=1.1.0" }, { name = "rpds-py", specifier = ">=0.7.1" }, { name = "uri-template", marker = "extra == 'format'" }, { name = "uri-template", marker = "extra == 'format-nongpl'" }, @@ -120,16 +204,67 @@ requires-dist = [ ] provides-extras = ["format", "format-nongpl"] +[package.metadata.requires-dev] +test = [ + { name = "jsonpath-ng" }, + { name = "virtue" }, +] + [[package]] name = "jsonschema-specifications" -version = "2025.4.1" +version = "2025.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "lark" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/37/a13baf0135f348af608c667633cbe5d13aa2c5c15a56ae9ad3e6cba45ae3/lark-1.3.0.tar.gz", hash = "sha256:9a3839d0ca5e1faf7cfa3460e420e859b66bcbde05b634e73c369c8244c5fa48", size = 259551, upload-time = "2025-09-22T13:45:05.072Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/3e/1c6b43277de64fc3c0333b0e72ab7b52ddaaea205210d60d9b9f83c3d0c7/lark-1.3.0-py3-none-any.whl", hash = "sha256:80661f261fb2584a9828a097a2432efd575af27d20be0fd35d17f0fe37253831", size = 113002, upload-time = "2025-09-22T13:45:03.747Z" }, +] + +[[package]] +name = "ply" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/69/882ee5c9d017149285cab114ebeab373308ef0f874fcdac9beb90e0ac4da/ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3", size = 159130, upload-time = "2018-02-15T19:01:31.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce", size = 49567, upload-time = "2018-02-15T19:01:27.172Z" }, +] + +[[package]] +name = "pyrsistent" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/3a/5031723c09068e9c8c2f0bc25c3a9245f2b1d1aea8396c787a408f2b95ca/pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4", size = 103642, upload-time = "2023-10-25T21:06:56.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/19/c343b14061907b629b765444b6436b160e2bd4184d17d4804bbe6381f6be/pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce", size = 83416, upload-time = "2023-10-25T21:06:04.579Z" }, + { url = "https://files.pythonhosted.org/packages/9f/4f/8342079ea331031ef9ed57edd312a9ad283bcc8adfaf268931ae356a09a6/pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f", size = 118021, upload-time = "2023-10-25T21:06:06.953Z" }, + { url = "https://files.pythonhosted.org/packages/d7/b7/64a125c488243965b7c5118352e47c6f89df95b4ac306d31cee409153d57/pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34", size = 117747, upload-time = "2023-10-25T21:06:08.5Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a5/43c67bd5f80df9e7583042398d12113263ec57f27c0607abe9d78395d18f/pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b", size = 114524, upload-time = "2023-10-25T21:06:10.728Z" }, + { url = "https://files.pythonhosted.org/packages/8a/98/b382a87e89ca839106d874f7bf78d226b3eedb26735eb6f751f1a3375f21/pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f", size = 60780, upload-time = "2023-10-25T21:06:12.14Z" }, + { url = "https://files.pythonhosted.org/packages/37/8a/23e2193f7adea6901262e3cf39c7fe18ac0c446176c0ff0e19aeb2e9681e/pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7", size = 63310, upload-time = "2023-10-25T21:06:13.598Z" }, + { url = "https://files.pythonhosted.org/packages/df/63/7544dc7d0953294882a5c587fb1b10a26e0c23d9b92281a14c2514bac1f7/pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958", size = 83481, upload-time = "2023-10-25T21:06:15.238Z" }, + { url = "https://files.pythonhosted.org/packages/ae/a0/49249bc14d71b1bf2ffe89703acfa86f2017c25cfdabcaea532b8c8a5810/pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8", size = 120222, upload-time = "2023-10-25T21:06:17.144Z" }, + { url = "https://files.pythonhosted.org/packages/a1/94/9808e8c9271424120289b9028a657da336ad7e43da0647f62e4f6011d19b/pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a", size = 120002, upload-time = "2023-10-25T21:06:18.727Z" }, + { url = "https://files.pythonhosted.org/packages/3f/f6/9ecfb78b2fc8e2540546db0fe19df1fae0f56664a5958c21ff8861b0f8da/pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224", size = 116850, upload-time = "2023-10-25T21:06:20.424Z" }, + { url = "https://files.pythonhosted.org/packages/83/c8/e6d28bc27a0719f8eaae660357df9757d6e9ca9be2691595721de9e8adfc/pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656", size = 60775, upload-time = "2023-10-25T21:06:21.815Z" }, + { url = "https://files.pythonhosted.org/packages/98/87/c6ef52ff30388f357922d08de012abdd3dc61e09311d88967bdae23ab657/pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee", size = 63306, upload-time = "2023-10-25T21:06:22.874Z" }, + { url = "https://files.pythonhosted.org/packages/15/ee/ff2ed52032ac1ce2e7ba19e79bd5b05d152ebfb77956cf08fcd6e8d760ea/pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e", size = 83537, upload-time = "2023-10-25T21:06:24.17Z" }, + { url = "https://files.pythonhosted.org/packages/80/f1/338d0050b24c3132bcfc79b68c3a5f54bce3d213ecef74d37e988b971d8a/pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e", size = 122615, upload-time = "2023-10-25T21:06:25.815Z" }, + { url = "https://files.pythonhosted.org/packages/07/3a/e56d6431b713518094fae6ff833a04a6f49ad0fbe25fb7c0dc7408e19d20/pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3", size = 122335, upload-time = "2023-10-25T21:06:28.631Z" }, + { url = "https://files.pythonhosted.org/packages/4a/bb/5f40a4d5e985a43b43f607250e766cdec28904682c3505eb0bd343a4b7db/pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d", size = 118510, upload-time = "2023-10-25T21:06:30.718Z" }, + { url = "https://files.pythonhosted.org/packages/1c/13/e6a22f40f5800af116c02c28e29f15c06aa41cb2036f6a64ab124647f28b/pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174", size = 60865, upload-time = "2023-10-25T21:06:32.742Z" }, + { url = "https://files.pythonhosted.org/packages/75/ef/2fa3b55023ec07c22682c957808f9a41836da4cd006b5f55ec76bf0fbfa6/pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d", size = 63239, upload-time = "2023-10-25T21:06:34.035Z" }, + { url = "https://files.pythonhosted.org/packages/23/88/0acd180010aaed4987c85700b7cc17f9505f3edb4e5873e4dc67f613e338/pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b", size = 58106, upload-time = "2023-10-25T21:06:54.387Z" }, ] [[package]] @@ -146,16 +281,16 @@ wheels = [ [[package]] name = "referencing" -version = "0.36.2" +version = "0.37.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "rpds-py" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, ] [[package]] @@ -188,155 +323,147 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/65/d4/f7407c3d15d5ac779c3dd34fbbc6ea2090f77bd7dd12f207ccf881551208/rfc3987-1.3.8-py2.py3-none-any.whl", hash = "sha256:10702b1e51e5658843460b189b185c0366d2cf4cff716f13111b0ea9fd2dce53", size = 13377, upload-time = "2018-07-29T17:23:45.313Z" }, ] +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, +] + [[package]] name = "rpds-py" -version = "0.26.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a5/aa/4456d84bbb54adc6a916fb10c9b374f78ac840337644e4a5eda229c81275/rpds_py-0.26.0.tar.gz", hash = "sha256:20dae58a859b0906f0685642e591056f1e787f3a8b39c8e8749a45dc7d26bdb0", size = 27385, upload-time = "2025-07-01T15:57:13.958Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/31/1459645f036c3dfeacef89e8e5825e430c77dde8489f3b99eaafcd4a60f5/rpds_py-0.26.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4c70c70f9169692b36307a95f3d8c0a9fcd79f7b4a383aad5eaa0e9718b79b37", size = 372466, upload-time = "2025-07-01T15:53:40.55Z" }, - { url = "https://files.pythonhosted.org/packages/dd/ff/3d0727f35836cc8773d3eeb9a46c40cc405854e36a8d2e951f3a8391c976/rpds_py-0.26.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:777c62479d12395bfb932944e61e915741e364c843afc3196b694db3d669fcd0", size = 357825, upload-time = "2025-07-01T15:53:42.247Z" }, - { url = "https://files.pythonhosted.org/packages/bf/ce/badc5e06120a54099ae287fa96d82cbb650a5f85cf247ffe19c7b157fd1f/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec671691e72dff75817386aa02d81e708b5a7ec0dec6669ec05213ff6b77e1bd", size = 381530, upload-time = "2025-07-01T15:53:43.585Z" }, - { url = "https://files.pythonhosted.org/packages/1e/a5/fa5d96a66c95d06c62d7a30707b6a4cfec696ab8ae280ee7be14e961e118/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a1cb5d6ce81379401bbb7f6dbe3d56de537fb8235979843f0d53bc2e9815a79", size = 396933, upload-time = "2025-07-01T15:53:45.78Z" }, - { url = "https://files.pythonhosted.org/packages/00/a7/7049d66750f18605c591a9db47d4a059e112a0c9ff8de8daf8fa0f446bba/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f789e32fa1fb6a7bf890e0124e7b42d1e60d28ebff57fe806719abb75f0e9a3", size = 513973, upload-time = "2025-07-01T15:53:47.085Z" }, - { url = "https://files.pythonhosted.org/packages/0e/f1/528d02c7d6b29d29fac8fd784b354d3571cc2153f33f842599ef0cf20dd2/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c55b0a669976cf258afd718de3d9ad1b7d1fe0a91cd1ab36f38b03d4d4aeaaf", size = 402293, upload-time = "2025-07-01T15:53:48.117Z" }, - { url = "https://files.pythonhosted.org/packages/15/93/fde36cd6e4685df2cd08508f6c45a841e82f5bb98c8d5ecf05649522acb5/rpds_py-0.26.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70d9ec912802ecfd6cd390dadb34a9578b04f9bcb8e863d0a7598ba5e9e7ccc", size = 383787, upload-time = "2025-07-01T15:53:50.874Z" }, - { url = "https://files.pythonhosted.org/packages/69/f2/5007553aaba1dcae5d663143683c3dfd03d9395289f495f0aebc93e90f24/rpds_py-0.26.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3021933c2cb7def39d927b9862292e0f4c75a13d7de70eb0ab06efed4c508c19", size = 416312, upload-time = "2025-07-01T15:53:52.046Z" }, - { url = "https://files.pythonhosted.org/packages/8f/a7/ce52c75c1e624a79e48a69e611f1c08844564e44c85db2b6f711d76d10ce/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a7898b6ca3b7d6659e55cdac825a2e58c638cbf335cde41f4619e290dd0ad11", size = 558403, upload-time = "2025-07-01T15:53:53.192Z" }, - { url = "https://files.pythonhosted.org/packages/79/d5/e119db99341cc75b538bf4cb80504129fa22ce216672fb2c28e4a101f4d9/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:12bff2ad9447188377f1b2794772f91fe68bb4bbfa5a39d7941fbebdbf8c500f", size = 588323, upload-time = "2025-07-01T15:53:54.336Z" }, - { url = "https://files.pythonhosted.org/packages/93/94/d28272a0b02f5fe24c78c20e13bbcb95f03dc1451b68e7830ca040c60bd6/rpds_py-0.26.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:191aa858f7d4902e975d4cf2f2d9243816c91e9605070aeb09c0a800d187e323", size = 554541, upload-time = "2025-07-01T15:53:55.469Z" }, - { url = "https://files.pythonhosted.org/packages/93/e0/8c41166602f1b791da892d976057eba30685486d2e2c061ce234679c922b/rpds_py-0.26.0-cp310-cp310-win32.whl", hash = "sha256:b37a04d9f52cb76b6b78f35109b513f6519efb481d8ca4c321f6a3b9580b3f45", size = 220442, upload-time = "2025-07-01T15:53:56.524Z" }, - { url = "https://files.pythonhosted.org/packages/87/f0/509736bb752a7ab50fb0270c2a4134d671a7b3038030837e5536c3de0e0b/rpds_py-0.26.0-cp310-cp310-win_amd64.whl", hash = "sha256:38721d4c9edd3eb6670437d8d5e2070063f305bfa2d5aa4278c51cedcd508a84", size = 231314, upload-time = "2025-07-01T15:53:57.842Z" }, - { url = "https://files.pythonhosted.org/packages/09/4c/4ee8f7e512030ff79fda1df3243c88d70fc874634e2dbe5df13ba4210078/rpds_py-0.26.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:9e8cb77286025bdb21be2941d64ac6ca016130bfdcd228739e8ab137eb4406ed", size = 372610, upload-time = "2025-07-01T15:53:58.844Z" }, - { url = "https://files.pythonhosted.org/packages/fa/9d/3dc16be00f14fc1f03c71b1d67c8df98263ab2710a2fbd65a6193214a527/rpds_py-0.26.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e09330b21d98adc8ccb2dbb9fc6cb434e8908d4c119aeaa772cb1caab5440a0", size = 358032, upload-time = "2025-07-01T15:53:59.985Z" }, - { url = "https://files.pythonhosted.org/packages/e7/5a/7f1bf8f045da2866324a08ae80af63e64e7bfaf83bd31f865a7b91a58601/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c9c1b92b774b2e68d11193dc39620d62fd8ab33f0a3c77ecdabe19c179cdbc1", size = 381525, upload-time = "2025-07-01T15:54:01.162Z" }, - { url = "https://files.pythonhosted.org/packages/45/8a/04479398c755a066ace10e3d158866beb600867cacae194c50ffa783abd0/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:824e6d3503ab990d7090768e4dfd9e840837bae057f212ff9f4f05ec6d1975e7", size = 397089, upload-time = "2025-07-01T15:54:02.319Z" }, - { url = "https://files.pythonhosted.org/packages/72/88/9203f47268db488a1b6d469d69c12201ede776bb728b9d9f29dbfd7df406/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ad7fd2258228bf288f2331f0a6148ad0186b2e3643055ed0db30990e59817a6", size = 514255, upload-time = "2025-07-01T15:54:03.38Z" }, - { url = "https://files.pythonhosted.org/packages/f5/b4/01ce5d1e853ddf81fbbd4311ab1eff0b3cf162d559288d10fd127e2588b5/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dc23bbb3e06ec1ea72d515fb572c1fea59695aefbffb106501138762e1e915e", size = 402283, upload-time = "2025-07-01T15:54:04.923Z" }, - { url = "https://files.pythonhosted.org/packages/34/a2/004c99936997bfc644d590a9defd9e9c93f8286568f9c16cdaf3e14429a7/rpds_py-0.26.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d80bf832ac7b1920ee29a426cdca335f96a2b5caa839811803e999b41ba9030d", size = 383881, upload-time = "2025-07-01T15:54:06.482Z" }, - { url = "https://files.pythonhosted.org/packages/05/1b/ef5fba4a8f81ce04c427bfd96223f92f05e6cd72291ce9d7523db3b03a6c/rpds_py-0.26.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0919f38f5542c0a87e7b4afcafab6fd2c15386632d249e9a087498571250abe3", size = 415822, upload-time = "2025-07-01T15:54:07.605Z" }, - { url = "https://files.pythonhosted.org/packages/16/80/5c54195aec456b292f7bd8aa61741c8232964063fd8a75fdde9c1e982328/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d422b945683e409000c888e384546dbab9009bb92f7c0b456e217988cf316107", size = 558347, upload-time = "2025-07-01T15:54:08.591Z" }, - { url = "https://files.pythonhosted.org/packages/f2/1c/1845c1b1fd6d827187c43afe1841d91678d7241cbdb5420a4c6de180a538/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77a7711fa562ba2da1aa757e11024ad6d93bad6ad7ede5afb9af144623e5f76a", size = 587956, upload-time = "2025-07-01T15:54:09.963Z" }, - { url = "https://files.pythonhosted.org/packages/2e/ff/9e979329dd131aa73a438c077252ddabd7df6d1a7ad7b9aacf6261f10faa/rpds_py-0.26.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238e8c8610cb7c29460e37184f6799547f7e09e6a9bdbdab4e8edb90986a2318", size = 554363, upload-time = "2025-07-01T15:54:11.073Z" }, - { url = "https://files.pythonhosted.org/packages/00/8b/d78cfe034b71ffbe72873a136e71acc7a831a03e37771cfe59f33f6de8a2/rpds_py-0.26.0-cp311-cp311-win32.whl", hash = "sha256:893b022bfbdf26d7bedb083efeea624e8550ca6eb98bf7fea30211ce95b9201a", size = 220123, upload-time = "2025-07-01T15:54:12.382Z" }, - { url = "https://files.pythonhosted.org/packages/94/c1/3c8c94c7dd3905dbfde768381ce98778500a80db9924731d87ddcdb117e9/rpds_py-0.26.0-cp311-cp311-win_amd64.whl", hash = "sha256:87a5531de9f71aceb8af041d72fc4cab4943648d91875ed56d2e629bef6d4c03", size = 231732, upload-time = "2025-07-01T15:54:13.434Z" }, - { url = "https://files.pythonhosted.org/packages/67/93/e936fbed1b734eabf36ccb5d93c6a2e9246fbb13c1da011624b7286fae3e/rpds_py-0.26.0-cp311-cp311-win_arm64.whl", hash = "sha256:de2713f48c1ad57f89ac25b3cb7daed2156d8e822cf0eca9b96a6f990718cc41", size = 221917, upload-time = "2025-07-01T15:54:14.559Z" }, - { url = "https://files.pythonhosted.org/packages/ea/86/90eb87c6f87085868bd077c7a9938006eb1ce19ed4d06944a90d3560fce2/rpds_py-0.26.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:894514d47e012e794f1350f076c427d2347ebf82f9b958d554d12819849a369d", size = 363933, upload-time = "2025-07-01T15:54:15.734Z" }, - { url = "https://files.pythonhosted.org/packages/63/78/4469f24d34636242c924626082b9586f064ada0b5dbb1e9d096ee7a8e0c6/rpds_py-0.26.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc921b96fa95a097add244da36a1d9e4f3039160d1d30f1b35837bf108c21136", size = 350447, upload-time = "2025-07-01T15:54:16.922Z" }, - { url = "https://files.pythonhosted.org/packages/ad/91/c448ed45efdfdade82348d5e7995e15612754826ea640afc20915119734f/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e1157659470aa42a75448b6e943c895be8c70531c43cb78b9ba990778955582", size = 384711, upload-time = "2025-07-01T15:54:18.101Z" }, - { url = "https://files.pythonhosted.org/packages/ec/43/e5c86fef4be7f49828bdd4ecc8931f0287b1152c0bb0163049b3218740e7/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:521ccf56f45bb3a791182dc6b88ae5f8fa079dd705ee42138c76deb1238e554e", size = 400865, upload-time = "2025-07-01T15:54:19.295Z" }, - { url = "https://files.pythonhosted.org/packages/55/34/e00f726a4d44f22d5c5fe2e5ddd3ac3d7fd3f74a175607781fbdd06fe375/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9def736773fd56b305c0eef698be5192c77bfa30d55a0e5885f80126c4831a15", size = 517763, upload-time = "2025-07-01T15:54:20.858Z" }, - { url = "https://files.pythonhosted.org/packages/52/1c/52dc20c31b147af724b16104500fba13e60123ea0334beba7b40e33354b4/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdad4ea3b4513b475e027be79e5a0ceac8ee1c113a1a11e5edc3c30c29f964d8", size = 406651, upload-time = "2025-07-01T15:54:22.508Z" }, - { url = "https://files.pythonhosted.org/packages/2e/77/87d7bfabfc4e821caa35481a2ff6ae0b73e6a391bb6b343db2c91c2b9844/rpds_py-0.26.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82b165b07f416bdccf5c84546a484cc8f15137ca38325403864bfdf2b5b72f6a", size = 386079, upload-time = "2025-07-01T15:54:23.987Z" }, - { url = "https://files.pythonhosted.org/packages/e3/d4/7f2200c2d3ee145b65b3cddc4310d51f7da6a26634f3ac87125fd789152a/rpds_py-0.26.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d04cab0a54b9dba4d278fe955a1390da3cf71f57feb78ddc7cb67cbe0bd30323", size = 421379, upload-time = "2025-07-01T15:54:25.073Z" }, - { url = "https://files.pythonhosted.org/packages/ae/13/9fdd428b9c820869924ab62236b8688b122baa22d23efdd1c566938a39ba/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:79061ba1a11b6a12743a2b0f72a46aa2758613d454aa6ba4f5a265cc48850158", size = 562033, upload-time = "2025-07-01T15:54:26.225Z" }, - { url = "https://files.pythonhosted.org/packages/f3/e1/b69686c3bcbe775abac3a4c1c30a164a2076d28df7926041f6c0eb5e8d28/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f405c93675d8d4c5ac87364bb38d06c988e11028a64b52a47158a355079661f3", size = 591639, upload-time = "2025-07-01T15:54:27.424Z" }, - { url = "https://files.pythonhosted.org/packages/5c/c9/1e3d8c8863c84a90197ac577bbc3d796a92502124c27092413426f670990/rpds_py-0.26.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dafd4c44b74aa4bed4b250f1aed165b8ef5de743bcca3b88fc9619b6087093d2", size = 557105, upload-time = "2025-07-01T15:54:29.93Z" }, - { url = "https://files.pythonhosted.org/packages/9f/c5/90c569649057622959f6dcc40f7b516539608a414dfd54b8d77e3b201ac0/rpds_py-0.26.0-cp312-cp312-win32.whl", hash = "sha256:3da5852aad63fa0c6f836f3359647870e21ea96cf433eb393ffa45263a170d44", size = 223272, upload-time = "2025-07-01T15:54:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/7d/16/19f5d9f2a556cfed454eebe4d354c38d51c20f3db69e7b4ce6cff904905d/rpds_py-0.26.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf47cfdabc2194a669dcf7a8dbba62e37a04c5041d2125fae0233b720da6f05c", size = 234995, upload-time = "2025-07-01T15:54:32.195Z" }, - { url = "https://files.pythonhosted.org/packages/83/f0/7935e40b529c0e752dfaa7880224771b51175fce08b41ab4a92eb2fbdc7f/rpds_py-0.26.0-cp312-cp312-win_arm64.whl", hash = "sha256:20ab1ae4fa534f73647aad289003f1104092890849e0266271351922ed5574f8", size = 223198, upload-time = "2025-07-01T15:54:33.271Z" }, - { url = "https://files.pythonhosted.org/packages/6a/67/bb62d0109493b12b1c6ab00de7a5566aa84c0e44217c2d94bee1bd370da9/rpds_py-0.26.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:696764a5be111b036256c0b18cd29783fab22154690fc698062fc1b0084b511d", size = 363917, upload-time = "2025-07-01T15:54:34.755Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f3/34e6ae1925a5706c0f002a8d2d7f172373b855768149796af87bd65dcdb9/rpds_py-0.26.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1e6c15d2080a63aaed876e228efe4f814bc7889c63b1e112ad46fdc8b368b9e1", size = 350073, upload-time = "2025-07-01T15:54:36.292Z" }, - { url = "https://files.pythonhosted.org/packages/75/83/1953a9d4f4e4de7fd0533733e041c28135f3c21485faaef56a8aadbd96b5/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:390e3170babf42462739a93321e657444f0862c6d722a291accc46f9d21ed04e", size = 384214, upload-time = "2025-07-01T15:54:37.469Z" }, - { url = "https://files.pythonhosted.org/packages/48/0e/983ed1b792b3322ea1d065e67f4b230f3b96025f5ce3878cc40af09b7533/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7da84c2c74c0f5bc97d853d9e17bb83e2dcafcff0dc48286916001cc114379a1", size = 400113, upload-time = "2025-07-01T15:54:38.954Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/36c0925fff6f660a80be259c5b4f5e53a16851f946eb080351d057698528/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c5fe114a6dd480a510b6d3661d09d67d1622c4bf20660a474507aaee7eeeee9", size = 515189, upload-time = "2025-07-01T15:54:40.57Z" }, - { url = "https://files.pythonhosted.org/packages/13/45/cbf07fc03ba7a9b54662c9badb58294ecfb24f828b9732970bd1a431ed5c/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3100b3090269f3a7ea727b06a6080d4eb7439dca4c0e91a07c5d133bb1727ea7", size = 406998, upload-time = "2025-07-01T15:54:43.025Z" }, - { url = "https://files.pythonhosted.org/packages/6c/b0/8fa5e36e58657997873fd6a1cf621285ca822ca75b4b3434ead047daa307/rpds_py-0.26.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c03c9b0c64afd0320ae57de4c982801271c0c211aa2d37f3003ff5feb75bb04", size = 385903, upload-time = "2025-07-01T15:54:44.752Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f7/b25437772f9f57d7a9fbd73ed86d0dcd76b4c7c6998348c070d90f23e315/rpds_py-0.26.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5963b72ccd199ade6ee493723d18a3f21ba7d5b957017607f815788cef50eaf1", size = 419785, upload-time = "2025-07-01T15:54:46.043Z" }, - { url = "https://files.pythonhosted.org/packages/a7/6b/63ffa55743dfcb4baf2e9e77a0b11f7f97ed96a54558fcb5717a4b2cd732/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9da4e873860ad5bab3291438525cae80169daecbfafe5657f7f5fb4d6b3f96b9", size = 561329, upload-time = "2025-07-01T15:54:47.64Z" }, - { url = "https://files.pythonhosted.org/packages/2f/07/1f4f5e2886c480a2346b1e6759c00278b8a69e697ae952d82ae2e6ee5db0/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5afaddaa8e8c7f1f7b4c5c725c0070b6eed0228f705b90a1732a48e84350f4e9", size = 590875, upload-time = "2025-07-01T15:54:48.9Z" }, - { url = "https://files.pythonhosted.org/packages/cc/bc/e6639f1b91c3a55f8c41b47d73e6307051b6e246254a827ede730624c0f8/rpds_py-0.26.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4916dc96489616a6f9667e7526af8fa693c0fdb4f3acb0e5d9f4400eb06a47ba", size = 556636, upload-time = "2025-07-01T15:54:50.619Z" }, - { url = "https://files.pythonhosted.org/packages/05/4c/b3917c45566f9f9a209d38d9b54a1833f2bb1032a3e04c66f75726f28876/rpds_py-0.26.0-cp313-cp313-win32.whl", hash = "sha256:2a343f91b17097c546b93f7999976fd6c9d5900617aa848c81d794e062ab302b", size = 222663, upload-time = "2025-07-01T15:54:52.023Z" }, - { url = "https://files.pythonhosted.org/packages/e0/0b/0851bdd6025775aaa2365bb8de0697ee2558184c800bfef8d7aef5ccde58/rpds_py-0.26.0-cp313-cp313-win_amd64.whl", hash = "sha256:0a0b60701f2300c81b2ac88a5fb893ccfa408e1c4a555a77f908a2596eb875a5", size = 234428, upload-time = "2025-07-01T15:54:53.692Z" }, - { url = "https://files.pythonhosted.org/packages/ed/e8/a47c64ed53149c75fb581e14a237b7b7cd18217e969c30d474d335105622/rpds_py-0.26.0-cp313-cp313-win_arm64.whl", hash = "sha256:257d011919f133a4746958257f2c75238e3ff54255acd5e3e11f3ff41fd14256", size = 222571, upload-time = "2025-07-01T15:54:54.822Z" }, - { url = "https://files.pythonhosted.org/packages/89/bf/3d970ba2e2bcd17d2912cb42874107390f72873e38e79267224110de5e61/rpds_py-0.26.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:529c8156d7506fba5740e05da8795688f87119cce330c244519cf706a4a3d618", size = 360475, upload-time = "2025-07-01T15:54:56.228Z" }, - { url = "https://files.pythonhosted.org/packages/82/9f/283e7e2979fc4ec2d8ecee506d5a3675fce5ed9b4b7cb387ea5d37c2f18d/rpds_py-0.26.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f53ec51f9d24e9638a40cabb95078ade8c99251945dad8d57bf4aabe86ecee35", size = 346692, upload-time = "2025-07-01T15:54:58.561Z" }, - { url = "https://files.pythonhosted.org/packages/e3/03/7e50423c04d78daf391da3cc4330bdb97042fc192a58b186f2d5deb7befd/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab504c4d654e4a29558eaa5bb8cea5fdc1703ea60a8099ffd9c758472cf913f", size = 379415, upload-time = "2025-07-01T15:54:59.751Z" }, - { url = "https://files.pythonhosted.org/packages/57/00/d11ee60d4d3b16808432417951c63df803afb0e0fc672b5e8d07e9edaaae/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd0641abca296bc1a00183fe44f7fced8807ed49d501f188faa642d0e4975b83", size = 391783, upload-time = "2025-07-01T15:55:00.898Z" }, - { url = "https://files.pythonhosted.org/packages/08/b3/1069c394d9c0d6d23c5b522e1f6546b65793a22950f6e0210adcc6f97c3e/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b312fecc1d017b5327afa81d4da1480f51c68810963a7336d92203dbb3d4f1", size = 512844, upload-time = "2025-07-01T15:55:02.201Z" }, - { url = "https://files.pythonhosted.org/packages/08/3b/c4fbf0926800ed70b2c245ceca99c49f066456755f5d6eb8863c2c51e6d0/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c741107203954f6fc34d3066d213d0a0c40f7bb5aafd698fb39888af277c70d8", size = 402105, upload-time = "2025-07-01T15:55:03.698Z" }, - { url = "https://files.pythonhosted.org/packages/1c/b0/db69b52ca07413e568dae9dc674627a22297abb144c4d6022c6d78f1e5cc/rpds_py-0.26.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc3e55a7db08dc9a6ed5fb7103019d2c1a38a349ac41901f9f66d7f95750942f", size = 383440, upload-time = "2025-07-01T15:55:05.398Z" }, - { url = "https://files.pythonhosted.org/packages/4c/e1/c65255ad5b63903e56b3bb3ff9dcc3f4f5c3badde5d08c741ee03903e951/rpds_py-0.26.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e851920caab2dbcae311fd28f4313c6953993893eb5c1bb367ec69d9a39e7ed", size = 412759, upload-time = "2025-07-01T15:55:08.316Z" }, - { url = "https://files.pythonhosted.org/packages/e4/22/bb731077872377a93c6e93b8a9487d0406c70208985831034ccdeed39c8e/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dfbf280da5f876d0b00c81f26bedce274e72a678c28845453885a9b3c22ae632", size = 556032, upload-time = "2025-07-01T15:55:09.52Z" }, - { url = "https://files.pythonhosted.org/packages/e0/8b/393322ce7bac5c4530fb96fc79cc9ea2f83e968ff5f6e873f905c493e1c4/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1cc81d14ddfa53d7f3906694d35d54d9d3f850ef8e4e99ee68bc0d1e5fed9a9c", size = 585416, upload-time = "2025-07-01T15:55:11.216Z" }, - { url = "https://files.pythonhosted.org/packages/49/ae/769dc372211835bf759319a7aae70525c6eb523e3371842c65b7ef41c9c6/rpds_py-0.26.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dca83c498b4650a91efcf7b88d669b170256bf8017a5db6f3e06c2bf031f57e0", size = 554049, upload-time = "2025-07-01T15:55:13.004Z" }, - { url = "https://files.pythonhosted.org/packages/6b/f9/4c43f9cc203d6ba44ce3146246cdc38619d92c7bd7bad4946a3491bd5b70/rpds_py-0.26.0-cp313-cp313t-win32.whl", hash = "sha256:4d11382bcaf12f80b51d790dee295c56a159633a8e81e6323b16e55d81ae37e9", size = 218428, upload-time = "2025-07-01T15:55:14.486Z" }, - { url = "https://files.pythonhosted.org/packages/7e/8b/9286b7e822036a4a977f2f1e851c7345c20528dbd56b687bb67ed68a8ede/rpds_py-0.26.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff110acded3c22c033e637dd8896e411c7d3a11289b2edf041f86663dbc791e9", size = 231524, upload-time = "2025-07-01T15:55:15.745Z" }, - { url = "https://files.pythonhosted.org/packages/55/07/029b7c45db910c74e182de626dfdae0ad489a949d84a468465cd0ca36355/rpds_py-0.26.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:da619979df60a940cd434084355c514c25cf8eb4cf9a508510682f6c851a4f7a", size = 364292, upload-time = "2025-07-01T15:55:17.001Z" }, - { url = "https://files.pythonhosted.org/packages/13/d1/9b3d3f986216b4d1f584878dca15ce4797aaf5d372d738974ba737bf68d6/rpds_py-0.26.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ea89a2458a1a75f87caabefe789c87539ea4e43b40f18cff526052e35bbb4fdf", size = 350334, upload-time = "2025-07-01T15:55:18.922Z" }, - { url = "https://files.pythonhosted.org/packages/18/98/16d5e7bc9ec715fa9668731d0cf97f6b032724e61696e2db3d47aeb89214/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feac1045b3327a45944e7dcbeb57530339f6b17baff154df51ef8b0da34c8c12", size = 384875, upload-time = "2025-07-01T15:55:20.399Z" }, - { url = "https://files.pythonhosted.org/packages/f9/13/aa5e2b1ec5ab0e86a5c464d53514c0467bec6ba2507027d35fc81818358e/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b818a592bd69bfe437ee8368603d4a2d928c34cffcdf77c2e761a759ffd17d20", size = 399993, upload-time = "2025-07-01T15:55:21.729Z" }, - { url = "https://files.pythonhosted.org/packages/17/03/8021810b0e97923abdbab6474c8b77c69bcb4b2c58330777df9ff69dc559/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a8b0dd8648709b62d9372fc00a57466f5fdeefed666afe3fea5a6c9539a0331", size = 516683, upload-time = "2025-07-01T15:55:22.918Z" }, - { url = "https://files.pythonhosted.org/packages/dc/b1/da8e61c87c2f3d836954239fdbbfb477bb7b54d74974d8f6fcb34342d166/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6d3498ad0df07d81112aa6ec6c95a7e7b1ae00929fb73e7ebee0f3faaeabad2f", size = 408825, upload-time = "2025-07-01T15:55:24.207Z" }, - { url = "https://files.pythonhosted.org/packages/38/bc/1fc173edaaa0e52c94b02a655db20697cb5fa954ad5a8e15a2c784c5cbdd/rpds_py-0.26.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a4146ccb15be237fdef10f331c568e1b0e505f8c8c9ed5d67759dac58ac246", size = 387292, upload-time = "2025-07-01T15:55:25.554Z" }, - { url = "https://files.pythonhosted.org/packages/7c/eb/3a9bb4bd90867d21916f253caf4f0d0be7098671b6715ad1cead9fe7bab9/rpds_py-0.26.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a9a63785467b2d73635957d32a4f6e73d5e4df497a16a6392fa066b753e87387", size = 420435, upload-time = "2025-07-01T15:55:27.798Z" }, - { url = "https://files.pythonhosted.org/packages/cd/16/e066dcdb56f5632713445271a3f8d3d0b426d51ae9c0cca387799df58b02/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:de4ed93a8c91debfd5a047be327b7cc8b0cc6afe32a716bbbc4aedca9e2a83af", size = 562410, upload-time = "2025-07-01T15:55:29.057Z" }, - { url = "https://files.pythonhosted.org/packages/60/22/ddbdec7eb82a0dc2e455be44c97c71c232983e21349836ce9f272e8a3c29/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:caf51943715b12af827696ec395bfa68f090a4c1a1d2509eb4e2cb69abbbdb33", size = 590724, upload-time = "2025-07-01T15:55:30.719Z" }, - { url = "https://files.pythonhosted.org/packages/2c/b4/95744085e65b7187d83f2fcb0bef70716a1ea0a9e5d8f7f39a86e5d83424/rpds_py-0.26.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4a59e5bc386de021f56337f757301b337d7ab58baa40174fb150accd480bc953", size = 558285, upload-time = "2025-07-01T15:55:31.981Z" }, - { url = "https://files.pythonhosted.org/packages/37/37/6309a75e464d1da2559446f9c811aa4d16343cebe3dbb73701e63f760caa/rpds_py-0.26.0-cp314-cp314-win32.whl", hash = "sha256:92c8db839367ef16a662478f0a2fe13e15f2227da3c1430a782ad0f6ee009ec9", size = 223459, upload-time = "2025-07-01T15:55:33.312Z" }, - { url = "https://files.pythonhosted.org/packages/d9/6f/8e9c11214c46098b1d1391b7e02b70bb689ab963db3b19540cba17315291/rpds_py-0.26.0-cp314-cp314-win_amd64.whl", hash = "sha256:b0afb8cdd034150d4d9f53926226ed27ad15b7f465e93d7468caaf5eafae0d37", size = 236083, upload-time = "2025-07-01T15:55:34.933Z" }, - { url = "https://files.pythonhosted.org/packages/47/af/9c4638994dd623d51c39892edd9d08e8be8220a4b7e874fa02c2d6e91955/rpds_py-0.26.0-cp314-cp314-win_arm64.whl", hash = "sha256:ca3f059f4ba485d90c8dc75cb5ca897e15325e4e609812ce57f896607c1c0867", size = 223291, upload-time = "2025-07-01T15:55:36.202Z" }, - { url = "https://files.pythonhosted.org/packages/4d/db/669a241144460474aab03e254326b32c42def83eb23458a10d163cb9b5ce/rpds_py-0.26.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:5afea17ab3a126006dc2f293b14ffc7ef3c85336cf451564a0515ed7648033da", size = 361445, upload-time = "2025-07-01T15:55:37.483Z" }, - { url = "https://files.pythonhosted.org/packages/3b/2d/133f61cc5807c6c2fd086a46df0eb8f63a23f5df8306ff9f6d0fd168fecc/rpds_py-0.26.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:69f0c0a3df7fd3a7eec50a00396104bb9a843ea6d45fcc31c2d5243446ffd7a7", size = 347206, upload-time = "2025-07-01T15:55:38.828Z" }, - { url = "https://files.pythonhosted.org/packages/05/bf/0e8fb4c05f70273469eecf82f6ccf37248558526a45321644826555db31b/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:801a71f70f9813e82d2513c9a96532551fce1e278ec0c64610992c49c04c2dad", size = 380330, upload-time = "2025-07-01T15:55:40.175Z" }, - { url = "https://files.pythonhosted.org/packages/d4/a8/060d24185d8b24d3923322f8d0ede16df4ade226a74e747b8c7c978e3dd3/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df52098cde6d5e02fa75c1f6244f07971773adb4a26625edd5c18fee906fa84d", size = 392254, upload-time = "2025-07-01T15:55:42.015Z" }, - { url = "https://files.pythonhosted.org/packages/b9/7b/7c2e8a9ee3e6bc0bae26bf29f5219955ca2fbb761dca996a83f5d2f773fe/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9bc596b30f86dc6f0929499c9e574601679d0341a0108c25b9b358a042f51bca", size = 516094, upload-time = "2025-07-01T15:55:43.603Z" }, - { url = "https://files.pythonhosted.org/packages/75/d6/f61cafbed8ba1499b9af9f1777a2a199cd888f74a96133d8833ce5eaa9c5/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dfbe56b299cf5875b68eb6f0ebaadc9cac520a1989cac0db0765abfb3709c19", size = 402889, upload-time = "2025-07-01T15:55:45.275Z" }, - { url = "https://files.pythonhosted.org/packages/92/19/c8ac0a8a8df2dd30cdec27f69298a5c13e9029500d6d76718130f5e5be10/rpds_py-0.26.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac64f4b2bdb4ea622175c9ab7cf09444e412e22c0e02e906978b3b488af5fde8", size = 384301, upload-time = "2025-07-01T15:55:47.098Z" }, - { url = "https://files.pythonhosted.org/packages/41/e1/6b1859898bc292a9ce5776016c7312b672da00e25cec74d7beced1027286/rpds_py-0.26.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:181ef9b6bbf9845a264f9aa45c31836e9f3c1f13be565d0d010e964c661d1e2b", size = 412891, upload-time = "2025-07-01T15:55:48.412Z" }, - { url = "https://files.pythonhosted.org/packages/ef/b9/ceb39af29913c07966a61367b3c08b4f71fad841e32c6b59a129d5974698/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:49028aa684c144ea502a8e847d23aed5e4c2ef7cadfa7d5eaafcb40864844b7a", size = 557044, upload-time = "2025-07-01T15:55:49.816Z" }, - { url = "https://files.pythonhosted.org/packages/2f/27/35637b98380731a521f8ec4f3fd94e477964f04f6b2f8f7af8a2d889a4af/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e5d524d68a474a9688336045bbf76cb0def88549c1b2ad9dbfec1fb7cfbe9170", size = 585774, upload-time = "2025-07-01T15:55:51.192Z" }, - { url = "https://files.pythonhosted.org/packages/52/d9/3f0f105420fecd18551b678c9a6ce60bd23986098b252a56d35781b3e7e9/rpds_py-0.26.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c1851f429b822831bd2edcbe0cfd12ee9ea77868f8d3daf267b189371671c80e", size = 554886, upload-time = "2025-07-01T15:55:52.541Z" }, - { url = "https://files.pythonhosted.org/packages/6b/c5/347c056a90dc8dd9bc240a08c527315008e1b5042e7a4cf4ac027be9d38a/rpds_py-0.26.0-cp314-cp314t-win32.whl", hash = "sha256:7bdb17009696214c3b66bb3590c6d62e14ac5935e53e929bcdbc5a495987a84f", size = 219027, upload-time = "2025-07-01T15:55:53.874Z" }, - { url = "https://files.pythonhosted.org/packages/75/04/5302cea1aa26d886d34cadbf2dc77d90d7737e576c0065f357b96dc7a1a6/rpds_py-0.26.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f14440b9573a6f76b4ee4770c13f0b5921f71dde3b6fcb8dabbefd13b7fe05d7", size = 232821, upload-time = "2025-07-01T15:55:55.167Z" }, - { url = "https://files.pythonhosted.org/packages/fb/74/846ab687119c9d31fc21ab1346ef9233c31035ce53c0e2d43a130a0c5a5e/rpds_py-0.26.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:7a48af25d9b3c15684059d0d1fc0bc30e8eee5ca521030e2bffddcab5be40226", size = 372786, upload-time = "2025-07-01T15:55:56.512Z" }, - { url = "https://files.pythonhosted.org/packages/33/02/1f9e465cb1a6032d02b17cd117c7bd9fb6156bc5b40ffeb8053d8a2aa89c/rpds_py-0.26.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c71c2f6bf36e61ee5c47b2b9b5d47e4d1baad6426bfed9eea3e858fc6ee8806", size = 358062, upload-time = "2025-07-01T15:55:58.084Z" }, - { url = "https://files.pythonhosted.org/packages/2a/49/81a38e3c67ac943907a9711882da3d87758c82cf26b2120b8128e45d80df/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d815d48b1804ed7867b539236b6dd62997850ca1c91cad187f2ddb1b7bbef19", size = 381576, upload-time = "2025-07-01T15:55:59.422Z" }, - { url = "https://files.pythonhosted.org/packages/14/37/418f030a76ef59f41e55f9dc916af8afafa3c9e3be38df744b2014851474/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:84cfbd4d4d2cdeb2be61a057a258d26b22877266dd905809e94172dff01a42ae", size = 397062, upload-time = "2025-07-01T15:56:00.868Z" }, - { url = "https://files.pythonhosted.org/packages/47/e3/9090817a8f4388bfe58e28136e9682fa7872a06daff2b8a2f8c78786a6e1/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fbaa70553ca116c77717f513e08815aec458e6b69a028d4028d403b3bc84ff37", size = 516277, upload-time = "2025-07-01T15:56:02.672Z" }, - { url = "https://files.pythonhosted.org/packages/3f/3a/1ec3dd93250fb8023f27d49b3f92e13f679141f2e59a61563f88922c2821/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39bfea47c375f379d8e87ab4bb9eb2c836e4f2069f0f65731d85e55d74666387", size = 402604, upload-time = "2025-07-01T15:56:04.453Z" }, - { url = "https://files.pythonhosted.org/packages/f2/98/9133c06e42ec3ce637936263c50ac647f879b40a35cfad2f5d4ad418a439/rpds_py-0.26.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1533b7eb683fb5f38c1d68a3c78f5fdd8f1412fa6b9bf03b40f450785a0ab915", size = 383664, upload-time = "2025-07-01T15:56:05.823Z" }, - { url = "https://files.pythonhosted.org/packages/a9/10/a59ce64099cc77c81adb51f06909ac0159c19a3e2c9d9613bab171f4730f/rpds_py-0.26.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c5ab0ee51f560d179b057555b4f601b7df909ed31312d301b99f8b9fc6028284", size = 415944, upload-time = "2025-07-01T15:56:07.132Z" }, - { url = "https://files.pythonhosted.org/packages/c3/f1/ae0c60b3be9df9d5bef3527d83b8eb4b939e3619f6dd8382840e220a27df/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e5162afc9e0d1f9cae3b577d9c29ddbab3505ab39012cb794d94a005825bde21", size = 558311, upload-time = "2025-07-01T15:56:08.484Z" }, - { url = "https://files.pythonhosted.org/packages/fb/2b/bf1498ebb3ddc5eff2fe3439da88963d1fc6e73d1277fa7ca0c72620d167/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:43f10b007033f359bc3fa9cd5e6c1e76723f056ffa9a6b5c117cc35720a80292", size = 587928, upload-time = "2025-07-01T15:56:09.946Z" }, - { url = "https://files.pythonhosted.org/packages/b6/eb/e6b949edf7af5629848c06d6e544a36c9f2781e2d8d03b906de61ada04d0/rpds_py-0.26.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e3730a48e5622e598293eee0762b09cff34dd3f271530f47b0894891281f051d", size = 554554, upload-time = "2025-07-01T15:56:11.775Z" }, - { url = "https://files.pythonhosted.org/packages/0a/1c/aa0298372ea898620d4706ad26b5b9e975550a4dd30bd042b0fe9ae72cce/rpds_py-0.26.0-cp39-cp39-win32.whl", hash = "sha256:4b1f66eb81eab2e0ff5775a3a312e5e2e16bf758f7b06be82fb0d04078c7ac51", size = 220273, upload-time = "2025-07-01T15:56:13.273Z" }, - { url = "https://files.pythonhosted.org/packages/b8/b0/8b3bef6ad0b35c172d1c87e2e5c2bb027d99e2a7bc7a16f744e66cf318f3/rpds_py-0.26.0-cp39-cp39-win_amd64.whl", hash = "sha256:519067e29f67b5c90e64fb1a6b6e9d2ec0ba28705c51956637bac23a2f4ddae1", size = 231627, upload-time = "2025-07-01T15:56:14.853Z" }, - { url = "https://files.pythonhosted.org/packages/ef/9a/1f033b0b31253d03d785b0cd905bc127e555ab496ea6b4c7c2e1f951f2fd/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3c0909c5234543ada2515c05dc08595b08d621ba919629e94427e8e03539c958", size = 373226, upload-time = "2025-07-01T15:56:16.578Z" }, - { url = "https://files.pythonhosted.org/packages/58/29/5f88023fd6aaaa8ca3c4a6357ebb23f6f07da6079093ccf27c99efce87db/rpds_py-0.26.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:c1fb0cda2abcc0ac62f64e2ea4b4e64c57dfd6b885e693095460c61bde7bb18e", size = 359230, upload-time = "2025-07-01T15:56:17.978Z" }, - { url = "https://files.pythonhosted.org/packages/6c/6c/13eaebd28b439da6964dde22712b52e53fe2824af0223b8e403249d10405/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84d142d2d6cf9b31c12aa4878d82ed3b2324226270b89b676ac62ccd7df52d08", size = 382363, upload-time = "2025-07-01T15:56:19.977Z" }, - { url = "https://files.pythonhosted.org/packages/55/fc/3bb9c486b06da19448646f96147796de23c5811ef77cbfc26f17307b6a9d/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a547e21c5610b7e9093d870be50682a6a6cf180d6da0f42c47c306073bfdbbf6", size = 397146, upload-time = "2025-07-01T15:56:21.39Z" }, - { url = "https://files.pythonhosted.org/packages/15/18/9d1b79eb4d18e64ba8bba9e7dec6f9d6920b639f22f07ee9368ca35d4673/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35e9a70a0f335371275cdcd08bc5b8051ac494dd58bff3bbfb421038220dc871", size = 514804, upload-time = "2025-07-01T15:56:22.78Z" }, - { url = "https://files.pythonhosted.org/packages/4f/5a/175ad7191bdbcd28785204621b225ad70e85cdfd1e09cc414cb554633b21/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0dfa6115c6def37905344d56fb54c03afc49104e2ca473d5dedec0f6606913b4", size = 402820, upload-time = "2025-07-01T15:56:24.584Z" }, - { url = "https://files.pythonhosted.org/packages/11/45/6a67ecf6d61c4d4aff4bc056e864eec4b2447787e11d1c2c9a0242c6e92a/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:313cfcd6af1a55a286a3c9a25f64af6d0e46cf60bc5798f1db152d97a216ff6f", size = 384567, upload-time = "2025-07-01T15:56:26.064Z" }, - { url = "https://files.pythonhosted.org/packages/a1/ba/16589da828732b46454c61858950a78fe4c931ea4bf95f17432ffe64b241/rpds_py-0.26.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7bf2496fa563c046d05e4d232d7b7fd61346e2402052064b773e5c378bf6f73", size = 416520, upload-time = "2025-07-01T15:56:27.608Z" }, - { url = "https://files.pythonhosted.org/packages/81/4b/00092999fc7c0c266045e984d56b7314734cc400a6c6dc4d61a35f135a9d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:aa81873e2c8c5aa616ab8e017a481a96742fdf9313c40f14338ca7dbf50cb55f", size = 559362, upload-time = "2025-07-01T15:56:29.078Z" }, - { url = "https://files.pythonhosted.org/packages/96/0c/43737053cde1f93ac4945157f7be1428724ab943e2132a0d235a7e161d4e/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:68ffcf982715f5b5b7686bdd349ff75d422e8f22551000c24b30eaa1b7f7ae84", size = 588113, upload-time = "2025-07-01T15:56:30.485Z" }, - { url = "https://files.pythonhosted.org/packages/46/46/8e38f6161466e60a997ed7e9951ae5de131dedc3cf778ad35994b4af823d/rpds_py-0.26.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6188de70e190847bb6db3dc3981cbadff87d27d6fe9b4f0e18726d55795cee9b", size = 555429, upload-time = "2025-07-01T15:56:31.956Z" }, - { url = "https://files.pythonhosted.org/packages/2c/ac/65da605e9f1dd643ebe615d5bbd11b6efa1d69644fc4bf623ea5ae385a82/rpds_py-0.26.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1c962145c7473723df9722ba4c058de12eb5ebedcb4e27e7d902920aa3831ee8", size = 231950, upload-time = "2025-07-01T15:56:33.337Z" }, - { url = "https://files.pythonhosted.org/packages/51/f2/b5c85b758a00c513bb0389f8fc8e61eb5423050c91c958cdd21843faa3e6/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f61a9326f80ca59214d1cceb0a09bb2ece5b2563d4e0cd37bfd5515c28510674", size = 373505, upload-time = "2025-07-01T15:56:34.716Z" }, - { url = "https://files.pythonhosted.org/packages/23/e0/25db45e391251118e915e541995bb5f5ac5691a3b98fb233020ba53afc9b/rpds_py-0.26.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:183f857a53bcf4b1b42ef0f57ca553ab56bdd170e49d8091e96c51c3d69ca696", size = 359468, upload-time = "2025-07-01T15:56:36.219Z" }, - { url = "https://files.pythonhosted.org/packages/0b/73/dd5ee6075bb6491be3a646b301dfd814f9486d924137a5098e61f0487e16/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:941c1cfdf4799d623cf3aa1d326a6b4fdb7a5799ee2687f3516738216d2262fb", size = 382680, upload-time = "2025-07-01T15:56:37.644Z" }, - { url = "https://files.pythonhosted.org/packages/2f/10/84b522ff58763a5c443f5bcedc1820240e454ce4e620e88520f04589e2ea/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72a8d9564a717ee291f554eeb4bfeafe2309d5ec0aa6c475170bdab0f9ee8e88", size = 397035, upload-time = "2025-07-01T15:56:39.241Z" }, - { url = "https://files.pythonhosted.org/packages/06/ea/8667604229a10a520fcbf78b30ccc278977dcc0627beb7ea2c96b3becef0/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:511d15193cbe013619dd05414c35a7dedf2088fcee93c6bbb7c77859765bd4e8", size = 514922, upload-time = "2025-07-01T15:56:40.645Z" }, - { url = "https://files.pythonhosted.org/packages/24/e6/9ed5b625c0661c4882fc8cdf302bf8e96c73c40de99c31e0b95ed37d508c/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aea1f9741b603a8d8fedb0ed5502c2bc0accbc51f43e2ad1337fe7259c2b77a5", size = 402822, upload-time = "2025-07-01T15:56:42.137Z" }, - { url = "https://files.pythonhosted.org/packages/8a/58/212c7b6fd51946047fb45d3733da27e2fa8f7384a13457c874186af691b1/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4019a9d473c708cf2f16415688ef0b4639e07abaa569d72f74745bbeffafa2c7", size = 384336, upload-time = "2025-07-01T15:56:44.239Z" }, - { url = "https://files.pythonhosted.org/packages/aa/f5/a40ba78748ae8ebf4934d4b88e77b98497378bc2c24ba55ebe87a4e87057/rpds_py-0.26.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:093d63b4b0f52d98ebae33b8c50900d3d67e0666094b1be7a12fffd7f65de74b", size = 416871, upload-time = "2025-07-01T15:56:46.284Z" }, - { url = "https://files.pythonhosted.org/packages/d5/a6/33b1fc0c9f7dcfcfc4a4353daa6308b3ece22496ceece348b3e7a7559a09/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2abe21d8ba64cded53a2a677e149ceb76dcf44284202d737178afe7ba540c1eb", size = 559439, upload-time = "2025-07-01T15:56:48.549Z" }, - { url = "https://files.pythonhosted.org/packages/71/2d/ceb3f9c12f8cfa56d34995097f6cd99da1325642c60d1b6680dd9df03ed8/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:4feb7511c29f8442cbbc28149a92093d32e815a28aa2c50d333826ad2a20fdf0", size = 588380, upload-time = "2025-07-01T15:56:50.086Z" }, - { url = "https://files.pythonhosted.org/packages/c8/ed/9de62c2150ca8e2e5858acf3f4f4d0d180a38feef9fdab4078bea63d8dba/rpds_py-0.26.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e99685fc95d386da368013e7fb4269dd39c30d99f812a8372d62f244f662709c", size = 555334, upload-time = "2025-07-01T15:56:51.703Z" }, - { url = "https://files.pythonhosted.org/packages/7e/78/a08e2f28e91c7e45db1150813c6d760a0fb114d5652b1373897073369e0d/rpds_py-0.26.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a90a13408a7a856b87be8a9f008fff53c5080eea4e4180f6c2e546e4a972fb5d", size = 373157, upload-time = "2025-07-01T15:56:53.291Z" }, - { url = "https://files.pythonhosted.org/packages/52/01/ddf51517497c8224fb0287e9842b820ed93748bc28ea74cab56a71e3dba4/rpds_py-0.26.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ac51b65e8dc76cf4949419c54c5528adb24fc721df722fd452e5fbc236f5c40", size = 358827, upload-time = "2025-07-01T15:56:54.963Z" }, - { url = "https://files.pythonhosted.org/packages/4d/f4/acaefa44b83705a4fcadd68054280127c07cdb236a44a1c08b7c5adad40b/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59b2093224a18c6508d95cfdeba8db9cbfd6f3494e94793b58972933fcee4c6d", size = 382182, upload-time = "2025-07-01T15:56:56.474Z" }, - { url = "https://files.pythonhosted.org/packages/e9/a2/d72ac03d37d33f6ff4713ca4c704da0c3b1b3a959f0bf5eb738c0ad94ea2/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4f01a5d6444a3258b00dc07b6ea4733e26f8072b788bef750baa37b370266137", size = 397123, upload-time = "2025-07-01T15:56:58.272Z" }, - { url = "https://files.pythonhosted.org/packages/74/58/c053e9d1da1d3724434dd7a5f506623913e6404d396ff3cf636a910c0789/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6e2c12160c72aeda9d1283e612f68804621f448145a210f1bf1d79151c47090", size = 516285, upload-time = "2025-07-01T15:57:00.283Z" }, - { url = "https://files.pythonhosted.org/packages/94/41/c81e97ee88b38b6d1847c75f2274dee8d67cb8d5ed7ca8c6b80442dead75/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb28c1f569f8d33b2b5dcd05d0e6ef7005d8639c54c2f0be824f05aedf715255", size = 402182, upload-time = "2025-07-01T15:57:02.587Z" }, - { url = "https://files.pythonhosted.org/packages/74/74/38a176b34ce5197b4223e295f36350dd90713db13cf3c3b533e8e8f7484e/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1766b5724c3f779317d5321664a343c07773c8c5fd1532e4039e6cc7d1a815be", size = 384436, upload-time = "2025-07-01T15:57:04.125Z" }, - { url = "https://files.pythonhosted.org/packages/e4/21/f40b9a5709d7078372c87fd11335469dc4405245528b60007cd4078ed57a/rpds_py-0.26.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b6d9e5a2ed9c4988c8f9b28b3bc0e3e5b1aaa10c28d210a594ff3a8c02742daf", size = 417039, upload-time = "2025-07-01T15:57:05.608Z" }, - { url = "https://files.pythonhosted.org/packages/02/ee/ed835925731c7e87306faa80a3a5e17b4d0f532083155e7e00fe1cd4e242/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:b5f7a446ddaf6ca0fad9a5535b56fbfc29998bf0e0b450d174bbec0d600e1d72", size = 559111, upload-time = "2025-07-01T15:57:07.371Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/d6e9e686b8ffb6139b82eb1c319ef32ae99aeb21f7e4bf45bba44a760d09/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:eed5ac260dd545fbc20da5f4f15e7efe36a55e0e7cf706e4ec005b491a9546a0", size = 588609, upload-time = "2025-07-01T15:57:09.319Z" }, - { url = "https://files.pythonhosted.org/packages/e5/96/09bcab08fa12a69672716b7f86c672ee7f79c5319f1890c5a79dcb8e0df2/rpds_py-0.26.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:582462833ba7cee52e968b0341b85e392ae53d44c0f9af6a5927c80e539a8b67", size = 555212, upload-time = "2025-07-01T15:57:10.905Z" }, - { url = "https://files.pythonhosted.org/packages/2c/07/c554b6ed0064b6e0350a622714298e930b3cf5a3d445a2e25c412268abcf/rpds_py-0.26.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:69a607203441e07e9a8a529cff1d5b73f6a160f22db1097211e6212a68567d11", size = 232048, upload-time = "2025-07-01T15:57:12.473Z" }, +version = "0.28.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/48/dc/95f074d43452b3ef5d06276696ece4b3b5d696e7c9ad7173c54b1390cd70/rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea", size = 27419, upload-time = "2025-10-22T22:24:29.327Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/f8/13bb772dc7cbf2c3c5b816febc34fa0cb2c64a08e0569869585684ce6631/rpds_py-0.28.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7b6013db815417eeb56b2d9d7324e64fcd4fa289caeee6e7a78b2e11fc9b438a", size = 362820, upload-time = "2025-10-22T22:21:15.074Z" }, + { url = "https://files.pythonhosted.org/packages/84/91/6acce964aab32469c3dbe792cb041a752d64739c534e9c493c701ef0c032/rpds_py-0.28.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a4c6b05c685c0c03f80dabaeb73e74218c49deea965ca63f76a752807397207", size = 348499, upload-time = "2025-10-22T22:21:17.658Z" }, + { url = "https://files.pythonhosted.org/packages/f1/93/c05bb1f4f5e0234db7c4917cb8dd5e2e0a9a7b26dc74b1b7bee3c9cfd477/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4794c6c3fbe8f9ac87699b131a1f26e7b4abcf6d828da46a3a52648c7930eba", size = 379356, upload-time = "2025-10-22T22:21:19.847Z" }, + { url = "https://files.pythonhosted.org/packages/5c/37/e292da436f0773e319753c567263427cdf6c645d30b44f09463ff8216cda/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2e8456b6ee5527112ff2354dd9087b030e3429e43a74f480d4a5ca79d269fd85", size = 390151, upload-time = "2025-10-22T22:21:21.569Z" }, + { url = "https://files.pythonhosted.org/packages/76/87/a4e3267131616e8faf10486dc00eaedf09bd61c87f01e5ef98e782ee06c9/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:beb880a9ca0a117415f241f66d56025c02037f7c4efc6fe59b5b8454f1eaa50d", size = 524831, upload-time = "2025-10-22T22:21:23.394Z" }, + { url = "https://files.pythonhosted.org/packages/e1/c8/4a4ca76f0befae9515da3fad11038f0fce44f6bb60b21fe9d9364dd51fb0/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6897bebb118c44b38c9cb62a178e09f1593c949391b9a1a6fe777ccab5934ee7", size = 404687, upload-time = "2025-10-22T22:21:25.201Z" }, + { url = "https://files.pythonhosted.org/packages/6a/65/118afe854424456beafbbebc6b34dcf6d72eae3a08b4632bc4220f8240d9/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1b553dd06e875249fd43efd727785efb57a53180e0fde321468222eabbeaafa", size = 382683, upload-time = "2025-10-22T22:21:26.536Z" }, + { url = "https://files.pythonhosted.org/packages/f7/bc/0625064041fb3a0c77ecc8878c0e8341b0ae27ad0f00cf8f2b57337a1e63/rpds_py-0.28.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:f0b2044fdddeea5b05df832e50d2a06fe61023acb44d76978e1b060206a8a476", size = 398927, upload-time = "2025-10-22T22:21:27.864Z" }, + { url = "https://files.pythonhosted.org/packages/5d/1a/fed7cf2f1ee8a5e4778f2054153f2cfcf517748875e2f5b21cf8907cd77d/rpds_py-0.28.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05cf1e74900e8da73fa08cc76c74a03345e5a3e37691d07cfe2092d7d8e27b04", size = 411590, upload-time = "2025-10-22T22:21:29.474Z" }, + { url = "https://files.pythonhosted.org/packages/c1/64/a8e0f67fa374a6c472dbb0afdaf1ef744724f165abb6899f20e2f1563137/rpds_py-0.28.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:efd489fec7c311dae25e94fe7eeda4b3d06be71c68f2cf2e8ef990ffcd2cd7e8", size = 559843, upload-time = "2025-10-22T22:21:30.917Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ea/e10353f6d7c105be09b8135b72787a65919971ae0330ad97d87e4e199880/rpds_py-0.28.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ada7754a10faacd4f26067e62de52d6af93b6d9542f0df73c57b9771eb3ba9c4", size = 584188, upload-time = "2025-10-22T22:21:32.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/b0/a19743e0763caf0c89f6fc6ba6fbd9a353b24ffb4256a492420c5517da5a/rpds_py-0.28.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c2a34fd26588949e1e7977cfcbb17a9a42c948c100cab890c6d8d823f0586457", size = 550052, upload-time = "2025-10-22T22:21:34.702Z" }, + { url = "https://files.pythonhosted.org/packages/de/bc/ec2c004f6c7d6ab1e25dae875cdb1aee087c3ebed5b73712ed3000e3851a/rpds_py-0.28.0-cp310-cp310-win32.whl", hash = "sha256:f9174471d6920cbc5e82a7822de8dfd4dcea86eb828b04fc8c6519a77b0ee51e", size = 215110, upload-time = "2025-10-22T22:21:36.645Z" }, + { url = "https://files.pythonhosted.org/packages/6c/de/4ce8abf59674e17187023933547d2018363e8fc76ada4f1d4d22871ccb6e/rpds_py-0.28.0-cp310-cp310-win_amd64.whl", hash = "sha256:6e32dd207e2c4f8475257a3540ab8a93eff997abfa0a3fdb287cae0d6cd874b8", size = 223850, upload-time = "2025-10-22T22:21:38.006Z" }, + { url = "https://files.pythonhosted.org/packages/a6/34/058d0db5471c6be7bef82487ad5021ff8d1d1d27794be8730aad938649cf/rpds_py-0.28.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:03065002fd2e287725d95fbc69688e0c6daf6c6314ba38bdbaa3895418e09296", size = 362344, upload-time = "2025-10-22T22:21:39.713Z" }, + { url = "https://files.pythonhosted.org/packages/5d/67/9503f0ec8c055a0782880f300c50a2b8e5e72eb1f94dfc2053da527444dd/rpds_py-0.28.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28ea02215f262b6d078daec0b45344c89e161eab9526b0d898221d96fdda5f27", size = 348440, upload-time = "2025-10-22T22:21:41.056Z" }, + { url = "https://files.pythonhosted.org/packages/68/2e/94223ee9b32332a41d75b6f94b37b4ce3e93878a556fc5f152cbd856a81f/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25dbade8fbf30bcc551cb352376c0ad64b067e4fc56f90e22ba70c3ce205988c", size = 379068, upload-time = "2025-10-22T22:21:42.593Z" }, + { url = "https://files.pythonhosted.org/packages/b4/25/54fd48f9f680cfc44e6a7f39a5fadf1d4a4a1fd0848076af4a43e79f998c/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c03002f54cc855860bfdc3442928ffdca9081e73b5b382ed0b9e8efe6e5e205", size = 390518, upload-time = "2025-10-22T22:21:43.998Z" }, + { url = "https://files.pythonhosted.org/packages/1b/85/ac258c9c27f2ccb1bd5d0697e53a82ebcf8088e3186d5d2bf8498ee7ed44/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9699fa7990368b22032baf2b2dce1f634388e4ffc03dfefaaac79f4695edc95", size = 525319, upload-time = "2025-10-22T22:21:45.645Z" }, + { url = "https://files.pythonhosted.org/packages/40/cb/c6734774789566d46775f193964b76627cd5f42ecf246d257ce84d1912ed/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9b06fe1a75e05e0713f06ea0c89ecb6452210fd60e2f1b6ddc1067b990e08d9", size = 404896, upload-time = "2025-10-22T22:21:47.544Z" }, + { url = "https://files.pythonhosted.org/packages/1f/53/14e37ce83202c632c89b0691185dca9532288ff9d390eacae3d2ff771bae/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9f83e7b326a3f9ec3ef84cda98fb0a74c7159f33e692032233046e7fd15da2", size = 382862, upload-time = "2025-10-22T22:21:49.176Z" }, + { url = "https://files.pythonhosted.org/packages/6a/83/f3642483ca971a54d60caa4449f9d6d4dbb56a53e0072d0deff51b38af74/rpds_py-0.28.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:0d3259ea9ad8743a75a43eb7819324cdab393263c91be86e2d1901ee65c314e0", size = 398848, upload-time = "2025-10-22T22:21:51.024Z" }, + { url = "https://files.pythonhosted.org/packages/44/09/2d9c8b2f88e399b4cfe86efdf2935feaf0394e4f14ab30c6c5945d60af7d/rpds_py-0.28.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a7548b345f66f6695943b4ef6afe33ccd3f1b638bd9afd0f730dd255c249c9e", size = 412030, upload-time = "2025-10-22T22:21:52.665Z" }, + { url = "https://files.pythonhosted.org/packages/dd/f5/e1cec473d4bde6df1fd3738be8e82d64dd0600868e76e92dfeaebbc2d18f/rpds_py-0.28.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9a40040aa388b037eb39416710fbcce9443498d2eaab0b9b45ae988b53f5c67", size = 559700, upload-time = "2025-10-22T22:21:54.123Z" }, + { url = "https://files.pythonhosted.org/packages/8d/be/73bb241c1649edbf14e98e9e78899c2c5e52bbe47cb64811f44d2cc11808/rpds_py-0.28.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f60c7ea34e78c199acd0d3cda37a99be2c861dd2b8cf67399784f70c9f8e57d", size = 584581, upload-time = "2025-10-22T22:21:56.102Z" }, + { url = "https://files.pythonhosted.org/packages/9c/9c/ffc6e9218cd1eb5c2c7dbd276c87cd10e8c2232c456b554169eb363381df/rpds_py-0.28.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1571ae4292649100d743b26d5f9c63503bb1fedf538a8f29a98dce2d5ba6b4e6", size = 549981, upload-time = "2025-10-22T22:21:58.253Z" }, + { url = "https://files.pythonhosted.org/packages/5f/50/da8b6d33803a94df0149345ee33e5d91ed4d25fc6517de6a25587eae4133/rpds_py-0.28.0-cp311-cp311-win32.whl", hash = "sha256:5cfa9af45e7c1140af7321fa0bef25b386ee9faa8928c80dc3a5360971a29e8c", size = 214729, upload-time = "2025-10-22T22:21:59.625Z" }, + { url = "https://files.pythonhosted.org/packages/12/fd/b0f48c4c320ee24c8c20df8b44acffb7353991ddf688af01eef5f93d7018/rpds_py-0.28.0-cp311-cp311-win_amd64.whl", hash = "sha256:dd8d86b5d29d1b74100982424ba53e56033dc47720a6de9ba0259cf81d7cecaa", size = 223977, upload-time = "2025-10-22T22:22:01.092Z" }, + { url = "https://files.pythonhosted.org/packages/b4/21/c8e77a2ac66e2ec4e21f18a04b4e9a0417ecf8e61b5eaeaa9360a91713b4/rpds_py-0.28.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e27d3a5709cc2b3e013bf93679a849213c79ae0573f9b894b284b55e729e120", size = 217326, upload-time = "2025-10-22T22:22:02.944Z" }, + { url = "https://files.pythonhosted.org/packages/b8/5c/6c3936495003875fe7b14f90ea812841a08fca50ab26bd840e924097d9c8/rpds_py-0.28.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6b4f28583a4f247ff60cd7bdda83db8c3f5b05a7a82ff20dd4b078571747708f", size = 366439, upload-time = "2025-10-22T22:22:04.525Z" }, + { url = "https://files.pythonhosted.org/packages/56/f9/a0f1ca194c50aa29895b442771f036a25b6c41a35e4f35b1a0ea713bedae/rpds_py-0.28.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d678e91b610c29c4b3d52a2c148b641df2b4676ffe47c59f6388d58b99cdc424", size = 348170, upload-time = "2025-10-22T22:22:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/18/ea/42d243d3a586beb72c77fa5def0487daf827210069a95f36328e869599ea/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e819e0e37a44a78e1383bf1970076e2ccc4dc8c2bbaa2f9bd1dc987e9afff628", size = 378838, upload-time = "2025-10-22T22:22:07.932Z" }, + { url = "https://files.pythonhosted.org/packages/e7/78/3de32e18a94791af8f33601402d9d4f39613136398658412a4e0b3047327/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5ee514e0f0523db5d3fb171f397c54875dbbd69760a414dccf9d4d7ad628b5bd", size = 393299, upload-time = "2025-10-22T22:22:09.435Z" }, + { url = "https://files.pythonhosted.org/packages/13/7e/4bdb435afb18acea2eb8a25ad56b956f28de7c59f8a1d32827effa0d4514/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3fa06d27fdcee47f07a39e02862da0100cb4982508f5ead53ec533cd5fe55e", size = 518000, upload-time = "2025-10-22T22:22:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/31/d0/5f52a656875cdc60498ab035a7a0ac8f399890cc1ee73ebd567bac4e39ae/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46959ef2e64f9e4a41fc89aa20dbca2b85531f9a72c21099a3360f35d10b0d5a", size = 408746, upload-time = "2025-10-22T22:22:13.143Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/49ce51767b879cde77e7ad9fae164ea15dce3616fe591d9ea1df51152706/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8455933b4bcd6e83fde3fefc987a023389c4b13f9a58c8d23e4b3f6d13f78c84", size = 386379, upload-time = "2025-10-22T22:22:14.602Z" }, + { url = "https://files.pythonhosted.org/packages/6a/99/e4e1e1ee93a98f72fc450e36c0e4d99c35370220e815288e3ecd2ec36a2a/rpds_py-0.28.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:ad50614a02c8c2962feebe6012b52f9802deec4263946cddea37aaf28dd25a66", size = 401280, upload-time = "2025-10-22T22:22:16.063Z" }, + { url = "https://files.pythonhosted.org/packages/61/35/e0c6a57488392a8b319d2200d03dad2b29c0db9996f5662c3b02d0b86c02/rpds_py-0.28.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5deca01b271492553fdb6c7fd974659dce736a15bae5dad7ab8b93555bceb28", size = 412365, upload-time = "2025-10-22T22:22:17.504Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6a/841337980ea253ec797eb084665436007a1aad0faac1ba097fb906c5f69c/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:735f8495a13159ce6a0d533f01e8674cec0c57038c920495f87dcb20b3ddb48a", size = 559573, upload-time = "2025-10-22T22:22:19.108Z" }, + { url = "https://files.pythonhosted.org/packages/e7/5e/64826ec58afd4c489731f8b00729c5f6afdb86f1df1df60bfede55d650bb/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:961ca621ff10d198bbe6ba4957decca61aa2a0c56695384c1d6b79bf61436df5", size = 583973, upload-time = "2025-10-22T22:22:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ee/44d024b4843f8386a4eeaa4c171b3d31d55f7177c415545fd1a24c249b5d/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2374e16cc9131022e7d9a8f8d65d261d9ba55048c78f3b6e017971a4f5e6353c", size = 553800, upload-time = "2025-10-22T22:22:22.25Z" }, + { url = "https://files.pythonhosted.org/packages/7d/89/33e675dccff11a06d4d85dbb4d1865f878d5020cbb69b2c1e7b2d3f82562/rpds_py-0.28.0-cp312-cp312-win32.whl", hash = "sha256:d15431e334fba488b081d47f30f091e5d03c18527c325386091f31718952fe08", size = 216954, upload-time = "2025-10-22T22:22:24.105Z" }, + { url = "https://files.pythonhosted.org/packages/af/36/45f6ebb3210887e8ee6dbf1bc710ae8400bb417ce165aaf3024b8360d999/rpds_py-0.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:a410542d61fc54710f750d3764380b53bf09e8c4edbf2f9141a82aa774a04f7c", size = 227844, upload-time = "2025-10-22T22:22:25.551Z" }, + { url = "https://files.pythonhosted.org/packages/57/91/f3fb250d7e73de71080f9a221d19bd6a1c1eb0d12a1ea26513f6c1052ad6/rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd", size = 217624, upload-time = "2025-10-22T22:22:26.914Z" }, + { url = "https://files.pythonhosted.org/packages/d3/03/ce566d92611dfac0085c2f4b048cd53ed7c274a5c05974b882a908d540a2/rpds_py-0.28.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e9e184408a0297086f880556b6168fa927d677716f83d3472ea333b42171ee3b", size = 366235, upload-time = "2025-10-22T22:22:28.397Z" }, + { url = "https://files.pythonhosted.org/packages/00/34/1c61da1b25592b86fd285bd7bd8422f4c9d748a7373b46126f9ae792a004/rpds_py-0.28.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:edd267266a9b0448f33dc465a97cfc5d467594b600fe28e7fa2f36450e03053a", size = 348241, upload-time = "2025-10-22T22:22:30.171Z" }, + { url = "https://files.pythonhosted.org/packages/fc/00/ed1e28616848c61c493a067779633ebf4b569eccaacf9ccbdc0e7cba2b9d/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85beb8b3f45e4e32f6802fb6cd6b17f615ef6c6a52f265371fb916fae02814aa", size = 378079, upload-time = "2025-10-22T22:22:31.644Z" }, + { url = "https://files.pythonhosted.org/packages/11/b2/ccb30333a16a470091b6e50289adb4d3ec656fd9951ba8c5e3aaa0746a67/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d2412be8d00a1b895f8ad827cc2116455196e20ed994bb704bf138fe91a42724", size = 393151, upload-time = "2025-10-22T22:22:33.453Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d0/73e2217c3ee486d555cb84920597480627d8c0240ff3062005c6cc47773e/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf128350d384b777da0e68796afdcebc2e9f63f0e9f242217754e647f6d32491", size = 517520, upload-time = "2025-10-22T22:22:34.949Z" }, + { url = "https://files.pythonhosted.org/packages/c4/91/23efe81c700427d0841a4ae7ea23e305654381831e6029499fe80be8a071/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2036d09b363aa36695d1cc1a97b36865597f4478470b0697b5ee9403f4fe399", size = 408699, upload-time = "2025-10-22T22:22:36.584Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ee/a324d3198da151820a326c1f988caaa4f37fc27955148a76fff7a2d787a9/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8e1e9be4fa6305a16be628959188e4fd5cd6f1b0e724d63c6d8b2a8adf74ea6", size = 385720, upload-time = "2025-10-22T22:22:38.014Z" }, + { url = "https://files.pythonhosted.org/packages/19/ad/e68120dc05af8b7cab4a789fccd8cdcf0fe7e6581461038cc5c164cd97d2/rpds_py-0.28.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0a403460c9dd91a7f23fc3188de6d8977f1d9603a351d5db6cf20aaea95b538d", size = 401096, upload-time = "2025-10-22T22:22:39.869Z" }, + { url = "https://files.pythonhosted.org/packages/99/90/c1e070620042459d60df6356b666bb1f62198a89d68881816a7ed121595a/rpds_py-0.28.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d7366b6553cdc805abcc512b849a519167db8f5e5c3472010cd1228b224265cb", size = 411465, upload-time = "2025-10-22T22:22:41.395Z" }, + { url = "https://files.pythonhosted.org/packages/68/61/7c195b30d57f1b8d5970f600efee72a4fad79ec829057972e13a0370fd24/rpds_py-0.28.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b43c6a3726efd50f18d8120ec0551241c38785b68952d240c45ea553912ac41", size = 558832, upload-time = "2025-10-22T22:22:42.871Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3d/06f3a718864773f69941d4deccdf18e5e47dd298b4628062f004c10f3b34/rpds_py-0.28.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0cb7203c7bc69d7c1585ebb33a2e6074492d2fc21ad28a7b9d40457ac2a51ab7", size = 583230, upload-time = "2025-10-22T22:22:44.877Z" }, + { url = "https://files.pythonhosted.org/packages/66/df/62fc783781a121e77fee9a21ead0a926f1b652280a33f5956a5e7833ed30/rpds_py-0.28.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a52a5169c664dfb495882adc75c304ae1d50df552fbd68e100fdc719dee4ff9", size = 553268, upload-time = "2025-10-22T22:22:46.441Z" }, + { url = "https://files.pythonhosted.org/packages/84/85/d34366e335140a4837902d3dea89b51f087bd6a63c993ebdff59e93ee61d/rpds_py-0.28.0-cp313-cp313-win32.whl", hash = "sha256:2e42456917b6687215b3e606ab46aa6bca040c77af7df9a08a6dcfe8a4d10ca5", size = 217100, upload-time = "2025-10-22T22:22:48.342Z" }, + { url = "https://files.pythonhosted.org/packages/3c/1c/f25a3f3752ad7601476e3eff395fe075e0f7813fbb9862bd67c82440e880/rpds_py-0.28.0-cp313-cp313-win_amd64.whl", hash = "sha256:e0a0311caedc8069d68fc2bf4c9019b58a2d5ce3cd7cb656c845f1615b577e1e", size = 227759, upload-time = "2025-10-22T22:22:50.219Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d6/5f39b42b99615b5bc2f36ab90423ea404830bdfee1c706820943e9a645eb/rpds_py-0.28.0-cp313-cp313-win_arm64.whl", hash = "sha256:04c1b207ab8b581108801528d59ad80aa83bb170b35b0ddffb29c20e411acdc1", size = 217326, upload-time = "2025-10-22T22:22:51.647Z" }, + { url = "https://files.pythonhosted.org/packages/5c/8b/0c69b72d1cee20a63db534be0df271effe715ef6c744fdf1ff23bb2b0b1c/rpds_py-0.28.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f296ea3054e11fc58ad42e850e8b75c62d9a93a9f981ad04b2e5ae7d2186ff9c", size = 355736, upload-time = "2025-10-22T22:22:53.211Z" }, + { url = "https://files.pythonhosted.org/packages/f7/6d/0c2ee773cfb55c31a8514d2cece856dd299170a49babd50dcffb15ddc749/rpds_py-0.28.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5a7306c19b19005ad98468fcefeb7100b19c79fc23a5f24a12e06d91181193fa", size = 342677, upload-time = "2025-10-22T22:22:54.723Z" }, + { url = "https://files.pythonhosted.org/packages/e2/1c/22513ab25a27ea205144414724743e305e8153e6abe81833b5e678650f5a/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5d9b86aa501fed9862a443c5c3116f6ead8bc9296185f369277c42542bd646b", size = 371847, upload-time = "2025-10-22T22:22:56.295Z" }, + { url = "https://files.pythonhosted.org/packages/60/07/68e6ccdb4b05115ffe61d31afc94adef1833d3a72f76c9632d4d90d67954/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e5bbc701eff140ba0e872691d573b3d5d30059ea26e5785acba9132d10c8c31d", size = 381800, upload-time = "2025-10-22T22:22:57.808Z" }, + { url = "https://files.pythonhosted.org/packages/73/bf/6d6d15df80781d7f9f368e7c1a00caf764436518c4877fb28b029c4624af/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5690671cd672a45aa8616d7374fdf334a1b9c04a0cac3c854b1136e92374fe", size = 518827, upload-time = "2025-10-22T22:22:59.826Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d3/2decbb2976cc452cbf12a2b0aaac5f1b9dc5dd9d1f7e2509a3ee00421249/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f1d92ecea4fa12f978a367c32a5375a1982834649cdb96539dcdc12e609ab1a", size = 399471, upload-time = "2025-10-22T22:23:01.968Z" }, + { url = "https://files.pythonhosted.org/packages/b1/2c/f30892f9e54bd02e5faca3f6a26d6933c51055e67d54818af90abed9748e/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d252db6b1a78d0a3928b6190156042d54c93660ce4d98290d7b16b5296fb7cc", size = 377578, upload-time = "2025-10-22T22:23:03.52Z" }, + { url = "https://files.pythonhosted.org/packages/f0/5d/3bce97e5534157318f29ac06bf2d279dae2674ec12f7cb9c12739cee64d8/rpds_py-0.28.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d61b355c3275acb825f8777d6c4505f42b5007e357af500939d4a35b19177259", size = 390482, upload-time = "2025-10-22T22:23:05.391Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f0/886bd515ed457b5bd93b166175edb80a0b21a210c10e993392127f1e3931/rpds_py-0.28.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:acbe5e8b1026c0c580d0321c8aae4b0a1e1676861d48d6e8c6586625055b606a", size = 402447, upload-time = "2025-10-22T22:23:06.93Z" }, + { url = "https://files.pythonhosted.org/packages/42/b5/71e8777ac55e6af1f4f1c05b47542a1eaa6c33c1cf0d300dca6a1c6e159a/rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8aa23b6f0fc59b85b4c7d89ba2965af274346f738e8d9fc2455763602e62fd5f", size = 552385, upload-time = "2025-10-22T22:23:08.557Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cb/6ca2d70cbda5a8e36605e7788c4aa3bea7c17d71d213465a5a675079b98d/rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7b14b0c680286958817c22d76fcbca4800ddacef6f678f3a7c79a1fe7067fe37", size = 575642, upload-time = "2025-10-22T22:23:10.348Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d4/407ad9960ca7856d7b25c96dcbe019270b5ffdd83a561787bc682c797086/rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bcf1d210dfee61a6c86551d67ee1031899c0fdbae88b2d44a569995d43797712", size = 544507, upload-time = "2025-10-22T22:23:12.434Z" }, + { url = "https://files.pythonhosted.org/packages/51/31/2f46fe0efcac23fbf5797c6b6b7e1c76f7d60773e525cb65fcbc582ee0f2/rpds_py-0.28.0-cp313-cp313t-win32.whl", hash = "sha256:3aa4dc0fdab4a7029ac63959a3ccf4ed605fee048ba67ce89ca3168da34a1342", size = 205376, upload-time = "2025-10-22T22:23:13.979Z" }, + { url = "https://files.pythonhosted.org/packages/92/e4/15947bda33cbedfc134490a41841ab8870a72a867a03d4969d886f6594a2/rpds_py-0.28.0-cp313-cp313t-win_amd64.whl", hash = "sha256:7b7d9d83c942855e4fdcfa75d4f96f6b9e272d42fffcb72cd4bb2577db2e2907", size = 215907, upload-time = "2025-10-22T22:23:15.5Z" }, + { url = "https://files.pythonhosted.org/packages/08/47/ffe8cd7a6a02833b10623bf765fbb57ce977e9a4318ca0e8cf97e9c3d2b3/rpds_py-0.28.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:dcdcb890b3ada98a03f9f2bb108489cdc7580176cb73b4f2d789e9a1dac1d472", size = 353830, upload-time = "2025-10-22T22:23:17.03Z" }, + { url = "https://files.pythonhosted.org/packages/f9/9f/890f36cbd83a58491d0d91ae0db1702639edb33fb48eeb356f80ecc6b000/rpds_py-0.28.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f274f56a926ba2dc02976ca5b11c32855cbd5925534e57cfe1fda64e04d1add2", size = 341819, upload-time = "2025-10-22T22:23:18.57Z" }, + { url = "https://files.pythonhosted.org/packages/09/e3/921eb109f682aa24fb76207698fbbcf9418738f35a40c21652c29053f23d/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fe0438ac4a29a520ea94c8c7f1754cdd8feb1bc490dfda1bfd990072363d527", size = 373127, upload-time = "2025-10-22T22:23:20.216Z" }, + { url = "https://files.pythonhosted.org/packages/23/13/bce4384d9f8f4989f1a9599c71b7a2d877462e5fd7175e1f69b398f729f4/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a358a32dd3ae50e933347889b6af9a1bdf207ba5d1a3f34e1a38cd3540e6733", size = 382767, upload-time = "2025-10-22T22:23:21.787Z" }, + { url = "https://files.pythonhosted.org/packages/23/e1/579512b2d89a77c64ccef5a0bc46a6ef7f72ae0cf03d4b26dcd52e57ee0a/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e80848a71c78aa328fefaba9c244d588a342c8e03bda518447b624ea64d1ff56", size = 517585, upload-time = "2025-10-22T22:23:23.699Z" }, + { url = "https://files.pythonhosted.org/packages/62/3c/ca704b8d324a2591b0b0adcfcaadf9c862375b11f2f667ac03c61b4fd0a6/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f586db2e209d54fe177e58e0bc4946bea5fb0102f150b1b2f13de03e1f0976f8", size = 399828, upload-time = "2025-10-22T22:23:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/da/37/e84283b9e897e3adc46b4c88bb3f6ec92a43bd4d2f7ef5b13459963b2e9c/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ae8ee156d6b586e4292491e885d41483136ab994e719a13458055bec14cf370", size = 375509, upload-time = "2025-10-22T22:23:27.32Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c2/a980beab869d86258bf76ec42dec778ba98151f253a952b02fe36d72b29c/rpds_py-0.28.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a805e9b3973f7e27f7cab63a6b4f61d90f2e5557cff73b6e97cd5b8540276d3d", size = 392014, upload-time = "2025-10-22T22:23:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/da/b5/b1d3c5f9d3fa5aeef74265f9c64de3c34a0d6d5cd3c81c8b17d5c8f10ed4/rpds_py-0.28.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5d3fd16b6dc89c73a4da0b4ac8b12a7ecc75b2864b95c9e5afed8003cb50a728", size = 402410, upload-time = "2025-10-22T22:23:31.14Z" }, + { url = "https://files.pythonhosted.org/packages/74/ae/cab05ff08dfcc052afc73dcb38cbc765ffc86f94e966f3924cd17492293c/rpds_py-0.28.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6796079e5d24fdaba6d49bda28e2c47347e89834678f2bc2c1b4fc1489c0fb01", size = 553593, upload-time = "2025-10-22T22:23:32.834Z" }, + { url = "https://files.pythonhosted.org/packages/70/80/50d5706ea2a9bfc9e9c5f401d91879e7c790c619969369800cde202da214/rpds_py-0.28.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:76500820c2af232435cbe215e3324c75b950a027134e044423f59f5b9a1ba515", size = 576925, upload-time = "2025-10-22T22:23:34.47Z" }, + { url = "https://files.pythonhosted.org/packages/ab/12/85a57d7a5855a3b188d024b099fd09c90db55d32a03626d0ed16352413ff/rpds_py-0.28.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bbdc5640900a7dbf9dd707fe6388972f5bbd883633eb68b76591044cfe346f7e", size = 542444, upload-time = "2025-10-22T22:23:36.093Z" }, + { url = "https://files.pythonhosted.org/packages/6c/65/10643fb50179509150eb94d558e8837c57ca8b9adc04bd07b98e57b48f8c/rpds_py-0.28.0-cp314-cp314-win32.whl", hash = "sha256:adc8aa88486857d2b35d75f0640b949759f79dc105f50aa2c27816b2e0dd749f", size = 207968, upload-time = "2025-10-22T22:23:37.638Z" }, + { url = "https://files.pythonhosted.org/packages/b4/84/0c11fe4d9aaea784ff4652499e365963222481ac647bcd0251c88af646eb/rpds_py-0.28.0-cp314-cp314-win_amd64.whl", hash = "sha256:66e6fa8e075b58946e76a78e69e1a124a21d9a48a5b4766d15ba5b06869d1fa1", size = 218876, upload-time = "2025-10-22T22:23:39.179Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e0/3ab3b86ded7bb18478392dc3e835f7b754cd446f62f3fc96f4fe2aca78f6/rpds_py-0.28.0-cp314-cp314-win_arm64.whl", hash = "sha256:a6fe887c2c5c59413353b7c0caff25d0e566623501ccfff88957fa438a69377d", size = 212506, upload-time = "2025-10-22T22:23:40.755Z" }, + { url = "https://files.pythonhosted.org/packages/51/ec/d5681bb425226c3501eab50fc30e9d275de20c131869322c8a1729c7b61c/rpds_py-0.28.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7a69df082db13c7070f7b8b1f155fa9e687f1d6aefb7b0e3f7231653b79a067b", size = 355433, upload-time = "2025-10-22T22:23:42.259Z" }, + { url = "https://files.pythonhosted.org/packages/be/ec/568c5e689e1cfb1ea8b875cffea3649260955f677fdd7ddc6176902d04cd/rpds_py-0.28.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b1cde22f2c30ebb049a9e74c5374994157b9b70a16147d332f89c99c5960737a", size = 342601, upload-time = "2025-10-22T22:23:44.372Z" }, + { url = "https://files.pythonhosted.org/packages/32/fe/51ada84d1d2a1d9d8f2c902cfddd0133b4a5eb543196ab5161d1c07ed2ad/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5338742f6ba7a51012ea470bd4dc600a8c713c0c72adaa0977a1b1f4327d6592", size = 372039, upload-time = "2025-10-22T22:23:46.025Z" }, + { url = "https://files.pythonhosted.org/packages/07/c1/60144a2f2620abade1a78e0d91b298ac2d9b91bc08864493fa00451ef06e/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1460ebde1bcf6d496d80b191d854adedcc619f84ff17dc1c6d550f58c9efbba", size = 382407, upload-time = "2025-10-22T22:23:48.098Z" }, + { url = "https://files.pythonhosted.org/packages/45/ed/091a7bbdcf4038a60a461df50bc4c82a7ed6d5d5e27649aab61771c17585/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e3eb248f2feba84c692579257a043a7699e28a77d86c77b032c1d9fbb3f0219c", size = 518172, upload-time = "2025-10-22T22:23:50.16Z" }, + { url = "https://files.pythonhosted.org/packages/54/dd/02cc90c2fd9c2ef8016fd7813bfacd1c3a1325633ec8f244c47b449fc868/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3bbba5def70b16cd1c1d7255666aad3b290fbf8d0fe7f9f91abafb73611a91", size = 399020, upload-time = "2025-10-22T22:23:51.81Z" }, + { url = "https://files.pythonhosted.org/packages/ab/81/5d98cc0329bbb911ccecd0b9e19fbf7f3a5de8094b4cda5e71013b2dd77e/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3114f4db69ac5a1f32e7e4d1cbbe7c8f9cf8217f78e6e002cedf2d54c2a548ed", size = 377451, upload-time = "2025-10-22T22:23:53.711Z" }, + { url = "https://files.pythonhosted.org/packages/b4/07/4d5bcd49e3dfed2d38e2dcb49ab6615f2ceb9f89f5a372c46dbdebb4e028/rpds_py-0.28.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:4b0cb8a906b1a0196b863d460c0222fb8ad0f34041568da5620f9799b83ccf0b", size = 390355, upload-time = "2025-10-22T22:23:55.299Z" }, + { url = "https://files.pythonhosted.org/packages/3f/79/9f14ba9010fee74e4f40bf578735cfcbb91d2e642ffd1abe429bb0b96364/rpds_py-0.28.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf681ac76a60b667106141e11a92a3330890257e6f559ca995fbb5265160b56e", size = 403146, upload-time = "2025-10-22T22:23:56.929Z" }, + { url = "https://files.pythonhosted.org/packages/39/4c/f08283a82ac141331a83a40652830edd3a4a92c34e07e2bbe00baaea2f5f/rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1e8ee6413cfc677ce8898d9cde18cc3a60fc2ba756b0dec5b71eb6eb21c49fa1", size = 552656, upload-time = "2025-10-22T22:23:58.62Z" }, + { url = "https://files.pythonhosted.org/packages/61/47/d922fc0666f0dd8e40c33990d055f4cc6ecff6f502c2d01569dbed830f9b/rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b3072b16904d0b5572a15eb9d31c1954e0d3227a585fc1351aa9878729099d6c", size = 576782, upload-time = "2025-10-22T22:24:00.312Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0c/5bafdd8ccf6aa9d3bfc630cfece457ff5b581af24f46a9f3590f790e3df2/rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b670c30fd87a6aec281c3c9896d3bae4b205fd75d79d06dc87c2503717e46092", size = 544671, upload-time = "2025-10-22T22:24:02.297Z" }, + { url = "https://files.pythonhosted.org/packages/2c/37/dcc5d8397caa924988693519069d0beea077a866128719351a4ad95e82fc/rpds_py-0.28.0-cp314-cp314t-win32.whl", hash = "sha256:8014045a15b4d2b3476f0a287fcc93d4f823472d7d1308d47884ecac9e612be3", size = 205749, upload-time = "2025-10-22T22:24:03.848Z" }, + { url = "https://files.pythonhosted.org/packages/d7/69/64d43b21a10d72b45939a28961216baeb721cc2a430f5f7c3bfa21659a53/rpds_py-0.28.0-cp314-cp314t-win_amd64.whl", hash = "sha256:7a4e59c90d9c27c561eb3160323634a9ff50b04e4f7820600a2beb0ac90db578", size = 216233, upload-time = "2025-10-22T22:24:05.471Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bc/b43f2ea505f28119bd551ae75f70be0c803d2dbcd37c1b3734909e40620b/rpds_py-0.28.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f5e7101145427087e493b9c9b959da68d357c28c562792300dd21a095118ed16", size = 363913, upload-time = "2025-10-22T22:24:07.129Z" }, + { url = "https://files.pythonhosted.org/packages/28/f2/db318195d324c89a2c57dc5195058cbadd71b20d220685c5bd1da79ee7fe/rpds_py-0.28.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:31eb671150b9c62409a888850aaa8e6533635704fe2b78335f9aaf7ff81eec4d", size = 350452, upload-time = "2025-10-22T22:24:08.754Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f2/1391c819b8573a4898cedd6b6c5ec5bc370ce59e5d6bdcebe3c9c1db4588/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48b55c1f64482f7d8bd39942f376bfdf2f6aec637ee8c805b5041e14eeb771db", size = 380957, upload-time = "2025-10-22T22:24:10.826Z" }, + { url = "https://files.pythonhosted.org/packages/5a/5c/e5de68ee7eb7248fce93269833d1b329a196d736aefb1a7481d1e99d1222/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24743a7b372e9a76171f6b69c01aedf927e8ac3e16c474d9fe20d552a8cb45c7", size = 391919, upload-time = "2025-10-22T22:24:12.559Z" }, + { url = "https://files.pythonhosted.org/packages/fb/4f/2376336112cbfeb122fd435d608ad8d5041b3aed176f85a3cb32c262eb80/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:389c29045ee8bbb1627ea190b4976a310a295559eaf9f1464a1a6f2bf84dde78", size = 528541, upload-time = "2025-10-22T22:24:14.197Z" }, + { url = "https://files.pythonhosted.org/packages/68/53/5ae232e795853dd20da7225c5dd13a09c0a905b1a655e92bdf8d78a99fd9/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23690b5827e643150cf7b49569679ec13fe9a610a15949ed48b85eb7f98f34ec", size = 405629, upload-time = "2025-10-22T22:24:16.001Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2d/351a3b852b683ca9b6b8b38ed9efb2347596973849ba6c3a0e99877c10aa/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f0c9266c26580e7243ad0d72fc3e01d6b33866cfab5084a6da7576bcf1c4f72", size = 384123, upload-time = "2025-10-22T22:24:17.585Z" }, + { url = "https://files.pythonhosted.org/packages/e0/15/870804daa00202728cc91cb8e2385fa9f1f4eb49857c49cfce89e304eae6/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4c6c4db5d73d179746951486df97fd25e92396be07fc29ee8ff9a8f5afbdfb27", size = 400923, upload-time = "2025-10-22T22:24:19.512Z" }, + { url = "https://files.pythonhosted.org/packages/53/25/3706b83c125fa2a0bccceac951de3f76631f6bd0ee4d02a0ed780712ef1b/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3b695a8fa799dd2cfdb4804b37096c5f6dba1ac7f48a7fbf6d0485bcd060316", size = 413767, upload-time = "2025-10-22T22:24:21.316Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f9/ce43dbe62767432273ed2584cef71fef8411bddfb64125d4c19128015018/rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:6aa1bfce3f83baf00d9c5fcdbba93a3ab79958b4c7d7d1f55e7fe68c20e63912", size = 561530, upload-time = "2025-10-22T22:24:22.958Z" }, + { url = "https://files.pythonhosted.org/packages/46/c9/ffe77999ed8f81e30713dd38fd9ecaa161f28ec48bb80fa1cd9118399c27/rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:7b0f9dceb221792b3ee6acb5438eb1f02b0cb2c247796a72b016dcc92c6de829", size = 585453, upload-time = "2025-10-22T22:24:24.779Z" }, + { url = "https://files.pythonhosted.org/packages/ed/d2/4a73b18821fd4669762c855fd1f4e80ceb66fb72d71162d14da58444a763/rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5d0145edba8abd3db0ab22b5300c99dc152f5c9021fab861be0f0544dc3cbc5f", size = 552199, upload-time = "2025-10-22T22:24:26.54Z" }, +] + +[[package]] +name = "setuptools" +version = "80.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, ] [[package]] @@ -349,21 +476,88 @@ wheels = [ ] [[package]] -name = "types-python-dateutil" -version = "2.9.0.20250708" +name = "tomli" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c9/95/6bdde7607da2e1e99ec1c1672a759d42f26644bbacf939916e086db34870/types_python_dateutil-2.9.0.20250708.tar.gz", hash = "sha256:ccdbd75dab2d6c9696c350579f34cffe2c281e4c5f27a585b2a2438dd1d5c8ab", size = 15834, upload-time = "2025-07-08T03:14:03.382Z" } +sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/52/43e70a8e57fefb172c22a21000b03ebcc15e47e97f5cb8495b9c2832efb4/types_python_dateutil-2.9.0.20250708-py3-none-any.whl", hash = "sha256:4d6d0cc1cc4d24a2dc3816024e502564094497b713f7befda4d5bc7a8e3fd21f", size = 17724, upload-time = "2025-07-08T03:14:02.593Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, + { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, + { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, + { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, + { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, + { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, + { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, + { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, + { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, + { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, + { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, + { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, + { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, + { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, + { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, + { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, + { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, + { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, + { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, +] + +[[package]] +name = "twisted" +version = "25.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "automat" }, + { name = "constantly" }, + { name = "hyperlink" }, + { name = "incremental" }, + { name = "typing-extensions" }, + { name = "zope-interface" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/13/0f/82716ed849bf7ea4984c21385597c949944f0f9b428b5710f79d0afc084d/twisted-25.5.0.tar.gz", hash = "sha256:1deb272358cb6be1e3e8fc6f9c8b36f78eb0fa7c2233d2dbe11ec6fee04ea316", size = 3545725, upload-time = "2025-06-07T09:52:24.858Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/66/ab7efd8941f0bc7b2bd555b0f0471bff77df4c88e0cc31120c82737fec77/twisted-25.5.0-py3-none-any.whl", hash = "sha256:8559f654d01a54a8c3efe66d533d43f383531ebf8d81d9f9ab4769d91ca15df7", size = 3204767, upload-time = "2025-06-07T09:52:21.428Z" }, ] [[package]] name = "typing-extensions" -version = "4.14.1" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "tzdata" +version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] [[package]] @@ -375,6 +569,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, ] +[[package]] +name = "virtue" +version = "2025.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "click" }, + { name = "colorama" }, + { name = "pyrsistent" }, + { name = "twisted" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/93/be/12ac287b9a2d8af43cc5b1e2b23be25c4c1d32b1c0ee1db162ed7c592023/virtue-2025.7.1.tar.gz", hash = "sha256:7af7e000de8629279f7dcdad43a851a833aa5019c02b277e737d544600ca319b", size = 34972, upload-time = "2025-07-01T15:39:15.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/7d/699d5077881131666596ce3eafd33a23c0228198f465d50ea42713b9f8af/virtue-2025.7.1-py3-none-any.whl", hash = "sha256:37c55eb88e8ac74041389cc07a7191cac0584f9ee8a76df36842ea367cd6ffee", size = 22815, upload-time = "2025-07-01T15:39:14.028Z" }, +] + [[package]] name = "webcolors" version = "24.11.1" @@ -383,3 +593,35 @@ sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb5852184 wheels = [ { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" }, ] + +[[package]] +name = "zope-interface" +version = "8.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/3a/7fcf02178b8fad0a51e67e32765cd039ae505d054d744d76b8c2bbcba5ba/zope_interface-8.0.1.tar.gz", hash = "sha256:eba5610d042c3704a48222f7f7c6ab5b243ed26f917e2bc69379456b115e02d1", size = 253746, upload-time = "2025-09-25T05:55:51.285Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/e5/ffef169d17b92c6236b3b18b890c0ce73502f3cbd5b6532ff20d412d94a3/zope_interface-8.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fd7195081b8637eeed8d73e4d183b07199a1dc738fb28b3de6666b1b55662570", size = 207364, upload-time = "2025-09-25T05:58:50.262Z" }, + { url = "https://files.pythonhosted.org/packages/35/b6/87aca626c09af829d3a32011599d6e18864bc8daa0ad3a7e258f3d7f8bcf/zope_interface-8.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f7c4bc4021108847bce763673ce70d0716b08dfc2ba9889e7bad46ac2b3bb924", size = 207901, upload-time = "2025-09-25T05:58:51.74Z" }, + { url = "https://files.pythonhosted.org/packages/d8/c1/eec33cc9f847ebeb0bc6234d7d45fe3fc0a6fe8fc5b5e6be0442bd2c684d/zope_interface-8.0.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:758803806b962f32c87b31bb18c298b022965ba34fe532163831cc39118c24ab", size = 249358, upload-time = "2025-09-25T05:58:16.979Z" }, + { url = "https://files.pythonhosted.org/packages/58/7d/1e3476a1ef0175559bd8492dc7bb921ad0df5b73861d764b1f824ad5484a/zope_interface-8.0.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f8e88f35f86bbe8243cad4b2972deef0fdfca0a0723455abbebdc83bbab96b69", size = 254475, upload-time = "2025-09-25T05:58:10.032Z" }, + { url = "https://files.pythonhosted.org/packages/bc/67/ba5ea98ff23f723c5cbe7db7409f2e43c9fe2df1ced67881443c01e64478/zope_interface-8.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7844765695937d9b0d83211220b72e2cf6ac81a08608ad2b58f2c094af498d83", size = 254913, upload-time = "2025-09-25T06:26:22.263Z" }, + { url = "https://files.pythonhosted.org/packages/2b/a7/b1b8b6c13fba955c043cdee409953ee85f652b106493e2e931a84f95c1aa/zope_interface-8.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:64fa7b206dd9669f29d5c1241a768bebe8ab1e8a4b63ee16491f041e058c09d0", size = 211753, upload-time = "2025-09-25T05:59:00.561Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2f/c10c739bcb9b072090c97c2e08533777497190daa19d190d72b4cce9c7cb/zope_interface-8.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4bd01022d2e1bce4a4a4ed9549edb25393c92e607d7daa6deff843f1f68b479d", size = 207903, upload-time = "2025-09-25T05:58:21.671Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e1/9845ac3697f108d9a1af6912170c59a23732090bbfb35955fe77e5544955/zope_interface-8.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:29be8db8b712d94f1c05e24ea230a879271d787205ba1c9a6100d1d81f06c69a", size = 208345, upload-time = "2025-09-25T05:58:24.217Z" }, + { url = "https://files.pythonhosted.org/packages/f2/49/6573bc8b841cfab18e80c8e8259f1abdbbf716140011370de30231be79ad/zope_interface-8.0.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:51ae1b856565b30455b7879fdf0a56a88763b401d3f814fa9f9542d7410dbd7e", size = 255027, upload-time = "2025-09-25T05:58:19.975Z" }, + { url = "https://files.pythonhosted.org/packages/e2/fd/908b0fd4b1ab6e412dfac9bd2b606f2893ef9ba3dd36d643f5e5b94c57b3/zope_interface-8.0.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d2e7596149cb1acd1d4d41b9f8fe2ffc0e9e29e2e91d026311814181d0d9efaf", size = 259800, upload-time = "2025-09-25T05:58:11.487Z" }, + { url = "https://files.pythonhosted.org/packages/dc/78/8419a2b4e88410520ed4b7f93bbd25a6d4ae66c4e2b131320f2b90f43077/zope_interface-8.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b2737c11c34fb9128816759864752d007ec4f987b571c934c30723ed881a7a4f", size = 260978, upload-time = "2025-09-25T06:26:24.483Z" }, + { url = "https://files.pythonhosted.org/packages/e5/90/caf68152c292f1810e2bd3acd2177badf08a740aa8a348714617d6c9ad0b/zope_interface-8.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:cf66e4bf731aa7e0ced855bb3670e8cda772f6515a475c6a107bad5cb6604103", size = 212155, upload-time = "2025-09-25T05:59:40.318Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/0f08713ddda834c428ebf97b2a7fd8dea50c0100065a8955924dbd94dae8/zope_interface-8.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:115f27c1cc95ce7a517d960ef381beedb0a7ce9489645e80b9ab3cbf8a78799c", size = 208609, upload-time = "2025-09-25T05:58:53.698Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5e/d423045f54dc81e0991ec655041e7a0eccf6b2642535839dd364b35f4d7f/zope_interface-8.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af655c573b84e3cb6a4f6fd3fbe04e4dc91c63c6b6f99019b3713ef964e589bc", size = 208797, upload-time = "2025-09-25T05:58:56.258Z" }, + { url = "https://files.pythonhosted.org/packages/c6/43/39d4bb3f7a80ebd261446792493cfa4e198badd47107224f5b6fe1997ad9/zope_interface-8.0.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:23f82ef9b2d5370750cc1bf883c3b94c33d098ce08557922a3fbc7ff3b63dfe1", size = 259242, upload-time = "2025-09-25T05:58:21.602Z" }, + { url = "https://files.pythonhosted.org/packages/da/29/49effcff64ef30731e35520a152a9dfcafec86cf114b4c2aff942e8264ba/zope_interface-8.0.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35a1565d5244997f2e629c5c68715b3d9d9036e8df23c4068b08d9316dcb2822", size = 264696, upload-time = "2025-09-25T05:58:13.351Z" }, + { url = "https://files.pythonhosted.org/packages/c7/39/b947673ec9a258eeaa20208dd2f6127d9fbb3e5071272a674ebe02063a78/zope_interface-8.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:029ea1db7e855a475bf88d9910baab4e94d007a054810e9007ac037a91c67c6f", size = 264229, upload-time = "2025-09-25T06:26:26.226Z" }, + { url = "https://files.pythonhosted.org/packages/8f/ee/eed6efd1fc3788d1bef7a814e0592d8173b7fe601c699b935009df035fc2/zope_interface-8.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0beb3e7f7dc153944076fcaf717a935f68d39efa9fce96ec97bafcc0c2ea6cab", size = 212270, upload-time = "2025-09-25T05:58:53.584Z" }, + { url = "https://files.pythonhosted.org/packages/5f/dc/3c12fca01c910c793d636ffe9c0984e0646abaf804e44552070228ed0ede/zope_interface-8.0.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:c7cc027fc5c61c5d69e5080c30b66382f454f43dc379c463a38e78a9c6bab71a", size = 208992, upload-time = "2025-09-25T05:58:40.712Z" }, + { url = "https://files.pythonhosted.org/packages/46/71/6127b7282a3e380ca927ab2b40778a9c97935a4a57a2656dadc312db5f30/zope_interface-8.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fcf9097ff3003b7662299f1c25145e15260ec2a27f9a9e69461a585d79ca8552", size = 209051, upload-time = "2025-09-25T05:58:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/56/86/4387a9f951ee18b0e41fda77da77d59c33e59f04660578e2bad688703e64/zope_interface-8.0.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6d965347dd1fb9e9a53aa852d4ded46b41ca670d517fd54e733a6b6a4d0561c2", size = 259223, upload-time = "2025-09-25T05:58:23.191Z" }, + { url = "https://files.pythonhosted.org/packages/61/08/ce60a114466abc067c68ed41e2550c655f551468ae17b4b17ea360090146/zope_interface-8.0.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9a3b8bb77a4b89427a87d1e9eb969ab05e38e6b4a338a9de10f6df23c33ec3c2", size = 264690, upload-time = "2025-09-25T05:58:15.052Z" }, + { url = "https://files.pythonhosted.org/packages/36/9a/62a9ba3a919594605a07c34eee3068659bbd648e2fa0c4a86d876810b674/zope_interface-8.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:87e6b089002c43231fb9afec89268391bcc7a3b66e76e269ffde19a8112fb8d5", size = 264201, upload-time = "2025-09-25T06:26:27.797Z" }, + { url = "https://files.pythonhosted.org/packages/da/06/8fe88bd7edef60566d21ef5caca1034e10f6b87441ea85de4bbf9ea74768/zope_interface-8.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:64a43f5280aa770cbafd0307cb3d1ff430e2a1001774e8ceb40787abe4bb6658", size = 212273, upload-time = "2025-09-25T06:00:25.398Z" }, +] From d6e90f8adfb43eb8e82e7dac522ac2d48d8d0d27 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 24 Oct 2025 17:05:27 -0400 Subject: [PATCH 164/212] Update requirements. --- docs/requirements.txt | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index cdd004539..bc2214ea5 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,26 +1,28 @@ # This file was autogenerated by uv via the following command: # uv pip compile --output-file /Users/julian/Development/jsonschema/docs/requirements.txt docs/requirements.in +accessible-pygments==0.0.5 + # via furo alabaster==1.0.0 # via sphinx -astroid==3.3.10 +astroid==4.0.1 # via sphinx-autoapi -attrs==25.3.0 +attrs==25.4.0 # via # jsonschema # referencing babel==2.17.0 # via sphinx -beautifulsoup4==4.13.4 +beautifulsoup4==4.14.2 # via furo -certifi==2025.6.15 +certifi==2025.10.5 # via requests -charset-normalizer==3.4.2 +charset-normalizer==3.4.4 # via requests docutils==0.21.2 # via sphinx -furo==2024.8.6 +furo==2025.9.25 # via -r docs/requirements.in -idna==3.10 +idna==3.11 # via requests imagesize==1.4.1 # via sphinx @@ -30,41 +32,42 @@ jinja2==3.1.6 # sphinx-autoapi jsonschema @ file:. # via -r docs/requirements.in -jsonschema-specifications==2025.4.1 +jsonschema-specifications==2025.9.1 # via jsonschema -lxml==6.0.0 +lxml==6.0.2 # via # -r docs/requirements.in # sphinx-json-schema-spec -markupsafe==3.0.2 +markupsafe==3.0.3 # via jinja2 packaging==25.0 # via sphinx -pyenchant==3.2.2 +pyenchant==3.3.0 # via sphinxcontrib-spelling pygments==2.19.2 # via + # accessible-pygments # furo # sphinx -pyyaml==6.0.2 +pyyaml==6.0.3 # via sphinx-autoapi -referencing==0.36.2 +referencing==0.37.0 # via # jsonschema # jsonschema-specifications -requests==2.32.4 +requests==2.32.5 # via # sphinx # sphinxcontrib-spelling roman-numerals-py==3.1.0 # via sphinx -rpds-py==0.25.1 +rpds-py==0.28.0 # via # jsonschema # referencing snowballstemmer==3.0.1 # via sphinx -soupsieve==2.7 +soupsieve==2.8 # via beautifulsoup4 sphinx==8.2.3 # via @@ -77,9 +80,9 @@ sphinx==8.2.3 # sphinx-json-schema-spec # sphinxcontrib-spelling # sphinxext-opengraph -sphinx-autoapi==3.6.0 +sphinx-autoapi==3.6.1 # via -r docs/requirements.in -sphinx-autodoc-typehints==3.2.0 +sphinx-autodoc-typehints==3.5.2 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo @@ -101,9 +104,9 @@ sphinxcontrib-serializinghtml==2.0.0 # via sphinx sphinxcontrib-spelling==8.0.1 # via -r docs/requirements.in -sphinxext-opengraph==0.10.0 +sphinxext-opengraph==0.13.0 # via -r docs/requirements.in -typing-extensions==4.14.0 +typing-extensions==4.15.0 # via beautifulsoup4 urllib3==2.5.0 # via requests From 0f816c6532cbac8902129f9ea4649415a6e71c04 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 24 Oct 2025 17:21:30 -0400 Subject: [PATCH 165/212] Try telling RTD to use 3.13. --- .readthedocs.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 31043883e..0cdedb08f 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,11 +1,11 @@ version: 2 build: - os: ubuntu-22.04 + os: ubuntu-24.04 apt_packages: - inkscape tools: - python: "3.11" + python: "3.13" sphinx: builder: dirhtml From c04dd7d3bff26083f0b22fc6bcc95f2d6b40f888 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 24 Oct 2025 18:54:35 -0400 Subject: [PATCH 166/212] Remove Win3.14 testing envs until we figure out why they don't work. The test failure is incomprehensible on its own. --- .github/workflows/ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 487735de6..d83b62716 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,6 +73,18 @@ jobs: noxenv: "docs(spelling)" - os: windows-latest noxenv: "docs(style)" + - os: windows-latest + noxenv: "tests-3.14(no-extras)" + - os: windows-latest + noxenv: "tests-3.14(format)" + - os: windows-latest + noxenv: "tests-3.14(format-nongpl)" + - os: windows-latest + noxenv: "tests-3.14t(no-extras)" + - os: windows-latest + noxenv: "tests-3.14t(format)" + - os: windows-latest + noxenv: "tests-3.14t(format-nongpl)" steps: - uses: actions/checkout@v5 From 0798cd7a59caea669e2de2ecac9c6e2dfcb57f6d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 24 Oct 2025 19:11:52 -0400 Subject: [PATCH 167/212] zizmor fixes. --- .github/dependabot.yml | 4 ++++ .github/workflows/ci.yml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e910012b3..efebeb25d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,8 +4,12 @@ updates: directory: "/" schedule: interval: "weekly" + cooldown: + default-days: 7 - package-ecosystem: "pip" directory: "/docs" schedule: interval: "weekly" + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 732359f00..b6706ea8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,7 +115,7 @@ jobs: - name: Set up uv uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 with: - enable-cache: true + enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - name: Run nox run: uvx nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }} # zizmor: ignore[template-injection] @@ -139,7 +139,7 @@ jobs: - name: Set up uv uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 with: - enable-cache: true + enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - name: Build our distributions run: uv run --frozen --with 'build[uv]' -m build --installer=uv From 6c311893ebf5a66e6f032076359a49ab81ceac25 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 18:12:14 +0000 Subject: [PATCH 168/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.1 → v0.14.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.1...v0.14.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19a98ef48..a25f4f44f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.1" + rev: "v0.14.2" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 9f735494696c33e70bb1865aed95eb9813b0dba2 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Oct 2025 09:34:14 -0400 Subject: [PATCH 169/212] Bump the minimum rpds.py version. Bumps to one that supports all Python versions we support (i.e. specifically 3.14). Closes: #1426 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 213f89bcd..acc243121 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ dependencies = [ "attrs>=22.2.0", "jsonschema-specifications>=2023.03.6", "referencing>=0.28.4", - "rpds-py>=0.7.1", + "rpds-py>=0.25.0", ] [project.optional-dependencies] From c84134b41ef41a8355a4d929b68bad18059ed4cc Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Oct 2025 11:36:12 -0400 Subject: [PATCH 170/212] Bump the uv lockfile. --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index e6271a86c..6b3080096 100644 --- a/uv.lock +++ b/uv.lock @@ -196,7 +196,7 @@ requires-dist = [ { name = "rfc3986-validator", marker = "extra == 'format-nongpl'", specifier = ">0.1.0" }, { name = "rfc3987", marker = "extra == 'format'" }, { name = "rfc3987-syntax", marker = "extra == 'format-nongpl'", specifier = ">=1.1.0" }, - { name = "rpds-py", specifier = ">=0.7.1" }, + { name = "rpds-py", specifier = ">=0.25.0" }, { name = "uri-template", marker = "extra == 'format'" }, { name = "uri-template", marker = "extra == 'format-nongpl'" }, { name = "webcolors", marker = "extra == 'format'", specifier = ">=1.11" }, From 7710cd6cc56ae7cd0688f0581706e3af3939a57d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 31 Oct 2025 11:36:26 -0400 Subject: [PATCH 171/212] Allow the benchmark noxenv to run against any installable. --- noxfile.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index dad6cd562..9f0964d46 100644 --- a/noxfile.py +++ b/noxfile.py @@ -229,6 +229,7 @@ def docs_style(session): @session(default=False) +@nox.parametrize("installable", INSTALLABLE) @nox.parametrize( "benchmark", [ @@ -236,11 +237,11 @@ def docs_style(session): for each in BENCHMARKS.glob("[!_]*.py") ], ) -def bench(session, benchmark): +def bench(session, installable, benchmark): """ Run a performance benchmark. """ - session.install("pyperf", f"{ROOT}[format]") + session.install("pyperf", installable) tmpdir = Path(session.create_tmp()) output = tmpdir / f"bench-{benchmark}.json" session.run("python", BENCHMARKS / f"{benchmark}.py", "--output", output) From 429c81e89a7503f379e98dc3610bd386c3083822 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Nov 2025 18:22:30 +0000 Subject: [PATCH 172/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.2 → v0.14.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.2...v0.14.3) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a25f4f44f..5913412c0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.2" + rev: "v0.14.3" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From f3fecd2492280d5f8edf5eb681aa65cfa4592ebc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 09:47:50 +0000 Subject: [PATCH 173/212] Bump astral-sh/setup-uv from 7.1.1 to 7.1.2 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.1.1 to 7.1.2. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/2ddd2b9cb38ad8efd50337e8ab201519a34c9f24...85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.1.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6706ea8c..1e0fd8bbf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 + uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -113,7 +113,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 + uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] @@ -137,7 +137,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 + uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 84542e0f2..9af890dc7 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@2ddd2b9cb38ad8efd50337e8ab201519a34c9f24 + uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 7ee35428585ddb563f36a169bcc09cc5c1039f8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 09:09:27 +0000 Subject: [PATCH 174/212] Bump softprops/action-gh-release from 2.4.1 to 2.4.2 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.4.1 to 2.4.2. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/6da8fa9354ddfdc4aeace5fc48d7f679b5214090...5be0e66d93ac7ed76da52eca8bb058f665c3a5fe) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 2.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6706ea8c..8e4f2254b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -149,7 +149,7 @@ jobs: uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 + uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe with: files: | dist/* From 437e6e387a587c384d171f65874fa2fbdc5f8374 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 18:18:25 +0000 Subject: [PATCH 175/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.3 → v0.14.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.3...v0.14.5) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5913412c0..fde7722de 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.3" + rev: "v0.14.5" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 568e1971be14d1ab7e6bc533d6dd1fb3cc564b08 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 18:28:34 +0000 Subject: [PATCH 176/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.5 → v0.14.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.5...v0.14.6) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fde7722de..cb67cf956 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.5" + rev: "v0.14.6" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 7bf5ede190e5122a57f7754d7ebcc09811c4461c Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 30 Nov 2025 11:19:08 -0500 Subject: [PATCH 177/212] Remove the (deprecated + dangerous) RTD docs preview. https://docs.readthedocs.com/platform/stable/visual-diff.html#show-build-overview-in-pull-requests is the replacement. (It's the only `pull_request_target`-using workflow here.) --- .github/workflows/documentation-links.yml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .github/workflows/documentation-links.yml diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml deleted file mode 100644 index 2e02d13cb..000000000 --- a/.github/workflows/documentation-links.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Read the Docs Pull Request Preview -on: - pull_request_target: # zizmor: ignore[dangerous-triggers] - types: - - opened - -permissions: - pull-requests: write - -jobs: - documentation-links: - runs-on: ubuntu-latest - steps: - - uses: readthedocs/actions/preview@b8bba1484329bda1a3abe986df7ebc80a8950333 - with: - project-slug: "python-jsonschema" From 4845cdf48f575f8e894373759ab63f2b1d479634 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sun, 30 Nov 2025 11:21:25 -0500 Subject: [PATCH 178/212] Update docs requirements. --- docs/requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index bc2214ea5..e2c149a72 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,7 +4,7 @@ accessible-pygments==0.0.5 # via furo alabaster==1.0.0 # via sphinx -astroid==4.0.1 +astroid==4.0.2 # via sphinx-autoapi attrs==25.4.0 # via @@ -12,9 +12,9 @@ attrs==25.4.0 # referencing babel==2.17.0 # via sphinx -beautifulsoup4==4.14.2 +beautifulsoup4==4.14.3 # via furo -certifi==2025.10.5 +certifi==2025.11.12 # via requests charset-normalizer==3.4.4 # via requests @@ -61,7 +61,7 @@ requests==2.32.5 # sphinxcontrib-spelling roman-numerals-py==3.1.0 # via sphinx -rpds-py==0.28.0 +rpds-py==0.29.0 # via # jsonschema # referencing @@ -102,7 +102,7 @@ sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx -sphinxcontrib-spelling==8.0.1 +sphinxcontrib-spelling==8.0.2 # via -r docs/requirements.in sphinxext-opengraph==0.13.0 # via -r docs/requirements.in From ec29676dd7a6c5b62b37f4870d49ae5b5c29f8b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 10:33:51 +0000 Subject: [PATCH 179/212] Bump astral-sh/setup-uv from 7.1.2 to 7.1.4 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.1.2 to 7.1.4. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41...1e862dfacbd1d6d858c55d9b792c756523627244) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.1.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96d4a550d..c143a7f93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -113,7 +113,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] @@ -137,7 +137,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 9af890dc7..7f4aef3fe 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 + uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 845636207e4ad45e9c0c475d471feaa30a99fd2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 10:34:02 +0000 Subject: [PATCH 180/212] Bump actions/checkout from 5 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96d4a550d..199755de4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: outputs: noxenvs: ${{ steps.noxenvs-matrix.outputs.noxenvs }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Set up uv @@ -87,7 +87,7 @@ jobs: noxenv: "tests-3.14t(format-nongpl)" steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: persist-credentials: false - name: Install dependencies @@ -132,7 +132,7 @@ jobs: id-token: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 9af890dc7..a1cae3e07 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false From 973018169c878ab3518fe2382896bfc15b6aba62 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 18:33:41 +0000 Subject: [PATCH 181/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.6 → v0.14.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.6...v0.14.7) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cb67cf956..08a46fb21 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.6" + rev: "v0.14.7" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From d51d916e3caf32b57a398dc269ab1eea2dbc5919 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 09:05:40 +0000 Subject: [PATCH 182/212] Bump softprops/action-gh-release from 2.4.2 to 2.5.0 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.4.2 to 2.5.0. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/5be0e66d93ac7ed76da52eca8bb058f665c3a5fe...a06a81a03ee405af7f2048a818ed3f03bbf83c7b) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 2.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 197c22cd1..5d0298f4f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -149,7 +149,7 @@ jobs: uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e - name: Create a GitHub Release if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') - uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe + uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b with: files: | dist/* From d9df1688426d6b2bb67a2c23ce0b6638ab962263 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 18:30:12 +0000 Subject: [PATCH 183/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.7 → v0.14.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.7...v0.14.8) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 08a46fb21..f44582376 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.7" + rev: "v0.14.8" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 8eeb602defae636e6ce78996e9faef922f79dd57 Mon Sep 17 00:00:00 2001 From: Simmo Saan Date: Thu, 11 Dec 2025 15:32:33 +0200 Subject: [PATCH 184/212] Document uuid format --- docs/validate.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/validate.rst b/docs/validate.rst index bc740e340..e8b79dbde 100644 --- a/docs/validate.rst +++ b/docs/validate.rst @@ -237,6 +237,7 @@ Checker Notes ``uri`` requires rfc3987_ or rfc3986-validator_ ``uri-reference`` requires rfc3987_ or rfc3986-validator_ ``uri-template`` requires uri-template_ +``uuid`` ========================= ==================== From b0f961af55d91455e807f083c4bd32c1090db9b1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 18:27:07 +0000 Subject: [PATCH 185/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.8 → v0.14.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.8...v0.14.9) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f44582376..22052c3f9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.8" + rev: "v0.14.9" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 2818efb4fa446ed4fa7815b4e09a7b4b7c633852 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 20 Dec 2025 18:35:28 +0200 Subject: [PATCH 186/212] Apache-2.0 -> nongpl --- noxfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/noxfile.py b/noxfile.py index 9f0964d46..0817c2389 100644 --- a/noxfile.py +++ b/noxfile.py @@ -28,6 +28,7 @@ NONGPL_LICENSES = [ "Apache Software License", + "Apache-2.0", "BSD License", "ISC License (ISCL)", "MIT", From 1f7c9fbd01d9c2f8ddd98065324062f7e122dbe1 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 20 Dec 2025 18:54:39 +0200 Subject: [PATCH 187/212] Partially update docs requirements. Sphinx 9 seems to have some issues which are initially not easy to even understand what they're trying to indicate... --- docs/requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index e2c149a72..2ead6c39e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -20,7 +20,7 @@ charset-normalizer==3.4.4 # via requests docutils==0.21.2 # via sphinx -furo==2025.9.25 +furo==2025.12.19 # via -r docs/requirements.in idna==3.11 # via requests @@ -59,15 +59,15 @@ requests==2.32.5 # via # sphinx # sphinxcontrib-spelling -roman-numerals-py==3.1.0 +roman-numerals==4.1.0 # via sphinx -rpds-py==0.29.0 +rpds-py==0.30.0 # via # jsonschema # referencing snowballstemmer==3.0.1 # via sphinx -soupsieve==2.8 +soupsieve==2.8.1 # via beautifulsoup4 sphinx==8.2.3 # via @@ -108,5 +108,5 @@ sphinxext-opengraph==0.13.0 # via -r docs/requirements.in typing-extensions==4.15.0 # via beautifulsoup4 -urllib3==2.5.0 +urllib3==2.6.2 # via requests From e54ce13fb590a5c17fb702431598a382de6e68f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 09:04:50 +0000 Subject: [PATCH 188/212] Bump astral-sh/setup-uv from 7.1.4 to 7.1.6 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.1.4 to 7.1.6. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/1e862dfacbd1d6d858c55d9b792c756523627244...681c641aba71e4a1c380be3ab5e12ad51f415867) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.1.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d0298f4f..b7c1aa124 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 + uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -113,7 +113,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 + uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] @@ -137,7 +137,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 + uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 427a7892a..fa4e4ab26 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@1e862dfacbd1d6d858c55d9b792c756523627244 + uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From e6bbbb7c5bcdb32a654572d17bfce264aefd1f9d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 18:14:55 +0000 Subject: [PATCH 189/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.9 → v0.14.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.9...v0.14.10) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 22052c3f9..f9573892e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.9" + rev: "v0.14.10" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From de9483f2027f3fc2fa765e03d1f582aa6d5d913e Mon Sep 17 00:00:00 2001 From: Padmashree S S Date: Wed, 7 Jan 2026 18:10:24 +0530 Subject: [PATCH 190/212] docs: Fix misleading comment in relevance function The comment in the relevance() function incorrectly suggested that -len(error.path) prefers 'deeper' errors. In reality, this logic prioritizes errors with shorter paths (higher up in the instance). Updated the comment to accurately reflect that shorter paths are preferred for general validation errors, which aligns with the actual code behavior and official documentation for best_match. Closes #1325 --- jsonschema/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index d955e356e..d89e17769 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -415,7 +415,7 @@ def by_relevance(weak=WEAK_MATCHES, strong=STRONG_MATCHES): def relevance(error): validator = error.validator return ( # prefer errors which are ... - -len(error.path), # 'deeper' and thereby more specific + -len(error.path), # 'higher up' (shorter path) and thereby more general error.path, # earlier (for sibling errors) validator not in weak, # for a non-low-priority keyword validator in strong, # for a high priority keyword From 739499edc33c007ff62180c9fef61dbf5480bb7b Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 7 Jan 2026 07:48:00 -0500 Subject: [PATCH 191/212] Update pre-commit hooks. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f9573892e..3f3d12e8e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.14.10" + rev: v0.14.10 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 6d28c13efbbd6cf136143fdbb18f79d4476091f6 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 7 Jan 2026 07:48:35 -0500 Subject: [PATCH 192/212] Update the lockfile. --- uv.lock | 348 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 177 insertions(+), 171 deletions(-) diff --git a/uv.lock b/uv.lock index 6b3080096..38908650c 100644 --- a/uv.lock +++ b/uv.lock @@ -35,14 +35,14 @@ wheels = [ [[package]] name = "click" -version = "8.3.0" +version = "8.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, ] [[package]] @@ -95,15 +95,15 @@ wheels = [ [[package]] name = "incremental" -version = "24.7.2" +version = "24.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "setuptools" }, + { name = "packaging" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/27/87/156b374ff6578062965afe30cc57627d35234369b3336cf244b240c8d8e6/incremental-24.7.2.tar.gz", hash = "sha256:fb4f1d47ee60efe87d4f6f0ebb5f70b9760db2b2574c59c8e8912be4ebd464c9", size = 28157, upload-time = "2024-07-29T20:03:55.441Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/3c/82e84109e02c492f382c711c58a3dd91badda6d746def81a1465f74dc9f5/incremental-24.11.0.tar.gz", hash = "sha256:87d3480dbb083c1d736222511a8cf380012a8176c2456d01ef483242abbbcf8c", size = 24000, upload-time = "2025-11-28T02:30:17.861Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/38/221e5b2ae676a3938c2c1919131410c342b6efc2baffeda395dd66eeca8f/incremental-24.7.2-py3-none-any.whl", hash = "sha256:8cb2c3431530bec48ad70513931a760f446ad6c25e8333ca5d95e24b0ed7b8fe", size = 20516, upload-time = "2024-07-29T20:03:53.677Z" }, + { url = "https://files.pythonhosted.org/packages/1d/55/0f4df2a44053867ea9cbea73fc588b03c55605cd695cee0a3d86f0029cb2/incremental-24.11.0-py3-none-any.whl", hash = "sha256:a34450716b1c4341fe6676a0598e88a39e04189f4dce5dc96f656e040baa10b3", size = 21109, upload-time = "2025-11-28T02:30:16.442Z" }, ] [[package]] @@ -224,11 +224,20 @@ wheels = [ [[package]] name = "lark" -version = "1.3.0" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/37/a13baf0135f348af608c667633cbe5d13aa2c5c15a56ae9ad3e6cba45ae3/lark-1.3.0.tar.gz", hash = "sha256:9a3839d0ca5e1faf7cfa3460e420e859b66bcbde05b634e73c369c8244c5fa48", size = 259551, upload-time = "2025-09-22T13:45:05.072Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/3e/1c6b43277de64fc3c0333b0e72ab7b52ddaaea205210d60d9b9f83c3d0c7/lark-1.3.0-py3-none-any.whl", hash = "sha256:80661f261fb2584a9828a097a2432efd575af27d20be0fd35d17f0fe37253831", size = 113002, upload-time = "2025-09-22T13:45:03.747Z" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] @@ -337,133 +346,124 @@ wheels = [ [[package]] name = "rpds-py" -version = "0.28.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/48/dc/95f074d43452b3ef5d06276696ece4b3b5d696e7c9ad7173c54b1390cd70/rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea", size = 27419, upload-time = "2025-10-22T22:24:29.327Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/82/f8/13bb772dc7cbf2c3c5b816febc34fa0cb2c64a08e0569869585684ce6631/rpds_py-0.28.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7b6013db815417eeb56b2d9d7324e64fcd4fa289caeee6e7a78b2e11fc9b438a", size = 362820, upload-time = "2025-10-22T22:21:15.074Z" }, - { url = "https://files.pythonhosted.org/packages/84/91/6acce964aab32469c3dbe792cb041a752d64739c534e9c493c701ef0c032/rpds_py-0.28.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a4c6b05c685c0c03f80dabaeb73e74218c49deea965ca63f76a752807397207", size = 348499, upload-time = "2025-10-22T22:21:17.658Z" }, - { url = "https://files.pythonhosted.org/packages/f1/93/c05bb1f4f5e0234db7c4917cb8dd5e2e0a9a7b26dc74b1b7bee3c9cfd477/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4794c6c3fbe8f9ac87699b131a1f26e7b4abcf6d828da46a3a52648c7930eba", size = 379356, upload-time = "2025-10-22T22:21:19.847Z" }, - { url = "https://files.pythonhosted.org/packages/5c/37/e292da436f0773e319753c567263427cdf6c645d30b44f09463ff8216cda/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2e8456b6ee5527112ff2354dd9087b030e3429e43a74f480d4a5ca79d269fd85", size = 390151, upload-time = "2025-10-22T22:21:21.569Z" }, - { url = "https://files.pythonhosted.org/packages/76/87/a4e3267131616e8faf10486dc00eaedf09bd61c87f01e5ef98e782ee06c9/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:beb880a9ca0a117415f241f66d56025c02037f7c4efc6fe59b5b8454f1eaa50d", size = 524831, upload-time = "2025-10-22T22:21:23.394Z" }, - { url = "https://files.pythonhosted.org/packages/e1/c8/4a4ca76f0befae9515da3fad11038f0fce44f6bb60b21fe9d9364dd51fb0/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6897bebb118c44b38c9cb62a178e09f1593c949391b9a1a6fe777ccab5934ee7", size = 404687, upload-time = "2025-10-22T22:21:25.201Z" }, - { url = "https://files.pythonhosted.org/packages/6a/65/118afe854424456beafbbebc6b34dcf6d72eae3a08b4632bc4220f8240d9/rpds_py-0.28.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1b553dd06e875249fd43efd727785efb57a53180e0fde321468222eabbeaafa", size = 382683, upload-time = "2025-10-22T22:21:26.536Z" }, - { url = "https://files.pythonhosted.org/packages/f7/bc/0625064041fb3a0c77ecc8878c0e8341b0ae27ad0f00cf8f2b57337a1e63/rpds_py-0.28.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:f0b2044fdddeea5b05df832e50d2a06fe61023acb44d76978e1b060206a8a476", size = 398927, upload-time = "2025-10-22T22:21:27.864Z" }, - { url = "https://files.pythonhosted.org/packages/5d/1a/fed7cf2f1ee8a5e4778f2054153f2cfcf517748875e2f5b21cf8907cd77d/rpds_py-0.28.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05cf1e74900e8da73fa08cc76c74a03345e5a3e37691d07cfe2092d7d8e27b04", size = 411590, upload-time = "2025-10-22T22:21:29.474Z" }, - { url = "https://files.pythonhosted.org/packages/c1/64/a8e0f67fa374a6c472dbb0afdaf1ef744724f165abb6899f20e2f1563137/rpds_py-0.28.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:efd489fec7c311dae25e94fe7eeda4b3d06be71c68f2cf2e8ef990ffcd2cd7e8", size = 559843, upload-time = "2025-10-22T22:21:30.917Z" }, - { url = "https://files.pythonhosted.org/packages/a9/ea/e10353f6d7c105be09b8135b72787a65919971ae0330ad97d87e4e199880/rpds_py-0.28.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ada7754a10faacd4f26067e62de52d6af93b6d9542f0df73c57b9771eb3ba9c4", size = 584188, upload-time = "2025-10-22T22:21:32.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/b0/a19743e0763caf0c89f6fc6ba6fbd9a353b24ffb4256a492420c5517da5a/rpds_py-0.28.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c2a34fd26588949e1e7977cfcbb17a9a42c948c100cab890c6d8d823f0586457", size = 550052, upload-time = "2025-10-22T22:21:34.702Z" }, - { url = "https://files.pythonhosted.org/packages/de/bc/ec2c004f6c7d6ab1e25dae875cdb1aee087c3ebed5b73712ed3000e3851a/rpds_py-0.28.0-cp310-cp310-win32.whl", hash = "sha256:f9174471d6920cbc5e82a7822de8dfd4dcea86eb828b04fc8c6519a77b0ee51e", size = 215110, upload-time = "2025-10-22T22:21:36.645Z" }, - { url = "https://files.pythonhosted.org/packages/6c/de/4ce8abf59674e17187023933547d2018363e8fc76ada4f1d4d22871ccb6e/rpds_py-0.28.0-cp310-cp310-win_amd64.whl", hash = "sha256:6e32dd207e2c4f8475257a3540ab8a93eff997abfa0a3fdb287cae0d6cd874b8", size = 223850, upload-time = "2025-10-22T22:21:38.006Z" }, - { url = "https://files.pythonhosted.org/packages/a6/34/058d0db5471c6be7bef82487ad5021ff8d1d1d27794be8730aad938649cf/rpds_py-0.28.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:03065002fd2e287725d95fbc69688e0c6daf6c6314ba38bdbaa3895418e09296", size = 362344, upload-time = "2025-10-22T22:21:39.713Z" }, - { url = "https://files.pythonhosted.org/packages/5d/67/9503f0ec8c055a0782880f300c50a2b8e5e72eb1f94dfc2053da527444dd/rpds_py-0.28.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28ea02215f262b6d078daec0b45344c89e161eab9526b0d898221d96fdda5f27", size = 348440, upload-time = "2025-10-22T22:21:41.056Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/94223ee9b32332a41d75b6f94b37b4ce3e93878a556fc5f152cbd856a81f/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25dbade8fbf30bcc551cb352376c0ad64b067e4fc56f90e22ba70c3ce205988c", size = 379068, upload-time = "2025-10-22T22:21:42.593Z" }, - { url = "https://files.pythonhosted.org/packages/b4/25/54fd48f9f680cfc44e6a7f39a5fadf1d4a4a1fd0848076af4a43e79f998c/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c03002f54cc855860bfdc3442928ffdca9081e73b5b382ed0b9e8efe6e5e205", size = 390518, upload-time = "2025-10-22T22:21:43.998Z" }, - { url = "https://files.pythonhosted.org/packages/1b/85/ac258c9c27f2ccb1bd5d0697e53a82ebcf8088e3186d5d2bf8498ee7ed44/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9699fa7990368b22032baf2b2dce1f634388e4ffc03dfefaaac79f4695edc95", size = 525319, upload-time = "2025-10-22T22:21:45.645Z" }, - { url = "https://files.pythonhosted.org/packages/40/cb/c6734774789566d46775f193964b76627cd5f42ecf246d257ce84d1912ed/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9b06fe1a75e05e0713f06ea0c89ecb6452210fd60e2f1b6ddc1067b990e08d9", size = 404896, upload-time = "2025-10-22T22:21:47.544Z" }, - { url = "https://files.pythonhosted.org/packages/1f/53/14e37ce83202c632c89b0691185dca9532288ff9d390eacae3d2ff771bae/rpds_py-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9f83e7b326a3f9ec3ef84cda98fb0a74c7159f33e692032233046e7fd15da2", size = 382862, upload-time = "2025-10-22T22:21:49.176Z" }, - { url = "https://files.pythonhosted.org/packages/6a/83/f3642483ca971a54d60caa4449f9d6d4dbb56a53e0072d0deff51b38af74/rpds_py-0.28.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:0d3259ea9ad8743a75a43eb7819324cdab393263c91be86e2d1901ee65c314e0", size = 398848, upload-time = "2025-10-22T22:21:51.024Z" }, - { url = "https://files.pythonhosted.org/packages/44/09/2d9c8b2f88e399b4cfe86efdf2935feaf0394e4f14ab30c6c5945d60af7d/rpds_py-0.28.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a7548b345f66f6695943b4ef6afe33ccd3f1b638bd9afd0f730dd255c249c9e", size = 412030, upload-time = "2025-10-22T22:21:52.665Z" }, - { url = "https://files.pythonhosted.org/packages/dd/f5/e1cec473d4bde6df1fd3738be8e82d64dd0600868e76e92dfeaebbc2d18f/rpds_py-0.28.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9a40040aa388b037eb39416710fbcce9443498d2eaab0b9b45ae988b53f5c67", size = 559700, upload-time = "2025-10-22T22:21:54.123Z" }, - { url = "https://files.pythonhosted.org/packages/8d/be/73bb241c1649edbf14e98e9e78899c2c5e52bbe47cb64811f44d2cc11808/rpds_py-0.28.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f60c7ea34e78c199acd0d3cda37a99be2c861dd2b8cf67399784f70c9f8e57d", size = 584581, upload-time = "2025-10-22T22:21:56.102Z" }, - { url = "https://files.pythonhosted.org/packages/9c/9c/ffc6e9218cd1eb5c2c7dbd276c87cd10e8c2232c456b554169eb363381df/rpds_py-0.28.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1571ae4292649100d743b26d5f9c63503bb1fedf538a8f29a98dce2d5ba6b4e6", size = 549981, upload-time = "2025-10-22T22:21:58.253Z" }, - { url = "https://files.pythonhosted.org/packages/5f/50/da8b6d33803a94df0149345ee33e5d91ed4d25fc6517de6a25587eae4133/rpds_py-0.28.0-cp311-cp311-win32.whl", hash = "sha256:5cfa9af45e7c1140af7321fa0bef25b386ee9faa8928c80dc3a5360971a29e8c", size = 214729, upload-time = "2025-10-22T22:21:59.625Z" }, - { url = "https://files.pythonhosted.org/packages/12/fd/b0f48c4c320ee24c8c20df8b44acffb7353991ddf688af01eef5f93d7018/rpds_py-0.28.0-cp311-cp311-win_amd64.whl", hash = "sha256:dd8d86b5d29d1b74100982424ba53e56033dc47720a6de9ba0259cf81d7cecaa", size = 223977, upload-time = "2025-10-22T22:22:01.092Z" }, - { url = "https://files.pythonhosted.org/packages/b4/21/c8e77a2ac66e2ec4e21f18a04b4e9a0417ecf8e61b5eaeaa9360a91713b4/rpds_py-0.28.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e27d3a5709cc2b3e013bf93679a849213c79ae0573f9b894b284b55e729e120", size = 217326, upload-time = "2025-10-22T22:22:02.944Z" }, - { url = "https://files.pythonhosted.org/packages/b8/5c/6c3936495003875fe7b14f90ea812841a08fca50ab26bd840e924097d9c8/rpds_py-0.28.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6b4f28583a4f247ff60cd7bdda83db8c3f5b05a7a82ff20dd4b078571747708f", size = 366439, upload-time = "2025-10-22T22:22:04.525Z" }, - { url = "https://files.pythonhosted.org/packages/56/f9/a0f1ca194c50aa29895b442771f036a25b6c41a35e4f35b1a0ea713bedae/rpds_py-0.28.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d678e91b610c29c4b3d52a2c148b641df2b4676ffe47c59f6388d58b99cdc424", size = 348170, upload-time = "2025-10-22T22:22:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/18/ea/42d243d3a586beb72c77fa5def0487daf827210069a95f36328e869599ea/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e819e0e37a44a78e1383bf1970076e2ccc4dc8c2bbaa2f9bd1dc987e9afff628", size = 378838, upload-time = "2025-10-22T22:22:07.932Z" }, - { url = "https://files.pythonhosted.org/packages/e7/78/3de32e18a94791af8f33601402d9d4f39613136398658412a4e0b3047327/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5ee514e0f0523db5d3fb171f397c54875dbbd69760a414dccf9d4d7ad628b5bd", size = 393299, upload-time = "2025-10-22T22:22:09.435Z" }, - { url = "https://files.pythonhosted.org/packages/13/7e/4bdb435afb18acea2eb8a25ad56b956f28de7c59f8a1d32827effa0d4514/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3fa06d27fdcee47f07a39e02862da0100cb4982508f5ead53ec533cd5fe55e", size = 518000, upload-time = "2025-10-22T22:22:11.326Z" }, - { url = "https://files.pythonhosted.org/packages/31/d0/5f52a656875cdc60498ab035a7a0ac8f399890cc1ee73ebd567bac4e39ae/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46959ef2e64f9e4a41fc89aa20dbca2b85531f9a72c21099a3360f35d10b0d5a", size = 408746, upload-time = "2025-10-22T22:22:13.143Z" }, - { url = "https://files.pythonhosted.org/packages/3e/cd/49ce51767b879cde77e7ad9fae164ea15dce3616fe591d9ea1df51152706/rpds_py-0.28.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8455933b4bcd6e83fde3fefc987a023389c4b13f9a58c8d23e4b3f6d13f78c84", size = 386379, upload-time = "2025-10-22T22:22:14.602Z" }, - { url = "https://files.pythonhosted.org/packages/6a/99/e4e1e1ee93a98f72fc450e36c0e4d99c35370220e815288e3ecd2ec36a2a/rpds_py-0.28.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:ad50614a02c8c2962feebe6012b52f9802deec4263946cddea37aaf28dd25a66", size = 401280, upload-time = "2025-10-22T22:22:16.063Z" }, - { url = "https://files.pythonhosted.org/packages/61/35/e0c6a57488392a8b319d2200d03dad2b29c0db9996f5662c3b02d0b86c02/rpds_py-0.28.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5deca01b271492553fdb6c7fd974659dce736a15bae5dad7ab8b93555bceb28", size = 412365, upload-time = "2025-10-22T22:22:17.504Z" }, - { url = "https://files.pythonhosted.org/packages/ff/6a/841337980ea253ec797eb084665436007a1aad0faac1ba097fb906c5f69c/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:735f8495a13159ce6a0d533f01e8674cec0c57038c920495f87dcb20b3ddb48a", size = 559573, upload-time = "2025-10-22T22:22:19.108Z" }, - { url = "https://files.pythonhosted.org/packages/e7/5e/64826ec58afd4c489731f8b00729c5f6afdb86f1df1df60bfede55d650bb/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:961ca621ff10d198bbe6ba4957decca61aa2a0c56695384c1d6b79bf61436df5", size = 583973, upload-time = "2025-10-22T22:22:20.768Z" }, - { url = "https://files.pythonhosted.org/packages/b6/ee/44d024b4843f8386a4eeaa4c171b3d31d55f7177c415545fd1a24c249b5d/rpds_py-0.28.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2374e16cc9131022e7d9a8f8d65d261d9ba55048c78f3b6e017971a4f5e6353c", size = 553800, upload-time = "2025-10-22T22:22:22.25Z" }, - { url = "https://files.pythonhosted.org/packages/7d/89/33e675dccff11a06d4d85dbb4d1865f878d5020cbb69b2c1e7b2d3f82562/rpds_py-0.28.0-cp312-cp312-win32.whl", hash = "sha256:d15431e334fba488b081d47f30f091e5d03c18527c325386091f31718952fe08", size = 216954, upload-time = "2025-10-22T22:22:24.105Z" }, - { url = "https://files.pythonhosted.org/packages/af/36/45f6ebb3210887e8ee6dbf1bc710ae8400bb417ce165aaf3024b8360d999/rpds_py-0.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:a410542d61fc54710f750d3764380b53bf09e8c4edbf2f9141a82aa774a04f7c", size = 227844, upload-time = "2025-10-22T22:22:25.551Z" }, - { url = "https://files.pythonhosted.org/packages/57/91/f3fb250d7e73de71080f9a221d19bd6a1c1eb0d12a1ea26513f6c1052ad6/rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd", size = 217624, upload-time = "2025-10-22T22:22:26.914Z" }, - { url = "https://files.pythonhosted.org/packages/d3/03/ce566d92611dfac0085c2f4b048cd53ed7c274a5c05974b882a908d540a2/rpds_py-0.28.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e9e184408a0297086f880556b6168fa927d677716f83d3472ea333b42171ee3b", size = 366235, upload-time = "2025-10-22T22:22:28.397Z" }, - { url = "https://files.pythonhosted.org/packages/00/34/1c61da1b25592b86fd285bd7bd8422f4c9d748a7373b46126f9ae792a004/rpds_py-0.28.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:edd267266a9b0448f33dc465a97cfc5d467594b600fe28e7fa2f36450e03053a", size = 348241, upload-time = "2025-10-22T22:22:30.171Z" }, - { url = "https://files.pythonhosted.org/packages/fc/00/ed1e28616848c61c493a067779633ebf4b569eccaacf9ccbdc0e7cba2b9d/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85beb8b3f45e4e32f6802fb6cd6b17f615ef6c6a52f265371fb916fae02814aa", size = 378079, upload-time = "2025-10-22T22:22:31.644Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/ccb30333a16a470091b6e50289adb4d3ec656fd9951ba8c5e3aaa0746a67/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d2412be8d00a1b895f8ad827cc2116455196e20ed994bb704bf138fe91a42724", size = 393151, upload-time = "2025-10-22T22:22:33.453Z" }, - { url = "https://files.pythonhosted.org/packages/8c/d0/73e2217c3ee486d555cb84920597480627d8c0240ff3062005c6cc47773e/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf128350d384b777da0e68796afdcebc2e9f63f0e9f242217754e647f6d32491", size = 517520, upload-time = "2025-10-22T22:22:34.949Z" }, - { url = "https://files.pythonhosted.org/packages/c4/91/23efe81c700427d0841a4ae7ea23e305654381831e6029499fe80be8a071/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2036d09b363aa36695d1cc1a97b36865597f4478470b0697b5ee9403f4fe399", size = 408699, upload-time = "2025-10-22T22:22:36.584Z" }, - { url = "https://files.pythonhosted.org/packages/ca/ee/a324d3198da151820a326c1f988caaa4f37fc27955148a76fff7a2d787a9/rpds_py-0.28.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8e1e9be4fa6305a16be628959188e4fd5cd6f1b0e724d63c6d8b2a8adf74ea6", size = 385720, upload-time = "2025-10-22T22:22:38.014Z" }, - { url = "https://files.pythonhosted.org/packages/19/ad/e68120dc05af8b7cab4a789fccd8cdcf0fe7e6581461038cc5c164cd97d2/rpds_py-0.28.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0a403460c9dd91a7f23fc3188de6d8977f1d9603a351d5db6cf20aaea95b538d", size = 401096, upload-time = "2025-10-22T22:22:39.869Z" }, - { url = "https://files.pythonhosted.org/packages/99/90/c1e070620042459d60df6356b666bb1f62198a89d68881816a7ed121595a/rpds_py-0.28.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d7366b6553cdc805abcc512b849a519167db8f5e5c3472010cd1228b224265cb", size = 411465, upload-time = "2025-10-22T22:22:41.395Z" }, - { url = "https://files.pythonhosted.org/packages/68/61/7c195b30d57f1b8d5970f600efee72a4fad79ec829057972e13a0370fd24/rpds_py-0.28.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b43c6a3726efd50f18d8120ec0551241c38785b68952d240c45ea553912ac41", size = 558832, upload-time = "2025-10-22T22:22:42.871Z" }, - { url = "https://files.pythonhosted.org/packages/b0/3d/06f3a718864773f69941d4deccdf18e5e47dd298b4628062f004c10f3b34/rpds_py-0.28.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0cb7203c7bc69d7c1585ebb33a2e6074492d2fc21ad28a7b9d40457ac2a51ab7", size = 583230, upload-time = "2025-10-22T22:22:44.877Z" }, - { url = "https://files.pythonhosted.org/packages/66/df/62fc783781a121e77fee9a21ead0a926f1b652280a33f5956a5e7833ed30/rpds_py-0.28.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a52a5169c664dfb495882adc75c304ae1d50df552fbd68e100fdc719dee4ff9", size = 553268, upload-time = "2025-10-22T22:22:46.441Z" }, - { url = "https://files.pythonhosted.org/packages/84/85/d34366e335140a4837902d3dea89b51f087bd6a63c993ebdff59e93ee61d/rpds_py-0.28.0-cp313-cp313-win32.whl", hash = "sha256:2e42456917b6687215b3e606ab46aa6bca040c77af7df9a08a6dcfe8a4d10ca5", size = 217100, upload-time = "2025-10-22T22:22:48.342Z" }, - { url = "https://files.pythonhosted.org/packages/3c/1c/f25a3f3752ad7601476e3eff395fe075e0f7813fbb9862bd67c82440e880/rpds_py-0.28.0-cp313-cp313-win_amd64.whl", hash = "sha256:e0a0311caedc8069d68fc2bf4c9019b58a2d5ce3cd7cb656c845f1615b577e1e", size = 227759, upload-time = "2025-10-22T22:22:50.219Z" }, - { url = "https://files.pythonhosted.org/packages/e0/d6/5f39b42b99615b5bc2f36ab90423ea404830bdfee1c706820943e9a645eb/rpds_py-0.28.0-cp313-cp313-win_arm64.whl", hash = "sha256:04c1b207ab8b581108801528d59ad80aa83bb170b35b0ddffb29c20e411acdc1", size = 217326, upload-time = "2025-10-22T22:22:51.647Z" }, - { url = "https://files.pythonhosted.org/packages/5c/8b/0c69b72d1cee20a63db534be0df271effe715ef6c744fdf1ff23bb2b0b1c/rpds_py-0.28.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f296ea3054e11fc58ad42e850e8b75c62d9a93a9f981ad04b2e5ae7d2186ff9c", size = 355736, upload-time = "2025-10-22T22:22:53.211Z" }, - { url = "https://files.pythonhosted.org/packages/f7/6d/0c2ee773cfb55c31a8514d2cece856dd299170a49babd50dcffb15ddc749/rpds_py-0.28.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5a7306c19b19005ad98468fcefeb7100b19c79fc23a5f24a12e06d91181193fa", size = 342677, upload-time = "2025-10-22T22:22:54.723Z" }, - { url = "https://files.pythonhosted.org/packages/e2/1c/22513ab25a27ea205144414724743e305e8153e6abe81833b5e678650f5a/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5d9b86aa501fed9862a443c5c3116f6ead8bc9296185f369277c42542bd646b", size = 371847, upload-time = "2025-10-22T22:22:56.295Z" }, - { url = "https://files.pythonhosted.org/packages/60/07/68e6ccdb4b05115ffe61d31afc94adef1833d3a72f76c9632d4d90d67954/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e5bbc701eff140ba0e872691d573b3d5d30059ea26e5785acba9132d10c8c31d", size = 381800, upload-time = "2025-10-22T22:22:57.808Z" }, - { url = "https://files.pythonhosted.org/packages/73/bf/6d6d15df80781d7f9f368e7c1a00caf764436518c4877fb28b029c4624af/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5690671cd672a45aa8616d7374fdf334a1b9c04a0cac3c854b1136e92374fe", size = 518827, upload-time = "2025-10-22T22:22:59.826Z" }, - { url = "https://files.pythonhosted.org/packages/7b/d3/2decbb2976cc452cbf12a2b0aaac5f1b9dc5dd9d1f7e2509a3ee00421249/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f1d92ecea4fa12f978a367c32a5375a1982834649cdb96539dcdc12e609ab1a", size = 399471, upload-time = "2025-10-22T22:23:01.968Z" }, - { url = "https://files.pythonhosted.org/packages/b1/2c/f30892f9e54bd02e5faca3f6a26d6933c51055e67d54818af90abed9748e/rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d252db6b1a78d0a3928b6190156042d54c93660ce4d98290d7b16b5296fb7cc", size = 377578, upload-time = "2025-10-22T22:23:03.52Z" }, - { url = "https://files.pythonhosted.org/packages/f0/5d/3bce97e5534157318f29ac06bf2d279dae2674ec12f7cb9c12739cee64d8/rpds_py-0.28.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d61b355c3275acb825f8777d6c4505f42b5007e357af500939d4a35b19177259", size = 390482, upload-time = "2025-10-22T22:23:05.391Z" }, - { url = "https://files.pythonhosted.org/packages/e3/f0/886bd515ed457b5bd93b166175edb80a0b21a210c10e993392127f1e3931/rpds_py-0.28.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:acbe5e8b1026c0c580d0321c8aae4b0a1e1676861d48d6e8c6586625055b606a", size = 402447, upload-time = "2025-10-22T22:23:06.93Z" }, - { url = "https://files.pythonhosted.org/packages/42/b5/71e8777ac55e6af1f4f1c05b47542a1eaa6c33c1cf0d300dca6a1c6e159a/rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8aa23b6f0fc59b85b4c7d89ba2965af274346f738e8d9fc2455763602e62fd5f", size = 552385, upload-time = "2025-10-22T22:23:08.557Z" }, - { url = "https://files.pythonhosted.org/packages/5d/cb/6ca2d70cbda5a8e36605e7788c4aa3bea7c17d71d213465a5a675079b98d/rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7b14b0c680286958817c22d76fcbca4800ddacef6f678f3a7c79a1fe7067fe37", size = 575642, upload-time = "2025-10-22T22:23:10.348Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d4/407ad9960ca7856d7b25c96dcbe019270b5ffdd83a561787bc682c797086/rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bcf1d210dfee61a6c86551d67ee1031899c0fdbae88b2d44a569995d43797712", size = 544507, upload-time = "2025-10-22T22:23:12.434Z" }, - { url = "https://files.pythonhosted.org/packages/51/31/2f46fe0efcac23fbf5797c6b6b7e1c76f7d60773e525cb65fcbc582ee0f2/rpds_py-0.28.0-cp313-cp313t-win32.whl", hash = "sha256:3aa4dc0fdab4a7029ac63959a3ccf4ed605fee048ba67ce89ca3168da34a1342", size = 205376, upload-time = "2025-10-22T22:23:13.979Z" }, - { url = "https://files.pythonhosted.org/packages/92/e4/15947bda33cbedfc134490a41841ab8870a72a867a03d4969d886f6594a2/rpds_py-0.28.0-cp313-cp313t-win_amd64.whl", hash = "sha256:7b7d9d83c942855e4fdcfa75d4f96f6b9e272d42fffcb72cd4bb2577db2e2907", size = 215907, upload-time = "2025-10-22T22:23:15.5Z" }, - { url = "https://files.pythonhosted.org/packages/08/47/ffe8cd7a6a02833b10623bf765fbb57ce977e9a4318ca0e8cf97e9c3d2b3/rpds_py-0.28.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:dcdcb890b3ada98a03f9f2bb108489cdc7580176cb73b4f2d789e9a1dac1d472", size = 353830, upload-time = "2025-10-22T22:23:17.03Z" }, - { url = "https://files.pythonhosted.org/packages/f9/9f/890f36cbd83a58491d0d91ae0db1702639edb33fb48eeb356f80ecc6b000/rpds_py-0.28.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f274f56a926ba2dc02976ca5b11c32855cbd5925534e57cfe1fda64e04d1add2", size = 341819, upload-time = "2025-10-22T22:23:18.57Z" }, - { url = "https://files.pythonhosted.org/packages/09/e3/921eb109f682aa24fb76207698fbbcf9418738f35a40c21652c29053f23d/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fe0438ac4a29a520ea94c8c7f1754cdd8feb1bc490dfda1bfd990072363d527", size = 373127, upload-time = "2025-10-22T22:23:20.216Z" }, - { url = "https://files.pythonhosted.org/packages/23/13/bce4384d9f8f4989f1a9599c71b7a2d877462e5fd7175e1f69b398f729f4/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a358a32dd3ae50e933347889b6af9a1bdf207ba5d1a3f34e1a38cd3540e6733", size = 382767, upload-time = "2025-10-22T22:23:21.787Z" }, - { url = "https://files.pythonhosted.org/packages/23/e1/579512b2d89a77c64ccef5a0bc46a6ef7f72ae0cf03d4b26dcd52e57ee0a/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e80848a71c78aa328fefaba9c244d588a342c8e03bda518447b624ea64d1ff56", size = 517585, upload-time = "2025-10-22T22:23:23.699Z" }, - { url = "https://files.pythonhosted.org/packages/62/3c/ca704b8d324a2591b0b0adcfcaadf9c862375b11f2f667ac03c61b4fd0a6/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f586db2e209d54fe177e58e0bc4946bea5fb0102f150b1b2f13de03e1f0976f8", size = 399828, upload-time = "2025-10-22T22:23:25.713Z" }, - { url = "https://files.pythonhosted.org/packages/da/37/e84283b9e897e3adc46b4c88bb3f6ec92a43bd4d2f7ef5b13459963b2e9c/rpds_py-0.28.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ae8ee156d6b586e4292491e885d41483136ab994e719a13458055bec14cf370", size = 375509, upload-time = "2025-10-22T22:23:27.32Z" }, - { url = "https://files.pythonhosted.org/packages/1a/c2/a980beab869d86258bf76ec42dec778ba98151f253a952b02fe36d72b29c/rpds_py-0.28.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a805e9b3973f7e27f7cab63a6b4f61d90f2e5557cff73b6e97cd5b8540276d3d", size = 392014, upload-time = "2025-10-22T22:23:29.332Z" }, - { url = "https://files.pythonhosted.org/packages/da/b5/b1d3c5f9d3fa5aeef74265f9c64de3c34a0d6d5cd3c81c8b17d5c8f10ed4/rpds_py-0.28.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5d3fd16b6dc89c73a4da0b4ac8b12a7ecc75b2864b95c9e5afed8003cb50a728", size = 402410, upload-time = "2025-10-22T22:23:31.14Z" }, - { url = "https://files.pythonhosted.org/packages/74/ae/cab05ff08dfcc052afc73dcb38cbc765ffc86f94e966f3924cd17492293c/rpds_py-0.28.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6796079e5d24fdaba6d49bda28e2c47347e89834678f2bc2c1b4fc1489c0fb01", size = 553593, upload-time = "2025-10-22T22:23:32.834Z" }, - { url = "https://files.pythonhosted.org/packages/70/80/50d5706ea2a9bfc9e9c5f401d91879e7c790c619969369800cde202da214/rpds_py-0.28.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:76500820c2af232435cbe215e3324c75b950a027134e044423f59f5b9a1ba515", size = 576925, upload-time = "2025-10-22T22:23:34.47Z" }, - { url = "https://files.pythonhosted.org/packages/ab/12/85a57d7a5855a3b188d024b099fd09c90db55d32a03626d0ed16352413ff/rpds_py-0.28.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bbdc5640900a7dbf9dd707fe6388972f5bbd883633eb68b76591044cfe346f7e", size = 542444, upload-time = "2025-10-22T22:23:36.093Z" }, - { url = "https://files.pythonhosted.org/packages/6c/65/10643fb50179509150eb94d558e8837c57ca8b9adc04bd07b98e57b48f8c/rpds_py-0.28.0-cp314-cp314-win32.whl", hash = "sha256:adc8aa88486857d2b35d75f0640b949759f79dc105f50aa2c27816b2e0dd749f", size = 207968, upload-time = "2025-10-22T22:23:37.638Z" }, - { url = "https://files.pythonhosted.org/packages/b4/84/0c11fe4d9aaea784ff4652499e365963222481ac647bcd0251c88af646eb/rpds_py-0.28.0-cp314-cp314-win_amd64.whl", hash = "sha256:66e6fa8e075b58946e76a78e69e1a124a21d9a48a5b4766d15ba5b06869d1fa1", size = 218876, upload-time = "2025-10-22T22:23:39.179Z" }, - { url = "https://files.pythonhosted.org/packages/0f/e0/3ab3b86ded7bb18478392dc3e835f7b754cd446f62f3fc96f4fe2aca78f6/rpds_py-0.28.0-cp314-cp314-win_arm64.whl", hash = "sha256:a6fe887c2c5c59413353b7c0caff25d0e566623501ccfff88957fa438a69377d", size = 212506, upload-time = "2025-10-22T22:23:40.755Z" }, - { url = "https://files.pythonhosted.org/packages/51/ec/d5681bb425226c3501eab50fc30e9d275de20c131869322c8a1729c7b61c/rpds_py-0.28.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7a69df082db13c7070f7b8b1f155fa9e687f1d6aefb7b0e3f7231653b79a067b", size = 355433, upload-time = "2025-10-22T22:23:42.259Z" }, - { url = "https://files.pythonhosted.org/packages/be/ec/568c5e689e1cfb1ea8b875cffea3649260955f677fdd7ddc6176902d04cd/rpds_py-0.28.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b1cde22f2c30ebb049a9e74c5374994157b9b70a16147d332f89c99c5960737a", size = 342601, upload-time = "2025-10-22T22:23:44.372Z" }, - { url = "https://files.pythonhosted.org/packages/32/fe/51ada84d1d2a1d9d8f2c902cfddd0133b4a5eb543196ab5161d1c07ed2ad/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5338742f6ba7a51012ea470bd4dc600a8c713c0c72adaa0977a1b1f4327d6592", size = 372039, upload-time = "2025-10-22T22:23:46.025Z" }, - { url = "https://files.pythonhosted.org/packages/07/c1/60144a2f2620abade1a78e0d91b298ac2d9b91bc08864493fa00451ef06e/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1460ebde1bcf6d496d80b191d854adedcc619f84ff17dc1c6d550f58c9efbba", size = 382407, upload-time = "2025-10-22T22:23:48.098Z" }, - { url = "https://files.pythonhosted.org/packages/45/ed/091a7bbdcf4038a60a461df50bc4c82a7ed6d5d5e27649aab61771c17585/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e3eb248f2feba84c692579257a043a7699e28a77d86c77b032c1d9fbb3f0219c", size = 518172, upload-time = "2025-10-22T22:23:50.16Z" }, - { url = "https://files.pythonhosted.org/packages/54/dd/02cc90c2fd9c2ef8016fd7813bfacd1c3a1325633ec8f244c47b449fc868/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3bbba5def70b16cd1c1d7255666aad3b290fbf8d0fe7f9f91abafb73611a91", size = 399020, upload-time = "2025-10-22T22:23:51.81Z" }, - { url = "https://files.pythonhosted.org/packages/ab/81/5d98cc0329bbb911ccecd0b9e19fbf7f3a5de8094b4cda5e71013b2dd77e/rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3114f4db69ac5a1f32e7e4d1cbbe7c8f9cf8217f78e6e002cedf2d54c2a548ed", size = 377451, upload-time = "2025-10-22T22:23:53.711Z" }, - { url = "https://files.pythonhosted.org/packages/b4/07/4d5bcd49e3dfed2d38e2dcb49ab6615f2ceb9f89f5a372c46dbdebb4e028/rpds_py-0.28.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:4b0cb8a906b1a0196b863d460c0222fb8ad0f34041568da5620f9799b83ccf0b", size = 390355, upload-time = "2025-10-22T22:23:55.299Z" }, - { url = "https://files.pythonhosted.org/packages/3f/79/9f14ba9010fee74e4f40bf578735cfcbb91d2e642ffd1abe429bb0b96364/rpds_py-0.28.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf681ac76a60b667106141e11a92a3330890257e6f559ca995fbb5265160b56e", size = 403146, upload-time = "2025-10-22T22:23:56.929Z" }, - { url = "https://files.pythonhosted.org/packages/39/4c/f08283a82ac141331a83a40652830edd3a4a92c34e07e2bbe00baaea2f5f/rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1e8ee6413cfc677ce8898d9cde18cc3a60fc2ba756b0dec5b71eb6eb21c49fa1", size = 552656, upload-time = "2025-10-22T22:23:58.62Z" }, - { url = "https://files.pythonhosted.org/packages/61/47/d922fc0666f0dd8e40c33990d055f4cc6ecff6f502c2d01569dbed830f9b/rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b3072b16904d0b5572a15eb9d31c1954e0d3227a585fc1351aa9878729099d6c", size = 576782, upload-time = "2025-10-22T22:24:00.312Z" }, - { url = "https://files.pythonhosted.org/packages/d3/0c/5bafdd8ccf6aa9d3bfc630cfece457ff5b581af24f46a9f3590f790e3df2/rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b670c30fd87a6aec281c3c9896d3bae4b205fd75d79d06dc87c2503717e46092", size = 544671, upload-time = "2025-10-22T22:24:02.297Z" }, - { url = "https://files.pythonhosted.org/packages/2c/37/dcc5d8397caa924988693519069d0beea077a866128719351a4ad95e82fc/rpds_py-0.28.0-cp314-cp314t-win32.whl", hash = "sha256:8014045a15b4d2b3476f0a287fcc93d4f823472d7d1308d47884ecac9e612be3", size = 205749, upload-time = "2025-10-22T22:24:03.848Z" }, - { url = "https://files.pythonhosted.org/packages/d7/69/64d43b21a10d72b45939a28961216baeb721cc2a430f5f7c3bfa21659a53/rpds_py-0.28.0-cp314-cp314t-win_amd64.whl", hash = "sha256:7a4e59c90d9c27c561eb3160323634a9ff50b04e4f7820600a2beb0ac90db578", size = 216233, upload-time = "2025-10-22T22:24:05.471Z" }, - { url = "https://files.pythonhosted.org/packages/ae/bc/b43f2ea505f28119bd551ae75f70be0c803d2dbcd37c1b3734909e40620b/rpds_py-0.28.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f5e7101145427087e493b9c9b959da68d357c28c562792300dd21a095118ed16", size = 363913, upload-time = "2025-10-22T22:24:07.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/f2/db318195d324c89a2c57dc5195058cbadd71b20d220685c5bd1da79ee7fe/rpds_py-0.28.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:31eb671150b9c62409a888850aaa8e6533635704fe2b78335f9aaf7ff81eec4d", size = 350452, upload-time = "2025-10-22T22:24:08.754Z" }, - { url = "https://files.pythonhosted.org/packages/ae/f2/1391c819b8573a4898cedd6b6c5ec5bc370ce59e5d6bdcebe3c9c1db4588/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48b55c1f64482f7d8bd39942f376bfdf2f6aec637ee8c805b5041e14eeb771db", size = 380957, upload-time = "2025-10-22T22:24:10.826Z" }, - { url = "https://files.pythonhosted.org/packages/5a/5c/e5de68ee7eb7248fce93269833d1b329a196d736aefb1a7481d1e99d1222/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24743a7b372e9a76171f6b69c01aedf927e8ac3e16c474d9fe20d552a8cb45c7", size = 391919, upload-time = "2025-10-22T22:24:12.559Z" }, - { url = "https://files.pythonhosted.org/packages/fb/4f/2376336112cbfeb122fd435d608ad8d5041b3aed176f85a3cb32c262eb80/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:389c29045ee8bbb1627ea190b4976a310a295559eaf9f1464a1a6f2bf84dde78", size = 528541, upload-time = "2025-10-22T22:24:14.197Z" }, - { url = "https://files.pythonhosted.org/packages/68/53/5ae232e795853dd20da7225c5dd13a09c0a905b1a655e92bdf8d78a99fd9/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23690b5827e643150cf7b49569679ec13fe9a610a15949ed48b85eb7f98f34ec", size = 405629, upload-time = "2025-10-22T22:24:16.001Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2d/351a3b852b683ca9b6b8b38ed9efb2347596973849ba6c3a0e99877c10aa/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f0c9266c26580e7243ad0d72fc3e01d6b33866cfab5084a6da7576bcf1c4f72", size = 384123, upload-time = "2025-10-22T22:24:17.585Z" }, - { url = "https://files.pythonhosted.org/packages/e0/15/870804daa00202728cc91cb8e2385fa9f1f4eb49857c49cfce89e304eae6/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4c6c4db5d73d179746951486df97fd25e92396be07fc29ee8ff9a8f5afbdfb27", size = 400923, upload-time = "2025-10-22T22:24:19.512Z" }, - { url = "https://files.pythonhosted.org/packages/53/25/3706b83c125fa2a0bccceac951de3f76631f6bd0ee4d02a0ed780712ef1b/rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3b695a8fa799dd2cfdb4804b37096c5f6dba1ac7f48a7fbf6d0485bcd060316", size = 413767, upload-time = "2025-10-22T22:24:21.316Z" }, - { url = "https://files.pythonhosted.org/packages/ef/f9/ce43dbe62767432273ed2584cef71fef8411bddfb64125d4c19128015018/rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:6aa1bfce3f83baf00d9c5fcdbba93a3ab79958b4c7d7d1f55e7fe68c20e63912", size = 561530, upload-time = "2025-10-22T22:24:22.958Z" }, - { url = "https://files.pythonhosted.org/packages/46/c9/ffe77999ed8f81e30713dd38fd9ecaa161f28ec48bb80fa1cd9118399c27/rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:7b0f9dceb221792b3ee6acb5438eb1f02b0cb2c247796a72b016dcc92c6de829", size = 585453, upload-time = "2025-10-22T22:24:24.779Z" }, - { url = "https://files.pythonhosted.org/packages/ed/d2/4a73b18821fd4669762c855fd1f4e80ceb66fb72d71162d14da58444a763/rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5d0145edba8abd3db0ab22b5300c99dc152f5c9021fab861be0f0544dc3cbc5f", size = 552199, upload-time = "2025-10-22T22:24:26.54Z" }, -] - -[[package]] -name = "setuptools" -version = "80.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490, upload-time = "2025-11-30T20:21:33.256Z" }, + { url = "https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00", size = 359751, upload-time = "2025-11-30T20:21:34.591Z" }, + { url = "https://files.pythonhosted.org/packages/cd/7c/e4933565ef7f7a0818985d87c15d9d273f1a649afa6a52ea35ad011195ea/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6", size = 389696, upload-time = "2025-11-30T20:21:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/5e/01/6271a2511ad0815f00f7ed4390cf2567bec1d4b1da39e2c27a41e6e3b4de/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7", size = 403136, upload-time = "2025-11-30T20:21:37.728Z" }, + { url = "https://files.pythonhosted.org/packages/55/64/c857eb7cd7541e9b4eee9d49c196e833128a55b89a9850a9c9ac33ccf897/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324", size = 524699, upload-time = "2025-11-30T20:21:38.92Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ed/94816543404078af9ab26159c44f9e98e20fe47e2126d5d32c9d9948d10a/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df", size = 412022, upload-time = "2025-11-30T20:21:40.407Z" }, + { url = "https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3", size = 390522, upload-time = "2025-11-30T20:21:42.17Z" }, + { url = "https://files.pythonhosted.org/packages/13/4e/57a85fda37a229ff4226f8cbcf09f2a455d1ed20e802ce5b2b4a7f5ed053/rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221", size = 404579, upload-time = "2025-11-30T20:21:43.769Z" }, + { url = "https://files.pythonhosted.org/packages/f9/da/c9339293513ec680a721e0e16bf2bac3db6e5d7e922488de471308349bba/rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7", size = 421305, upload-time = "2025-11-30T20:21:44.994Z" }, + { url = "https://files.pythonhosted.org/packages/f9/be/522cb84751114f4ad9d822ff5a1aa3c98006341895d5f084779b99596e5c/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff", size = 572503, upload-time = "2025-11-30T20:21:46.91Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9b/de879f7e7ceddc973ea6e4629e9b380213a6938a249e94b0cdbcc325bb66/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7", size = 598322, upload-time = "2025-11-30T20:21:48.709Z" }, + { url = "https://files.pythonhosted.org/packages/48/ac/f01fc22efec3f37d8a914fc1b2fb9bcafd56a299edbe96406f3053edea5a/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139", size = 560792, upload-time = "2025-11-30T20:21:50.024Z" }, + { url = "https://files.pythonhosted.org/packages/e2/da/4e2b19d0f131f35b6146425f846563d0ce036763e38913d917187307a671/rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464", size = 221901, upload-time = "2025-11-30T20:21:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169", size = 235823, upload-time = "2025-11-30T20:21:52.505Z" }, + { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157, upload-time = "2025-11-30T20:21:53.789Z" }, + { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676, upload-time = "2025-11-30T20:21:55.475Z" }, + { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938, upload-time = "2025-11-30T20:21:57.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932, upload-time = "2025-11-30T20:21:58.47Z" }, + { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830, upload-time = "2025-11-30T20:21:59.699Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033, upload-time = "2025-11-30T20:22:00.991Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828, upload-time = "2025-11-30T20:22:02.723Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683, upload-time = "2025-11-30T20:22:04.367Z" }, + { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583, upload-time = "2025-11-30T20:22:05.814Z" }, + { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496, upload-time = "2025-11-30T20:22:07.713Z" }, + { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669, upload-time = "2025-11-30T20:22:09.312Z" }, + { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011, upload-time = "2025-11-30T20:22:11.309Z" }, + { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406, upload-time = "2025-11-30T20:22:13.101Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024, upload-time = "2025-11-30T20:22:14.853Z" }, + { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069, upload-time = "2025-11-30T20:22:16.577Z" }, + { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" }, + { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951, upload-time = "2025-11-30T20:22:23.408Z" }, + { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622, upload-time = "2025-11-30T20:22:25.16Z" }, + { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492, upload-time = "2025-11-30T20:22:26.505Z" }, + { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080, upload-time = "2025-11-30T20:22:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680, upload-time = "2025-11-30T20:22:29.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589, upload-time = "2025-11-30T20:22:31.469Z" }, + { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289, upload-time = "2025-11-30T20:22:32.997Z" }, + { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737, upload-time = "2025-11-30T20:22:34.419Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120, upload-time = "2025-11-30T20:22:35.903Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782, upload-time = "2025-11-30T20:22:37.271Z" }, + { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463, upload-time = "2025-11-30T20:22:39.021Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868, upload-time = "2025-11-30T20:22:40.493Z" }, + { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887, upload-time = "2025-11-30T20:22:41.812Z" }, + { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904, upload-time = "2025-11-30T20:22:43.479Z" }, + { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945, upload-time = "2025-11-30T20:22:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783, upload-time = "2025-11-30T20:22:46.103Z" }, + { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021, upload-time = "2025-11-30T20:22:47.458Z" }, + { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589, upload-time = "2025-11-30T20:22:48.872Z" }, + { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025, upload-time = "2025-11-30T20:22:50.196Z" }, + { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895, upload-time = "2025-11-30T20:22:51.87Z" }, + { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799, upload-time = "2025-11-30T20:22:53.341Z" }, + { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731, upload-time = "2025-11-30T20:22:54.778Z" }, + { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027, upload-time = "2025-11-30T20:22:56.212Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020, upload-time = "2025-11-30T20:22:58.2Z" }, + { url = "https://files.pythonhosted.org/packages/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139, upload-time = "2025-11-30T20:23:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224, upload-time = "2025-11-30T20:23:02.008Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645, upload-time = "2025-11-30T20:23:03.43Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443, upload-time = "2025-11-30T20:23:04.878Z" }, + { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375, upload-time = "2025-11-30T20:23:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850, upload-time = "2025-11-30T20:23:07.825Z" }, + { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812, upload-time = "2025-11-30T20:23:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841, upload-time = "2025-11-30T20:23:11.186Z" }, + { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149, upload-time = "2025-11-30T20:23:12.864Z" }, + { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843, upload-time = "2025-11-30T20:23:14.638Z" }, + { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507, upload-time = "2025-11-30T20:23:16.105Z" }, + { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949, upload-time = "2025-11-30T20:23:17.539Z" }, + { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790, upload-time = "2025-11-30T20:23:19.029Z" }, + { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217, upload-time = "2025-11-30T20:23:20.885Z" }, + { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806, upload-time = "2025-11-30T20:23:22.488Z" }, + { url = "https://files.pythonhosted.org/packages/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341, upload-time = "2025-11-30T20:23:24.449Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768, upload-time = "2025-11-30T20:23:25.908Z" }, + { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099, upload-time = "2025-11-30T20:23:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192, upload-time = "2025-11-30T20:23:29.151Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080, upload-time = "2025-11-30T20:23:30.785Z" }, + { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841, upload-time = "2025-11-30T20:23:32.209Z" }, + { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670, upload-time = "2025-11-30T20:23:33.742Z" }, + { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005, upload-time = "2025-11-30T20:23:35.253Z" }, + { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112, upload-time = "2025-11-30T20:23:36.842Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049, upload-time = "2025-11-30T20:23:38.343Z" }, + { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661, upload-time = "2025-11-30T20:23:40.263Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606, upload-time = "2025-11-30T20:23:42.186Z" }, + { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126, upload-time = "2025-11-30T20:23:44.086Z" }, + { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371, upload-time = "2025-11-30T20:23:46.004Z" }, + { url = "https://files.pythonhosted.org/packages/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298, upload-time = "2025-11-30T20:23:47.696Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604, upload-time = "2025-11-30T20:23:49.501Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391, upload-time = "2025-11-30T20:23:50.96Z" }, + { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868, upload-time = "2025-11-30T20:23:52.494Z" }, + { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747, upload-time = "2025-11-30T20:23:54.036Z" }, + { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795, upload-time = "2025-11-30T20:23:55.556Z" }, + { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330, upload-time = "2025-11-30T20:23:57.033Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194, upload-time = "2025-11-30T20:23:58.637Z" }, + { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340, upload-time = "2025-11-30T20:24:00.2Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765, upload-time = "2025-11-30T20:24:01.759Z" }, + { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834, upload-time = "2025-11-30T20:24:03.687Z" }, + { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470, upload-time = "2025-11-30T20:24:05.232Z" }, + { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630, upload-time = "2025-11-30T20:24:06.878Z" }, + { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148, upload-time = "2025-11-30T20:24:08.445Z" }, + { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, + { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, + { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, + { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292, upload-time = "2025-11-30T20:24:16.537Z" }, + { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128, upload-time = "2025-11-30T20:24:18.086Z" }, + { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542, upload-time = "2025-11-30T20:24:20.092Z" }, + { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004, upload-time = "2025-11-30T20:24:22.231Z" }, + { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063, upload-time = "2025-11-30T20:24:24.302Z" }, + { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099, upload-time = "2025-11-30T20:24:25.916Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177, upload-time = "2025-11-30T20:24:27.834Z" }, + { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015, upload-time = "2025-11-30T20:24:29.457Z" }, + { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736, upload-time = "2025-11-30T20:24:31.22Z" }, + { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981, upload-time = "2025-11-30T20:24:32.934Z" }, + { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782, upload-time = "2025-11-30T20:24:35.169Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, ] [[package]] @@ -553,11 +553,11 @@ wheels = [ [[package]] name = "tzdata" -version = "2025.2" +version = "2025.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz", hash = "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", size = 196772, upload-time = "2025-12-13T17:45:35.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl", hash = "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1", size = 348521, upload-time = "2025-12-13T17:45:33.889Z" }, ] [[package]] @@ -587,41 +587,47 @@ wheels = [ [[package]] name = "webcolors" -version = "24.11.1" +version = "25.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491, upload-time = "2025-10-31T07:51:03.977Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905, upload-time = "2025-10-31T07:51:01.778Z" }, ] [[package]] name = "zope-interface" -version = "8.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/3a/7fcf02178b8fad0a51e67e32765cd039ae505d054d744d76b8c2bbcba5ba/zope_interface-8.0.1.tar.gz", hash = "sha256:eba5610d042c3704a48222f7f7c6ab5b243ed26f917e2bc69379456b115e02d1", size = 253746, upload-time = "2025-09-25T05:55:51.285Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/75/e5/ffef169d17b92c6236b3b18b890c0ce73502f3cbd5b6532ff20d412d94a3/zope_interface-8.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fd7195081b8637eeed8d73e4d183b07199a1dc738fb28b3de6666b1b55662570", size = 207364, upload-time = "2025-09-25T05:58:50.262Z" }, - { url = "https://files.pythonhosted.org/packages/35/b6/87aca626c09af829d3a32011599d6e18864bc8daa0ad3a7e258f3d7f8bcf/zope_interface-8.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f7c4bc4021108847bce763673ce70d0716b08dfc2ba9889e7bad46ac2b3bb924", size = 207901, upload-time = "2025-09-25T05:58:51.74Z" }, - { url = "https://files.pythonhosted.org/packages/d8/c1/eec33cc9f847ebeb0bc6234d7d45fe3fc0a6fe8fc5b5e6be0442bd2c684d/zope_interface-8.0.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:758803806b962f32c87b31bb18c298b022965ba34fe532163831cc39118c24ab", size = 249358, upload-time = "2025-09-25T05:58:16.979Z" }, - { url = "https://files.pythonhosted.org/packages/58/7d/1e3476a1ef0175559bd8492dc7bb921ad0df5b73861d764b1f824ad5484a/zope_interface-8.0.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f8e88f35f86bbe8243cad4b2972deef0fdfca0a0723455abbebdc83bbab96b69", size = 254475, upload-time = "2025-09-25T05:58:10.032Z" }, - { url = "https://files.pythonhosted.org/packages/bc/67/ba5ea98ff23f723c5cbe7db7409f2e43c9fe2df1ced67881443c01e64478/zope_interface-8.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7844765695937d9b0d83211220b72e2cf6ac81a08608ad2b58f2c094af498d83", size = 254913, upload-time = "2025-09-25T06:26:22.263Z" }, - { url = "https://files.pythonhosted.org/packages/2b/a7/b1b8b6c13fba955c043cdee409953ee85f652b106493e2e931a84f95c1aa/zope_interface-8.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:64fa7b206dd9669f29d5c1241a768bebe8ab1e8a4b63ee16491f041e058c09d0", size = 211753, upload-time = "2025-09-25T05:59:00.561Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2f/c10c739bcb9b072090c97c2e08533777497190daa19d190d72b4cce9c7cb/zope_interface-8.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4bd01022d2e1bce4a4a4ed9549edb25393c92e607d7daa6deff843f1f68b479d", size = 207903, upload-time = "2025-09-25T05:58:21.671Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e1/9845ac3697f108d9a1af6912170c59a23732090bbfb35955fe77e5544955/zope_interface-8.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:29be8db8b712d94f1c05e24ea230a879271d787205ba1c9a6100d1d81f06c69a", size = 208345, upload-time = "2025-09-25T05:58:24.217Z" }, - { url = "https://files.pythonhosted.org/packages/f2/49/6573bc8b841cfab18e80c8e8259f1abdbbf716140011370de30231be79ad/zope_interface-8.0.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:51ae1b856565b30455b7879fdf0a56a88763b401d3f814fa9f9542d7410dbd7e", size = 255027, upload-time = "2025-09-25T05:58:19.975Z" }, - { url = "https://files.pythonhosted.org/packages/e2/fd/908b0fd4b1ab6e412dfac9bd2b606f2893ef9ba3dd36d643f5e5b94c57b3/zope_interface-8.0.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d2e7596149cb1acd1d4d41b9f8fe2ffc0e9e29e2e91d026311814181d0d9efaf", size = 259800, upload-time = "2025-09-25T05:58:11.487Z" }, - { url = "https://files.pythonhosted.org/packages/dc/78/8419a2b4e88410520ed4b7f93bbd25a6d4ae66c4e2b131320f2b90f43077/zope_interface-8.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b2737c11c34fb9128816759864752d007ec4f987b571c934c30723ed881a7a4f", size = 260978, upload-time = "2025-09-25T06:26:24.483Z" }, - { url = "https://files.pythonhosted.org/packages/e5/90/caf68152c292f1810e2bd3acd2177badf08a740aa8a348714617d6c9ad0b/zope_interface-8.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:cf66e4bf731aa7e0ced855bb3670e8cda772f6515a475c6a107bad5cb6604103", size = 212155, upload-time = "2025-09-25T05:59:40.318Z" }, - { url = "https://files.pythonhosted.org/packages/dc/a6/0f08713ddda834c428ebf97b2a7fd8dea50c0100065a8955924dbd94dae8/zope_interface-8.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:115f27c1cc95ce7a517d960ef381beedb0a7ce9489645e80b9ab3cbf8a78799c", size = 208609, upload-time = "2025-09-25T05:58:53.698Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5e/d423045f54dc81e0991ec655041e7a0eccf6b2642535839dd364b35f4d7f/zope_interface-8.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af655c573b84e3cb6a4f6fd3fbe04e4dc91c63c6b6f99019b3713ef964e589bc", size = 208797, upload-time = "2025-09-25T05:58:56.258Z" }, - { url = "https://files.pythonhosted.org/packages/c6/43/39d4bb3f7a80ebd261446792493cfa4e198badd47107224f5b6fe1997ad9/zope_interface-8.0.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:23f82ef9b2d5370750cc1bf883c3b94c33d098ce08557922a3fbc7ff3b63dfe1", size = 259242, upload-time = "2025-09-25T05:58:21.602Z" }, - { url = "https://files.pythonhosted.org/packages/da/29/49effcff64ef30731e35520a152a9dfcafec86cf114b4c2aff942e8264ba/zope_interface-8.0.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35a1565d5244997f2e629c5c68715b3d9d9036e8df23c4068b08d9316dcb2822", size = 264696, upload-time = "2025-09-25T05:58:13.351Z" }, - { url = "https://files.pythonhosted.org/packages/c7/39/b947673ec9a258eeaa20208dd2f6127d9fbb3e5071272a674ebe02063a78/zope_interface-8.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:029ea1db7e855a475bf88d9910baab4e94d007a054810e9007ac037a91c67c6f", size = 264229, upload-time = "2025-09-25T06:26:26.226Z" }, - { url = "https://files.pythonhosted.org/packages/8f/ee/eed6efd1fc3788d1bef7a814e0592d8173b7fe601c699b935009df035fc2/zope_interface-8.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0beb3e7f7dc153944076fcaf717a935f68d39efa9fce96ec97bafcc0c2ea6cab", size = 212270, upload-time = "2025-09-25T05:58:53.584Z" }, - { url = "https://files.pythonhosted.org/packages/5f/dc/3c12fca01c910c793d636ffe9c0984e0646abaf804e44552070228ed0ede/zope_interface-8.0.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:c7cc027fc5c61c5d69e5080c30b66382f454f43dc379c463a38e78a9c6bab71a", size = 208992, upload-time = "2025-09-25T05:58:40.712Z" }, - { url = "https://files.pythonhosted.org/packages/46/71/6127b7282a3e380ca927ab2b40778a9c97935a4a57a2656dadc312db5f30/zope_interface-8.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fcf9097ff3003b7662299f1c25145e15260ec2a27f9a9e69461a585d79ca8552", size = 209051, upload-time = "2025-09-25T05:58:42.182Z" }, - { url = "https://files.pythonhosted.org/packages/56/86/4387a9f951ee18b0e41fda77da77d59c33e59f04660578e2bad688703e64/zope_interface-8.0.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6d965347dd1fb9e9a53aa852d4ded46b41ca670d517fd54e733a6b6a4d0561c2", size = 259223, upload-time = "2025-09-25T05:58:23.191Z" }, - { url = "https://files.pythonhosted.org/packages/61/08/ce60a114466abc067c68ed41e2550c655f551468ae17b4b17ea360090146/zope_interface-8.0.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9a3b8bb77a4b89427a87d1e9eb969ab05e38e6b4a338a9de10f6df23c33ec3c2", size = 264690, upload-time = "2025-09-25T05:58:15.052Z" }, - { url = "https://files.pythonhosted.org/packages/36/9a/62a9ba3a919594605a07c34eee3068659bbd648e2fa0c4a86d876810b674/zope_interface-8.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:87e6b089002c43231fb9afec89268391bcc7a3b66e76e269ffde19a8112fb8d5", size = 264201, upload-time = "2025-09-25T06:26:27.797Z" }, - { url = "https://files.pythonhosted.org/packages/da/06/8fe88bd7edef60566d21ef5caca1034e10f6b87441ea85de4bbf9ea74768/zope_interface-8.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:64a43f5280aa770cbafd0307cb3d1ff430e2a1001774e8ceb40787abe4bb6658", size = 212273, upload-time = "2025-09-25T06:00:25.398Z" }, +version = "8.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/c9/5ec8679a04d37c797d343f650c51ad67d178f0001c363e44b6ac5f97a9da/zope_interface-8.1.1.tar.gz", hash = "sha256:51b10e6e8e238d719636a401f44f1e366146912407b58453936b781a19be19ec", size = 254748, upload-time = "2025-11-15T08:32:52.404Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/ca/77df8f9bcbd8a5e29913c7fef14ff0aadac9448e78dc2606a85d7a23ec6c/zope_interface-8.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c6b12b656c7d7e3d79cad8e2afc4a37eae6b6076e2c209a33345143148e435e", size = 207415, upload-time = "2025-11-15T08:36:36.508Z" }, + { url = "https://files.pythonhosted.org/packages/e1/1f/f1c7828ba3d9b34e65c7e498216fc37ca6e69f1ff1918cca37cd1d895682/zope_interface-8.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:557c0f1363c300db406e9eeaae8ab6d1ba429d4fed60d8ab7dadab5ca66ccd35", size = 207951, upload-time = "2025-11-15T08:36:38.468Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9e/e079035812f06fe1feede1bef753f537fb33d5480d05107f65a51d94e7b3/zope_interface-8.1.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:127b0e4c873752b777721543cf8525b3db5e76b88bd33bab807f03c568e9003f", size = 249409, upload-time = "2025-11-15T08:36:40.148Z" }, + { url = "https://files.pythonhosted.org/packages/c2/09/b7f5a33bd3a17efb31e9e14496e600ab550ab0e38829dcda8a73f017fbfe/zope_interface-8.1.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e0892c9d2dd47b45f62d1861bcae8b427fcc49b4a04fff67f12c5c55e56654d7", size = 254527, upload-time = "2025-11-15T08:36:41.552Z" }, + { url = "https://files.pythonhosted.org/packages/2a/90/0eecd1eab6b62d296dff8445f051e4aa6bd91b67d71cfe9ff9d270b64dbe/zope_interface-8.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff8a92dc8c8a2c605074e464984e25b9b5a8ac9b2a0238dd73a0f374df59a77e", size = 254963, upload-time = "2025-11-15T08:36:42.708Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ff/2fe84fadd13e8adb7b2fb542311c27bad15881be26e37f403df3d0279c74/zope_interface-8.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:54627ddf6034aab1f506ba750dd093f67d353be6249467d720e9f278a578efe5", size = 211809, upload-time = "2025-11-15T08:36:44.43Z" }, + { url = "https://files.pythonhosted.org/packages/77/fc/d84bac27332bdefe8c03f7289d932aeb13a5fd6aeedba72b0aa5b18276ff/zope_interface-8.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e8a0fdd5048c1bb733e4693eae9bc4145a19419ea6a1c95299318a93fe9f3d72", size = 207955, upload-time = "2025-11-15T08:36:45.902Z" }, + { url = "https://files.pythonhosted.org/packages/52/02/e1234eb08b10b5cf39e68372586acc7f7bbcd18176f6046433a8f6b8b263/zope_interface-8.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4cb0ea75a26b606f5bc8524fbce7b7d8628161b6da002c80e6417ce5ec757c0", size = 208398, upload-time = "2025-11-15T08:36:47.016Z" }, + { url = "https://files.pythonhosted.org/packages/3c/be/aabda44d4bc490f9966c2b77fa7822b0407d852cb909b723f2d9e05d2427/zope_interface-8.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:c267b00b5a49a12743f5e1d3b4beef45479d696dab090f11fe3faded078a5133", size = 255079, upload-time = "2025-11-15T08:36:48.157Z" }, + { url = "https://files.pythonhosted.org/packages/d8/7f/4fbc7c2d7cb310e5a91b55db3d98e98d12b262014c1fcad9714fe33c2adc/zope_interface-8.1.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e25d3e2b9299e7ec54b626573673bdf0d740cf628c22aef0a3afef85b438aa54", size = 259850, upload-time = "2025-11-15T08:36:49.544Z" }, + { url = "https://files.pythonhosted.org/packages/fe/2c/dc573fffe59cdbe8bbbdd2814709bdc71c4870893e7226700bc6a08c5e0c/zope_interface-8.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:63db1241804417aff95ac229c13376c8c12752b83cc06964d62581b493e6551b", size = 261033, upload-time = "2025-11-15T08:36:51.061Z" }, + { url = "https://files.pythonhosted.org/packages/0e/51/1ac50e5ee933d9e3902f3400bda399c128a5c46f9f209d16affe3d4facc5/zope_interface-8.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:9639bf4ed07b5277fb231e54109117c30d608254685e48a7104a34618bcbfc83", size = 212215, upload-time = "2025-11-15T08:36:52.553Z" }, + { url = "https://files.pythonhosted.org/packages/08/3d/f5b8dd2512f33bfab4faba71f66f6873603d625212206dd36f12403ae4ca/zope_interface-8.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a16715808408db7252b8c1597ed9008bdad7bf378ed48eb9b0595fad4170e49d", size = 208660, upload-time = "2025-11-15T08:36:53.579Z" }, + { url = "https://files.pythonhosted.org/packages/e5/41/c331adea9b11e05ff9ac4eb7d3032b24c36a3654ae9f2bf4ef2997048211/zope_interface-8.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce6b58752acc3352c4aa0b55bbeae2a941d61537e6afdad2467a624219025aae", size = 208851, upload-time = "2025-11-15T08:36:54.854Z" }, + { url = "https://files.pythonhosted.org/packages/25/00/7a8019c3bb8b119c5f50f0a4869183a4b699ca004a7f87ce98382e6b364c/zope_interface-8.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:807778883d07177713136479de7fd566f9056a13aef63b686f0ab4807c6be259", size = 259292, upload-time = "2025-11-15T08:36:56.409Z" }, + { url = "https://files.pythonhosted.org/packages/1a/fc/b70e963bf89345edffdd5d16b61e789fdc09365972b603e13785360fea6f/zope_interface-8.1.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50e5eb3b504a7d63dc25211b9298071d5b10a3eb754d6bf2f8ef06cb49f807ab", size = 264741, upload-time = "2025-11-15T08:36:57.675Z" }, + { url = "https://files.pythonhosted.org/packages/96/fe/7d0b5c0692b283901b34847f2b2f50d805bfff4b31de4021ac9dfb516d2a/zope_interface-8.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eee6f93b2512ec9466cf30c37548fd3ed7bc4436ab29cd5943d7a0b561f14f0f", size = 264281, upload-time = "2025-11-15T08:36:58.968Z" }, + { url = "https://files.pythonhosted.org/packages/2b/2c/a7cebede1cf2757be158bcb151fe533fa951038cfc5007c7597f9f86804b/zope_interface-8.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:80edee6116d569883c58ff8efcecac3b737733d646802036dc337aa839a5f06b", size = 212327, upload-time = "2025-11-15T08:37:00.4Z" }, + { url = "https://files.pythonhosted.org/packages/85/81/3c3b5386ce4fba4612fd82ffb8a90d76bcfea33ca2b6399f21e94d38484f/zope_interface-8.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:84f9be6d959640de9da5d14ac1f6a89148b16da766e88db37ed17e936160b0b1", size = 209046, upload-time = "2025-11-15T08:37:01.473Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e3/32b7cb950c4c4326b3760a8e28e5d6f70ad15f852bfd8f9364b58634f74b/zope_interface-8.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:531fba91dcb97538f70cf4642a19d6574269460274e3f6004bba6fe684449c51", size = 209104, upload-time = "2025-11-15T08:37:02.887Z" }, + { url = "https://files.pythonhosted.org/packages/a3/3d/c4c68e1752a5f5effa2c1f5eaa4fea4399433c9b058fb7000a34bfb1c447/zope_interface-8.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:fc65f5633d5a9583ee8d88d1f5de6b46cd42c62e47757cfe86be36fb7c8c4c9b", size = 259277, upload-time = "2025-11-15T08:37:04.389Z" }, + { url = "https://files.pythonhosted.org/packages/fd/5b/cf4437b174af7591ee29bbad728f620cab5f47bd6e9c02f87d59f31a0dda/zope_interface-8.1.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efef80ddec4d7d99618ef71bc93b88859248075ca2e1ae1c78636654d3d55533", size = 264742, upload-time = "2025-11-15T08:37:05.613Z" }, + { url = "https://files.pythonhosted.org/packages/0b/0e/0cf77356862852d3d3e62db9aadae5419a1a7d89bf963b219745283ab5ca/zope_interface-8.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49aad83525eca3b4747ef51117d302e891f0042b06f32aa1c7023c62642f962b", size = 264252, upload-time = "2025-11-15T08:37:07.035Z" }, + { url = "https://files.pythonhosted.org/packages/8a/10/2af54aa88b2fa172d12364116cc40d325fedbb1877c3bb031b0da6052855/zope_interface-8.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:71cf329a21f98cb2bd9077340a589e316ac8a415cac900575a32544b3dffcb98", size = 212330, upload-time = "2025-11-15T08:37:08.14Z" }, + { url = "https://files.pythonhosted.org/packages/b9/f5/44efbd98ba06cb937fce7a69fcd7a78c4ac7aa4e1ad2125536801376d2d0/zope_interface-8.1.1-cp314-cp314-macosx_10_9_x86_64.whl", hash = "sha256:da311e9d253991ca327601f47c4644d72359bac6950fbb22f971b24cd7850f8c", size = 209099, upload-time = "2025-11-15T08:37:09.395Z" }, + { url = "https://files.pythonhosted.org/packages/fd/36/a19866c09c8485c36a4c6908e1dd3f8820b41c1ee333c291157cf4cf09e7/zope_interface-8.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3fb25fca0442c7fb93c4ee40b42e3e033fef2f648730c4b7ae6d43222a3e8946", size = 209240, upload-time = "2025-11-15T08:37:10.687Z" }, + { url = "https://files.pythonhosted.org/packages/c1/28/0dbf40db772d779a4ac8d006a57ad60936d42ad4769a3d5410dcfb98f6f9/zope_interface-8.1.1-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:bac588d0742b4e35efb7c7df1dacc0397b51ed37a17d4169a38019a1cebacf0a", size = 260919, upload-time = "2025-11-15T08:37:11.838Z" }, + { url = "https://files.pythonhosted.org/packages/72/ae/650cd4c01dd1b32c26c800b2c4d852f044552c34a56fbb74d41f569cee31/zope_interface-8.1.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d1f053d2d5e2b393e619bce1e55954885c2e63969159aa521839e719442db49", size = 264102, upload-time = "2025-11-15T08:37:13.241Z" }, + { url = "https://files.pythonhosted.org/packages/46/f0/f534a2c34c006aa090c593cd70eaf94e259fd0786f934698d81f0534d907/zope_interface-8.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:64a1ad7f4cb17d948c6bdc525a1d60c0e567b2526feb4fa38b38f249961306b8", size = 264276, upload-time = "2025-11-15T08:37:14.369Z" }, + { url = "https://files.pythonhosted.org/packages/5b/a8/d7e9cf03067b767e23908dbab5f6be7735d70cb4818311a248a8c4bb23cc/zope_interface-8.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:169214da1b82b7695d1a36f92d70b11166d66b6b09d03df35d150cc62ac52276", size = 212492, upload-time = "2025-11-15T08:37:15.538Z" }, ] From a7277432b0f7bcd0551f6e589d30457017125df4 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 7 Jan 2026 08:20:25 -0500 Subject: [PATCH 193/212] Add a changelog entry for 4.26. --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 836fdcdc0..f169513ce 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,8 @@ +v4.26.0 +======= + +* Decrease import time by delaying importing of ``urllib.request`` (#1416). + v4.25.1 ======= From 0e5655c3884c1df030287e224f8fc1eddc4fd636 Mon Sep 17 00:00:00 2001 From: Padmashree S S Date: Wed, 7 Jan 2026 19:44:34 +0530 Subject: [PATCH 194/212] Shortend the comment --- jsonschema/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index d89e17769..2e5d4ca08 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -415,7 +415,7 @@ def by_relevance(weak=WEAK_MATCHES, strong=STRONG_MATCHES): def relevance(error): validator = error.validator return ( # prefer errors which are ... - -len(error.path), # 'higher up' (shorter path) and thereby more general + -len(error.path), # shorter path thereby more general error.path, # earlier (for sibling errors) validator not in weak, # for a non-low-priority keyword validator in strong, # for a high priority keyword From f14220463ed7e0c282207f6d5f2bdcee126a65c9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 18:21:09 +0000 Subject: [PATCH 195/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.10 → v0.14.11](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.10...v0.14.11) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3f3d12e8e..ce66805e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.10 + rev: v0.14.11 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 2bb4ee7cb8cb9438331496a92edfa664f8ab5aa6 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 17 Jan 2026 09:17:19 -0500 Subject: [PATCH 196/212] Add an additional banner warning users about accepting untrusted schemas. --- docs/spelling-wordlist.txt | 1 + docs/validate.rst | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/spelling-wordlist.txt b/docs/spelling-wordlist.txt index 640d56f73..cf9eaf0b5 100644 --- a/docs/spelling-wordlist.txt +++ b/docs/spelling-wordlist.txt @@ -37,6 +37,7 @@ recurses regex repr runtime +sandboxing sensical subclassing submodule diff --git a/docs/validate.rst b/docs/validate.rst index e8b79dbde..4e287e4a3 100644 --- a/docs/validate.rst +++ b/docs/validate.rst @@ -11,16 +11,19 @@ Schema Validation If you aren't already comfortable with writing schemas and need an introduction which teaches about JSON Schema the specification, you may find :ujs:`Understanding JSON Schema ` to be a good read! - The Basics ---------- -The simplest way to validate an instance under a given schema is to use the -`validate ` function. +The simplest way to validate an instance under a given schema is to use the `validate ` function. .. autofunction:: validate :noindex: +.. warning:: + + Accepting untrusted schemas as input, especially when combined with untrusted data to validate, can lead to vulnerabilities even when restricting to official JSON Schema dialects and vocabularies. + Never validate data against schemas from untrusted sources without proper sandboxing or input validation. + .. _validator-protocol: The Validator Protocol From e6f85132c8ef903e34ed7b20196dfabc3e20c78d Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 17 Jan 2026 09:22:01 -0500 Subject: [PATCH 197/212] Update docs requirements. --- docs/requirements.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 2ead6c39e..ed5677ebe 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,7 +4,7 @@ accessible-pygments==0.0.5 # via furo alabaster==1.0.0 # via sphinx -astroid==4.0.2 +astroid==4.0.3 # via sphinx-autoapi attrs==25.4.0 # via @@ -14,11 +14,11 @@ babel==2.17.0 # via sphinx beautifulsoup4==4.14.3 # via furo -certifi==2025.11.12 +certifi==2026.1.4 # via requests charset-normalizer==3.4.4 # via requests -docutils==0.21.2 +docutils==0.22.4 # via sphinx furo==2025.12.19 # via -r docs/requirements.in @@ -69,7 +69,7 @@ snowballstemmer==3.0.1 # via sphinx soupsieve==2.8.1 # via beautifulsoup4 -sphinx==8.2.3 +sphinx==9.1.0 # via # -r docs/requirements.in # furo @@ -82,7 +82,7 @@ sphinx==8.2.3 # sphinxext-opengraph sphinx-autoapi==3.6.1 # via -r docs/requirements.in -sphinx-autodoc-typehints==3.5.2 +sphinx-autodoc-typehints==3.6.2 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo @@ -108,5 +108,5 @@ sphinxext-opengraph==0.13.0 # via -r docs/requirements.in typing-extensions==4.15.0 # via beautifulsoup4 -urllib3==2.6.2 +urllib3==2.6.3 # via requests From 2dbf2ce2d85f56679c67d82955293ddd1d75f77a Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Sat, 17 Jan 2026 10:33:09 -0500 Subject: [PATCH 198/212] Back to Sphinx 8 until we figure out why 9 doesn't work. --- docs/requirements.in | 2 +- docs/requirements.txt | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/requirements.in b/docs/requirements.in index ae66984ae..a3657146b 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,7 +1,7 @@ file:. furo lxml -sphinx!=7.2.5 +sphinx<9 # sphinx 9 appears to have issues I haven't diagnosed sphinx-autoapi sphinx-autodoc-typehints sphinx-copybutton diff --git a/docs/requirements.txt b/docs/requirements.txt index ed5677ebe..4961b37f1 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -18,7 +18,7 @@ certifi==2026.1.4 # via requests charset-normalizer==3.4.4 # via requests -docutils==0.22.4 +docutils==0.21.2 # via sphinx furo==2025.12.19 # via -r docs/requirements.in @@ -60,6 +60,8 @@ requests==2.32.5 # sphinx # sphinxcontrib-spelling roman-numerals==4.1.0 + # via roman-numerals-py +roman-numerals-py==4.1.0 # via sphinx rpds-py==0.30.0 # via @@ -69,7 +71,7 @@ snowballstemmer==3.0.1 # via sphinx soupsieve==2.8.1 # via beautifulsoup4 -sphinx==9.1.0 +sphinx==8.2.3 # via # -r docs/requirements.in # furo @@ -82,7 +84,7 @@ sphinx==9.1.0 # sphinxext-opengraph sphinx-autoapi==3.6.1 # via -r docs/requirements.in -sphinx-autodoc-typehints==3.6.2 +sphinx-autodoc-typehints==3.5.2 # via -r docs/requirements.in sphinx-basic-ng==1.0.0b2 # via furo From 16e3cfae89f8b7514a386642443cd85c104c9d9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 10:42:39 +0000 Subject: [PATCH 199/212] Bump astral-sh/setup-uv from 7.1.6 to 7.2.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.1.6 to 7.2.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/681c641aba71e4a1c380be3ab5e12ad51f415867...61cb8a9741eeb8a550a1b8544337180c0fc8476b) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7c1aa124..8dcd6d86e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -113,7 +113,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] @@ -137,7 +137,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index fa4e4ab26..ac8a51519 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 + uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 763a264a76c33ab4f36a19ecf365ca34c23a98b7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:35:47 +0000 Subject: [PATCH 200/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.11 → v0.14.13](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.11...v0.14.13) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ce66805e3..9067c0c33 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.11 + rev: v0.14.13 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 3757799d5767eb97fca47e6d8c9c063609ad8f0a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 18:24:35 +0000 Subject: [PATCH 201/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.13 → v0.14.14](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.13...v0.14.14) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9067c0c33..4e7698b0b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.13 + rev: v0.14.14 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From c74a7006c416420a12ba2c3f75f295aa3b0066e6 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 11 Feb 2026 07:44:52 -0500 Subject: [PATCH 202/212] Minor style. --- jsonschema/tests/test_validators.py | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index d419ddf8e..7d8a4c5cd 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -839,9 +839,9 @@ def test_anyOf(self): self.assertEqual(e.schema, schema) self.assertIsNone(e.parent) - self.assertEqual(e.path, deque([])) - self.assertEqual(e.relative_path, deque([])) - self.assertEqual(e.absolute_path, deque([])) + self.assertEqual(e.path, deque()) + self.assertEqual(e.relative_path, deque()) + self.assertEqual(e.absolute_path, deque()) self.assertEqual(e.json_path, "$") self.assertEqual(e.schema_path, deque(["anyOf"])) @@ -858,9 +858,9 @@ def test_anyOf(self): self.assertEqual(e1.schema, schema["anyOf"][0]) self.assertIs(e1.parent, e) - self.assertEqual(e1.path, deque([])) - self.assertEqual(e1.absolute_path, deque([])) - self.assertEqual(e1.relative_path, deque([])) + self.assertEqual(e1.path, deque()) + self.assertEqual(e1.absolute_path, deque()) + self.assertEqual(e1.relative_path, deque()) self.assertEqual(e1.json_path, "$") self.assertEqual(e1.schema_path, deque([0, "minimum"])) @@ -877,9 +877,9 @@ def test_anyOf(self): self.assertEqual(e2.schema, schema["anyOf"][1]) self.assertIs(e2.parent, e) - self.assertEqual(e2.path, deque([])) - self.assertEqual(e2.relative_path, deque([])) - self.assertEqual(e2.absolute_path, deque([])) + self.assertEqual(e2.path, deque()) + self.assertEqual(e2.relative_path, deque()) + self.assertEqual(e2.absolute_path, deque()) self.assertEqual(e2.json_path, "$") self.assertEqual(e2.schema_path, deque([1, "type"])) @@ -911,9 +911,9 @@ def test_type(self): self.assertEqual(e.schema, schema) self.assertIsNone(e.parent) - self.assertEqual(e.path, deque([])) - self.assertEqual(e.relative_path, deque([])) - self.assertEqual(e.absolute_path, deque([])) + self.assertEqual(e.path, deque()) + self.assertEqual(e.relative_path, deque()) + self.assertEqual(e.absolute_path, deque()) self.assertEqual(e.json_path, "$") self.assertEqual(e.schema_path, deque(["type"])) @@ -930,9 +930,9 @@ def test_type(self): self.assertEqual(e1.schema, schema["type"][0]) self.assertIs(e1.parent, e) - self.assertEqual(e1.path, deque([])) - self.assertEqual(e1.relative_path, deque([])) - self.assertEqual(e1.absolute_path, deque([])) + self.assertEqual(e1.path, deque()) + self.assertEqual(e1.relative_path, deque()) + self.assertEqual(e1.absolute_path, deque()) self.assertEqual(e1.json_path, "$") self.assertEqual(e1.schema_path, deque([0, "type"])) @@ -1027,7 +1027,7 @@ def test_multiple_nesting(self): errors = validator.iter_errors(instance) e1, e2, e3, e4, e5, e6 = sorted_errors(errors) - self.assertEqual(e1.path, deque([])) + self.assertEqual(e1.path, deque()) self.assertEqual(e2.path, deque([0])) self.assertEqual(e3.path, deque([1, "bar"])) self.assertEqual(e4.path, deque([1, "bar", "bar"])) @@ -1257,7 +1257,7 @@ def test_propertyNames(self): error.message, "'foo' should not be valid under {'const': 'foo'}", ) - self.assertEqual(error.path, deque([])) + self.assertEqual(error.path, deque()) self.assertEqual(error.json_path, "$") self.assertEqual(error.schema_path, deque(["propertyNames", "not"])) @@ -1272,7 +1272,7 @@ def test_if_then(self): self.assertEqual(error.validator, "const") self.assertEqual(error.message, "13 was expected") - self.assertEqual(error.path, deque([])) + self.assertEqual(error.path, deque()) self.assertEqual(error.json_path, "$") self.assertEqual(error.schema_path, deque(["then", "const"])) @@ -1287,7 +1287,7 @@ def test_if_else(self): self.assertEqual(error.validator, "const") self.assertEqual(error.message, "13 was expected") - self.assertEqual(error.path, deque([])) + self.assertEqual(error.path, deque()) self.assertEqual(error.json_path, "$") self.assertEqual(error.schema_path, deque(["else", "const"])) @@ -1311,7 +1311,7 @@ def test_boolean_schema_False(self): None, 12, False, - deque([]), + deque(), "$", ), ) @@ -1472,7 +1472,7 @@ def test_contains_too_many(self): "maxContains", 2, ["foo", 2, "bar", 4, "baz", "quux"], - deque([]), + deque(), {"contains": {"type": "string"}, "maxContains": 2}, deque(["contains"]), "$", @@ -1502,7 +1502,7 @@ def test_contains_too_few(self): "minContains", 2, ["foo", 2, 4], - deque([]), + deque(), {"contains": {"type": "string"}, "minContains": 2}, deque(["contains"]), "$", @@ -1529,7 +1529,7 @@ def test_contains_none(self): "contains", {"type": "string"}, [2, 4], - deque([]), + deque(), {"contains": {"type": "string"}, "minContains": 2}, deque(["contains"]), "$", From 54805e210ba56b55d33a4921a2a5f3c828dd0c26 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Wed, 11 Feb 2026 07:45:45 -0500 Subject: [PATCH 203/212] Bump the uv lockfile. --- uv.lock | 169 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 87 insertions(+), 82 deletions(-) diff --git a/uv.lock b/uv.lock index 38908650c..cbbb98629 100644 --- a/uv.lock +++ b/uv.lock @@ -233,11 +233,11 @@ wheels = [ [[package]] name = "packaging" -version = "25.0" +version = "26.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] [[package]] @@ -477,51 +477,56 @@ wheels = [ [[package]] name = "tomli" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, - { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, - { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, - { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, - { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, - { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, - { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, - { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, - { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, - { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, - { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, - { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, - { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, - { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, - { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, - { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, - { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, - { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, - { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, - { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, - { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, - { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, - { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, - { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, - { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, - { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, - { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, - { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, - { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, - { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, - { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, - { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, - { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, - { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, - { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, - { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, - { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, - { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, - { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, + { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, + { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, + { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, + { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, + { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, + { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, + { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, + { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, + { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, + { url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" }, + { url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" }, + { url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" }, + { url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" }, + { url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" }, + { url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" }, + { url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" }, + { url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" }, + { url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" }, + { url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" }, + { url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" }, + { url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" }, + { url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" }, + { url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" }, + { url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" }, + { url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" }, + { url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" }, + { url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" }, + { url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" }, + { url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" }, + { url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" }, + { url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" }, + { url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" }, + { url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" }, + { url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" }, + { url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" }, + { url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" }, + { url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" }, + { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, ] [[package]] @@ -596,38 +601,38 @@ wheels = [ [[package]] name = "zope-interface" -version = "8.1.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/c9/5ec8679a04d37c797d343f650c51ad67d178f0001c363e44b6ac5f97a9da/zope_interface-8.1.1.tar.gz", hash = "sha256:51b10e6e8e238d719636a401f44f1e366146912407b58453936b781a19be19ec", size = 254748, upload-time = "2025-11-15T08:32:52.404Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d8/ca/77df8f9bcbd8a5e29913c7fef14ff0aadac9448e78dc2606a85d7a23ec6c/zope_interface-8.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c6b12b656c7d7e3d79cad8e2afc4a37eae6b6076e2c209a33345143148e435e", size = 207415, upload-time = "2025-11-15T08:36:36.508Z" }, - { url = "https://files.pythonhosted.org/packages/e1/1f/f1c7828ba3d9b34e65c7e498216fc37ca6e69f1ff1918cca37cd1d895682/zope_interface-8.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:557c0f1363c300db406e9eeaae8ab6d1ba429d4fed60d8ab7dadab5ca66ccd35", size = 207951, upload-time = "2025-11-15T08:36:38.468Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9e/e079035812f06fe1feede1bef753f537fb33d5480d05107f65a51d94e7b3/zope_interface-8.1.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:127b0e4c873752b777721543cf8525b3db5e76b88bd33bab807f03c568e9003f", size = 249409, upload-time = "2025-11-15T08:36:40.148Z" }, - { url = "https://files.pythonhosted.org/packages/c2/09/b7f5a33bd3a17efb31e9e14496e600ab550ab0e38829dcda8a73f017fbfe/zope_interface-8.1.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e0892c9d2dd47b45f62d1861bcae8b427fcc49b4a04fff67f12c5c55e56654d7", size = 254527, upload-time = "2025-11-15T08:36:41.552Z" }, - { url = "https://files.pythonhosted.org/packages/2a/90/0eecd1eab6b62d296dff8445f051e4aa6bd91b67d71cfe9ff9d270b64dbe/zope_interface-8.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff8a92dc8c8a2c605074e464984e25b9b5a8ac9b2a0238dd73a0f374df59a77e", size = 254963, upload-time = "2025-11-15T08:36:42.708Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ff/2fe84fadd13e8adb7b2fb542311c27bad15881be26e37f403df3d0279c74/zope_interface-8.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:54627ddf6034aab1f506ba750dd093f67d353be6249467d720e9f278a578efe5", size = 211809, upload-time = "2025-11-15T08:36:44.43Z" }, - { url = "https://files.pythonhosted.org/packages/77/fc/d84bac27332bdefe8c03f7289d932aeb13a5fd6aeedba72b0aa5b18276ff/zope_interface-8.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e8a0fdd5048c1bb733e4693eae9bc4145a19419ea6a1c95299318a93fe9f3d72", size = 207955, upload-time = "2025-11-15T08:36:45.902Z" }, - { url = "https://files.pythonhosted.org/packages/52/02/e1234eb08b10b5cf39e68372586acc7f7bbcd18176f6046433a8f6b8b263/zope_interface-8.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4cb0ea75a26b606f5bc8524fbce7b7d8628161b6da002c80e6417ce5ec757c0", size = 208398, upload-time = "2025-11-15T08:36:47.016Z" }, - { url = "https://files.pythonhosted.org/packages/3c/be/aabda44d4bc490f9966c2b77fa7822b0407d852cb909b723f2d9e05d2427/zope_interface-8.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:c267b00b5a49a12743f5e1d3b4beef45479d696dab090f11fe3faded078a5133", size = 255079, upload-time = "2025-11-15T08:36:48.157Z" }, - { url = "https://files.pythonhosted.org/packages/d8/7f/4fbc7c2d7cb310e5a91b55db3d98e98d12b262014c1fcad9714fe33c2adc/zope_interface-8.1.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e25d3e2b9299e7ec54b626573673bdf0d740cf628c22aef0a3afef85b438aa54", size = 259850, upload-time = "2025-11-15T08:36:49.544Z" }, - { url = "https://files.pythonhosted.org/packages/fe/2c/dc573fffe59cdbe8bbbdd2814709bdc71c4870893e7226700bc6a08c5e0c/zope_interface-8.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:63db1241804417aff95ac229c13376c8c12752b83cc06964d62581b493e6551b", size = 261033, upload-time = "2025-11-15T08:36:51.061Z" }, - { url = "https://files.pythonhosted.org/packages/0e/51/1ac50e5ee933d9e3902f3400bda399c128a5c46f9f209d16affe3d4facc5/zope_interface-8.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:9639bf4ed07b5277fb231e54109117c30d608254685e48a7104a34618bcbfc83", size = 212215, upload-time = "2025-11-15T08:36:52.553Z" }, - { url = "https://files.pythonhosted.org/packages/08/3d/f5b8dd2512f33bfab4faba71f66f6873603d625212206dd36f12403ae4ca/zope_interface-8.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a16715808408db7252b8c1597ed9008bdad7bf378ed48eb9b0595fad4170e49d", size = 208660, upload-time = "2025-11-15T08:36:53.579Z" }, - { url = "https://files.pythonhosted.org/packages/e5/41/c331adea9b11e05ff9ac4eb7d3032b24c36a3654ae9f2bf4ef2997048211/zope_interface-8.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce6b58752acc3352c4aa0b55bbeae2a941d61537e6afdad2467a624219025aae", size = 208851, upload-time = "2025-11-15T08:36:54.854Z" }, - { url = "https://files.pythonhosted.org/packages/25/00/7a8019c3bb8b119c5f50f0a4869183a4b699ca004a7f87ce98382e6b364c/zope_interface-8.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:807778883d07177713136479de7fd566f9056a13aef63b686f0ab4807c6be259", size = 259292, upload-time = "2025-11-15T08:36:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/1a/fc/b70e963bf89345edffdd5d16b61e789fdc09365972b603e13785360fea6f/zope_interface-8.1.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50e5eb3b504a7d63dc25211b9298071d5b10a3eb754d6bf2f8ef06cb49f807ab", size = 264741, upload-time = "2025-11-15T08:36:57.675Z" }, - { url = "https://files.pythonhosted.org/packages/96/fe/7d0b5c0692b283901b34847f2b2f50d805bfff4b31de4021ac9dfb516d2a/zope_interface-8.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eee6f93b2512ec9466cf30c37548fd3ed7bc4436ab29cd5943d7a0b561f14f0f", size = 264281, upload-time = "2025-11-15T08:36:58.968Z" }, - { url = "https://files.pythonhosted.org/packages/2b/2c/a7cebede1cf2757be158bcb151fe533fa951038cfc5007c7597f9f86804b/zope_interface-8.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:80edee6116d569883c58ff8efcecac3b737733d646802036dc337aa839a5f06b", size = 212327, upload-time = "2025-11-15T08:37:00.4Z" }, - { url = "https://files.pythonhosted.org/packages/85/81/3c3b5386ce4fba4612fd82ffb8a90d76bcfea33ca2b6399f21e94d38484f/zope_interface-8.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:84f9be6d959640de9da5d14ac1f6a89148b16da766e88db37ed17e936160b0b1", size = 209046, upload-time = "2025-11-15T08:37:01.473Z" }, - { url = "https://files.pythonhosted.org/packages/4a/e3/32b7cb950c4c4326b3760a8e28e5d6f70ad15f852bfd8f9364b58634f74b/zope_interface-8.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:531fba91dcb97538f70cf4642a19d6574269460274e3f6004bba6fe684449c51", size = 209104, upload-time = "2025-11-15T08:37:02.887Z" }, - { url = "https://files.pythonhosted.org/packages/a3/3d/c4c68e1752a5f5effa2c1f5eaa4fea4399433c9b058fb7000a34bfb1c447/zope_interface-8.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:fc65f5633d5a9583ee8d88d1f5de6b46cd42c62e47757cfe86be36fb7c8c4c9b", size = 259277, upload-time = "2025-11-15T08:37:04.389Z" }, - { url = "https://files.pythonhosted.org/packages/fd/5b/cf4437b174af7591ee29bbad728f620cab5f47bd6e9c02f87d59f31a0dda/zope_interface-8.1.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efef80ddec4d7d99618ef71bc93b88859248075ca2e1ae1c78636654d3d55533", size = 264742, upload-time = "2025-11-15T08:37:05.613Z" }, - { url = "https://files.pythonhosted.org/packages/0b/0e/0cf77356862852d3d3e62db9aadae5419a1a7d89bf963b219745283ab5ca/zope_interface-8.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49aad83525eca3b4747ef51117d302e891f0042b06f32aa1c7023c62642f962b", size = 264252, upload-time = "2025-11-15T08:37:07.035Z" }, - { url = "https://files.pythonhosted.org/packages/8a/10/2af54aa88b2fa172d12364116cc40d325fedbb1877c3bb031b0da6052855/zope_interface-8.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:71cf329a21f98cb2bd9077340a589e316ac8a415cac900575a32544b3dffcb98", size = 212330, upload-time = "2025-11-15T08:37:08.14Z" }, - { url = "https://files.pythonhosted.org/packages/b9/f5/44efbd98ba06cb937fce7a69fcd7a78c4ac7aa4e1ad2125536801376d2d0/zope_interface-8.1.1-cp314-cp314-macosx_10_9_x86_64.whl", hash = "sha256:da311e9d253991ca327601f47c4644d72359bac6950fbb22f971b24cd7850f8c", size = 209099, upload-time = "2025-11-15T08:37:09.395Z" }, - { url = "https://files.pythonhosted.org/packages/fd/36/a19866c09c8485c36a4c6908e1dd3f8820b41c1ee333c291157cf4cf09e7/zope_interface-8.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3fb25fca0442c7fb93c4ee40b42e3e033fef2f648730c4b7ae6d43222a3e8946", size = 209240, upload-time = "2025-11-15T08:37:10.687Z" }, - { url = "https://files.pythonhosted.org/packages/c1/28/0dbf40db772d779a4ac8d006a57ad60936d42ad4769a3d5410dcfb98f6f9/zope_interface-8.1.1-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:bac588d0742b4e35efb7c7df1dacc0397b51ed37a17d4169a38019a1cebacf0a", size = 260919, upload-time = "2025-11-15T08:37:11.838Z" }, - { url = "https://files.pythonhosted.org/packages/72/ae/650cd4c01dd1b32c26c800b2c4d852f044552c34a56fbb74d41f569cee31/zope_interface-8.1.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d1f053d2d5e2b393e619bce1e55954885c2e63969159aa521839e719442db49", size = 264102, upload-time = "2025-11-15T08:37:13.241Z" }, - { url = "https://files.pythonhosted.org/packages/46/f0/f534a2c34c006aa090c593cd70eaf94e259fd0786f934698d81f0534d907/zope_interface-8.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:64a1ad7f4cb17d948c6bdc525a1d60c0e567b2526feb4fa38b38f249961306b8", size = 264276, upload-time = "2025-11-15T08:37:14.369Z" }, - { url = "https://files.pythonhosted.org/packages/5b/a8/d7e9cf03067b767e23908dbab5f6be7735d70cb4818311a248a8c4bb23cc/zope_interface-8.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:169214da1b82b7695d1a36f92d70b11166d66b6b09d03df35d150cc62ac52276", size = 212492, upload-time = "2025-11-15T08:37:15.538Z" }, +version = "8.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/a4/77daa5ba398996d16bb43fc721599d27d03eae68fe3c799de1963c72e228/zope_interface-8.2.tar.gz", hash = "sha256:afb20c371a601d261b4f6edb53c3c418c249db1a9717b0baafc9a9bb39ba1224", size = 254019, upload-time = "2026-01-09T07:51:07.253Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fa/6d9eb3a33998a3019d7eb4fa1802d01d6602fad90e0aea443e6e0fe8e49a/zope_interface-8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:788c293f3165964ec6527b2d861072c68eef53425213f36d3893ebee89a89623", size = 207541, upload-time = "2026-01-09T08:04:55.378Z" }, + { url = "https://files.pythonhosted.org/packages/19/8c/ad23c96fdee84cb1f768f6695dac187cc26e9038e01c69713ba0f7dc46ab/zope_interface-8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9a4e785097e741a1c953b3970ce28f2823bd63c00adc5d276f2981dd66c96c15", size = 208075, upload-time = "2026-01-09T08:04:57.118Z" }, + { url = "https://files.pythonhosted.org/packages/dd/35/1bfd5fec31a307f0cf4065ee74ade63858ded3e2a71e248f1508118fcc95/zope_interface-8.2-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:16c69da19a06566664ddd4785f37cad5693a51d48df1515d264c20d005d322e2", size = 249528, upload-time = "2026-01-09T08:04:59.074Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3a/5d50b5fdb0f8226a2edff6adb7efdd3762ec95dff827dbab1761cb9a9e85/zope_interface-8.2-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c31acfa3d7cde48bec45701b0e1f4698daffc378f559bfb296837d8c834732f6", size = 254646, upload-time = "2026-01-09T08:05:00.964Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2a/ee7d675e151578eaf77828b8faac2b7ed9a69fead350bf5cf0e4afe7c73d/zope_interface-8.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0723507127f8269b8f3f22663168f717e9c9742107d1b6c9f419df561b71aa6d", size = 255083, upload-time = "2026-01-09T08:05:02.857Z" }, + { url = "https://files.pythonhosted.org/packages/5d/07/99e2342f976c3700e142eddc01524e375a9e9078869a6885d9c72f3a3659/zope_interface-8.2-cp310-cp310-win_amd64.whl", hash = "sha256:3bf73a910bb27344def2d301a03329c559a79b308e1e584686b74171d736be4e", size = 211924, upload-time = "2026-01-09T08:05:04.702Z" }, + { url = "https://files.pythonhosted.org/packages/98/97/9c2aa8caae79915ed64eb114e18816f178984c917aa9adf2a18345e4f2e5/zope_interface-8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c65ade7ea85516e428651048489f5e689e695c79188761de8c622594d1e13322", size = 208081, upload-time = "2026-01-09T08:05:06.623Z" }, + { url = "https://files.pythonhosted.org/packages/34/86/4e2fcb01a8f6780ac84923748e450af0805531f47c0956b83065c99ab543/zope_interface-8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1ef4b43659e1348f35f38e7d1a6bbc1682efde239761f335ffc7e31e798b65b", size = 208522, upload-time = "2026-01-09T08:05:07.986Z" }, + { url = "https://files.pythonhosted.org/packages/f6/eb/08e277da32ddcd4014922854096cf6dcb7081fad415892c2da1bedefbf02/zope_interface-8.2-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:dfc4f44e8de2ff4eba20af4f0a3ca42d3c43ab24a08e49ccd8558b7a4185b466", size = 255198, upload-time = "2026-01-09T08:05:09.532Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a1/b32484f3281a5dc83bc713ad61eca52c543735cdf204543172087a074a74/zope_interface-8.2-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8f094bfb49179ec5dc9981cb769af1275702bd64720ef94874d9e34da1390d4c", size = 259970, upload-time = "2026-01-09T08:05:11.477Z" }, + { url = "https://files.pythonhosted.org/packages/f6/81/bca0e8ae1e487d4093a8a7cfed2118aa2d4758c8cfd66e59d2af09d71f1c/zope_interface-8.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d2bb8e7364e18f083bf6744ccf30433b2a5f236c39c95df8514e3c13007098ce", size = 261153, upload-time = "2026-01-09T08:05:13.402Z" }, + { url = "https://files.pythonhosted.org/packages/40/1e/e3ff2a708011e56b10b271b038d4cb650a8ad5b7d24352fe2edf6d6b187a/zope_interface-8.2-cp311-cp311-win_amd64.whl", hash = "sha256:6f4b4dfcfdfaa9177a600bb31cebf711fdb8c8e9ed84f14c61c420c6aa398489", size = 212330, upload-time = "2026-01-09T08:05:15.267Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a0/1e1fabbd2e9c53ef92b69df6d14f4adc94ec25583b1380336905dc37e9a0/zope_interface-8.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:624b6787fc7c3e45fa401984f6add2c736b70a7506518c3b537ffaacc4b29d4c", size = 208785, upload-time = "2026-01-09T08:05:17.348Z" }, + { url = "https://files.pythonhosted.org/packages/c3/2a/88d098a06975c722a192ef1fb7d623d1b57c6a6997cf01a7aabb45ab1970/zope_interface-8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bc9ded9e97a0ed17731d479596ed1071e53b18e6fdb2fc33af1e43f5fd2d3aaa", size = 208976, upload-time = "2026-01-09T08:05:18.792Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e8/757398549fdfd2f8c89f32c82ae4d2f0537ae2a5d2f21f4a2f711f5a059f/zope_interface-8.2-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:532367553e4420c80c0fc0cabcc2c74080d495573706f66723edee6eae53361d", size = 259411, upload-time = "2026-01-09T08:05:20.567Z" }, + { url = "https://files.pythonhosted.org/packages/91/af/502601f0395ce84dff622f63cab47488657a04d0065547df42bee3a680ff/zope_interface-8.2-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2bf9cf275468bafa3c72688aad8cfcbe3d28ee792baf0b228a1b2d93bd1d541a", size = 264859, upload-time = "2026-01-09T08:05:22.234Z" }, + { url = "https://files.pythonhosted.org/packages/89/0c/d2f765b9b4814a368a7c1b0ac23b68823c6789a732112668072fe596945d/zope_interface-8.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0009d2d3c02ea783045d7804da4fd016245e5c5de31a86cebba66dd6914d59a2", size = 264398, upload-time = "2026-01-09T08:05:23.853Z" }, + { url = "https://files.pythonhosted.org/packages/4a/81/2f171fbc4222066957e6b9220c4fb9146792540102c37e6d94e5d14aad97/zope_interface-8.2-cp312-cp312-win_amd64.whl", hash = "sha256:845d14e580220ae4544bd4d7eb800f0b6034fe5585fc2536806e0a26c2ee6640", size = 212444, upload-time = "2026-01-09T08:05:25.148Z" }, + { url = "https://files.pythonhosted.org/packages/66/47/45188fb101fa060b20e6090e500682398ab415e516a0c228fbb22bc7def2/zope_interface-8.2-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:6068322004a0158c80dfd4708dfb103a899635408c67c3b10e9acec4dbacefec", size = 209170, upload-time = "2026-01-09T08:05:26.616Z" }, + { url = "https://files.pythonhosted.org/packages/09/03/f6b9336c03c2b48403c4eb73a1ec961d94dc2fb5354c583dfb5fa05fd41f/zope_interface-8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2499de92e8275d0dd68f84425b3e19e9268cd1fa8507997900fa4175f157733c", size = 209229, upload-time = "2026-01-09T08:05:28.521Z" }, + { url = "https://files.pythonhosted.org/packages/07/b1/65fe1dca708569f302ade02e6cdca309eab6752bc9f80105514f5b708651/zope_interface-8.2-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:f777e68c76208503609c83ca021a6864902b646530a1a39abb9ed310d1100664", size = 259393, upload-time = "2026-01-09T08:05:29.897Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a5/97b49cfceb6ed53d3dcfb3f3ebf24d83b5553194f0337fbbb3a9fec6cf78/zope_interface-8.2-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9b05a919fdb0ed6ea942e5a7800e09a8b6cdae6f98fee1bef1c9d1a3fc43aaa0", size = 264863, upload-time = "2026-01-09T08:05:31.501Z" }, + { url = "https://files.pythonhosted.org/packages/cb/02/0b7a77292810efe3a0586a505b077ebafd5114e10c6e6e659f0c8e387e1f/zope_interface-8.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ccc62b5712dd7bd64cfba3ee63089fb11e840f5914b990033beeae3b2180b6cb", size = 264369, upload-time = "2026-01-09T08:05:32.941Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1d/0d1ff3846302ed1b5bbf659316d8084b30106770a5f346b7ff4e9f540f80/zope_interface-8.2-cp313-cp313-win_amd64.whl", hash = "sha256:34f877d1d3bb7565c494ed93828fa6417641ca26faf6e8f044e0d0d500807028", size = 212447, upload-time = "2026-01-09T08:05:35.064Z" }, + { url = "https://files.pythonhosted.org/packages/1a/da/3c89de3917751446728b8898b4d53318bc2f8f6bf8196e150a063c59905e/zope_interface-8.2-cp314-cp314-macosx_10_9_x86_64.whl", hash = "sha256:46c7e4e8cbc698398a67e56ca985d19cb92365b4aafbeb6a712e8c101090f4cb", size = 209223, upload-time = "2026-01-09T08:05:36.449Z" }, + { url = "https://files.pythonhosted.org/packages/00/7f/62d00ec53f0a6e5df0c984781e6f3999ed265129c4c3413df8128d1e0207/zope_interface-8.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a87fc7517f825a97ff4a4ca4c8a950593c59e0f8e7bfe1b6f898a38d5ba9f9cf", size = 209366, upload-time = "2026-01-09T08:05:38.197Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a2/f241986315174be8e00aabecfc2153cf8029c1327cab8ed53a9d979d7e08/zope_interface-8.2-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:ccf52f7d44d669203c2096c1a0c2c15d52e36b2e7a9413df50f48392c7d4d080", size = 261037, upload-time = "2026-01-09T08:05:39.568Z" }, + { url = "https://files.pythonhosted.org/packages/02/cc/b321c51d6936ede296a1b8860cf173bee2928357fe1fff7f97234899173f/zope_interface-8.2-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:aae807efc7bd26302eb2fea05cd6de7d59269ed6ae23a6de1ee47add6de99b8c", size = 264219, upload-time = "2026-01-09T08:05:41.624Z" }, + { url = "https://files.pythonhosted.org/packages/ab/fb/5f5e7b40a2f4efd873fe173624795ca47eaa22e29051270c981361b45209/zope_interface-8.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:05a0e42d6d830f547e114de2e7cd15750dc6c0c78f8138e6c5035e51ddfff37c", size = 264390, upload-time = "2026-01-09T08:05:42.936Z" }, + { url = "https://files.pythonhosted.org/packages/f9/82/3f2bc594370bc3abd58e5f9085d263bf682a222f059ed46275cde0570810/zope_interface-8.2-cp314-cp314-win_amd64.whl", hash = "sha256:561ce42390bee90bae51cf1c012902a8033b2aaefbd0deed81e877562a116d48", size = 212585, upload-time = "2026-01-09T08:05:44.419Z" }, ] From 526ae719f2530040a47a4c0791f437cb53ff464b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 10:04:11 +0000 Subject: [PATCH 204/212] Bump astral-sh/setup-uv from 7.2.0 to 7.3.0 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.2.0 to 7.3.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/61cb8a9741eeb8a550a1b8544337180c0fc8476b...eac588ad8def6316056a12d4907a9d4d84ff7a3b) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8dcd6d86e..b61d89bb7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b + uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -113,7 +113,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b + uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] @@ -137,7 +137,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b + uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index ac8a51519..0fe8d7a55 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b + uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From 447654a61da3204b03e31ee6238f27af8d928cc8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:16:58 +0000 Subject: [PATCH 205/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.14 → v0.15.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.14...v0.15.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e7698b0b..e4d305f5a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.14 + rev: v0.15.1 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 0061353db1dbfc9be82a6501b1456a295fc5597e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 18:32:07 +0000 Subject: [PATCH 206/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.15.1 → v0.15.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.1...v0.15.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e4d305f5a..a16adf9c6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.1 + rev: v0.15.2 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From a6f6ddf6c266c2aa4f40a86433c255ce752803e7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 18:35:13 +0000 Subject: [PATCH 207/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.15.2 → v0.15.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.2...v0.15.4) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a16adf9c6..4a94f6591 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.2 + rev: v0.15.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 520784a04384aeeec0806416965c1bcffcfb4f59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 09:59:06 +0000 Subject: [PATCH 208/212] Bump astral-sh/setup-uv from 7.3.0 to 7.3.1 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.3.0 to 7.3.1. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/eac588ad8def6316056a12d4907a9d4d84ff7a3b...5a095e7a2014a4212f075830d4f7277575a9d098) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 7.3.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- .github/workflows/zizmor.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b61d89bb7..0b46be871 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: with: persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b + uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] - id: noxenvs-matrix @@ -113,7 +113,7 @@ jobs: if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests') - name: Set up uv - uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b + uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] @@ -137,7 +137,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Set up uv - uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b + uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 with: enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning] diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 0fe8d7a55..82556d88e 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -20,7 +20,7 @@ jobs: persist-credentials: false - name: Install uv - uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b + uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 - name: Run zizmor 🌈 run: uvx zizmor --format=sarif .github > results.sarif From bb3d8b7e90e6d0f5d6b37050cb2cc50b0ac42630 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:42:41 +0000 Subject: [PATCH 209/212] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.15.4 → v0.15.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.4...v0.15.5) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4a94f6591..a9601e3db 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.4 + rev: v0.15.5 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From fb5750db7f0f6c378ea33e1b04c387062a89baa2 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 27 Mar 2026 22:07:42 -0300 Subject: [PATCH 210/212] Zenodo appears to have started returning 403s... --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 4f8d9f157..ec04c0d3f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -87,6 +87,7 @@ def entire_domain(host): linkcheck_ignore = [ + entire_domain("zenodo.org"), entire_domain("img.shields.io"), "https://github.com/python-jsonschema/jsonschema/actions", "https://github.com/python-jsonschema/jsonschema/workflows/CI/badge.svg", From bbc17d3ca9cf70c605444d4d74a96c27dbed0bfa Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 27 Mar 2026 22:08:08 -0300 Subject: [PATCH 211/212] Style noise. --- .pre-commit-config.yaml | 2 +- jsonschema/benchmarks/import_benchmark.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9601e3db..2eebcd398 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: [--fix, lf] - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.5 + rev: v0.15.8 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/jsonschema/benchmarks/import_benchmark.py b/jsonschema/benchmarks/import_benchmark.py index 59fa921dd..e3aac70ba 100644 --- a/jsonschema/benchmarks/import_benchmark.py +++ b/jsonschema/benchmarks/import_benchmark.py @@ -9,7 +9,7 @@ def import_time(loops): total_us = 0 for _ in range(loops): - p = subprocess.run( # noqa: S603 (arguments are static) + p = subprocess.run( [sys.executable, "-X", "importtime", "-c", "import jsonschema"], stderr=subprocess.PIPE, stdout=subprocess.DEVNULL, From b747e59151ce8652e7860fc9e0639aa78676a5b1 Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Fri, 27 Mar 2026 22:09:04 -0300 Subject: [PATCH 212/212] Update dependencies. --- docs/requirements.txt | 20 +++---- uv.lock | 130 +++++++++++++++++++----------------------- 2 files changed, 69 insertions(+), 81 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 4961b37f1..d27e4ca07 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,19 +4,19 @@ accessible-pygments==0.0.5 # via furo alabaster==1.0.0 # via sphinx -astroid==4.0.3 +astroid==4.1.2 # via sphinx-autoapi -attrs==25.4.0 +attrs==26.1.0 # via # jsonschema # referencing -babel==2.17.0 +babel==2.18.0 # via sphinx beautifulsoup4==4.14.3 # via furo -certifi==2026.1.4 +certifi==2026.2.25 # via requests -charset-normalizer==3.4.4 +charset-normalizer==3.4.6 # via requests docutils==0.21.2 # via sphinx @@ -24,7 +24,7 @@ furo==2025.12.19 # via -r docs/requirements.in idna==3.11 # via requests -imagesize==1.4.1 +imagesize==2.0.0 # via sphinx jinja2==3.1.6 # via @@ -40,7 +40,7 @@ lxml==6.0.2 # sphinx-json-schema-spec markupsafe==3.0.3 # via jinja2 -packaging==25.0 +packaging==26.0 # via sphinx pyenchant==3.3.0 # via sphinxcontrib-spelling @@ -55,7 +55,7 @@ referencing==0.37.0 # via # jsonschema # jsonschema-specifications -requests==2.32.5 +requests==2.33.0 # via # sphinx # sphinxcontrib-spelling @@ -69,7 +69,7 @@ rpds-py==0.30.0 # referencing snowballstemmer==3.0.1 # via sphinx -soupsieve==2.8.1 +soupsieve==2.8.3 # via beautifulsoup4 sphinx==8.2.3 # via @@ -82,7 +82,7 @@ sphinx==8.2.3 # sphinx-json-schema-spec # sphinxcontrib-spelling # sphinxext-opengraph -sphinx-autoapi==3.6.1 +sphinx-autoapi==3.8.0 # via -r docs/requirements.in sphinx-autodoc-typehints==3.5.2 # via -r docs/requirements.in diff --git a/uv.lock b/uv.lock index cbbb98629..e450c3f57 100644 --- a/uv.lock +++ b/uv.lock @@ -17,11 +17,11 @@ wheels = [ [[package]] name = "attrs" -version = "25.4.0" +version = "26.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, ] [[package]] @@ -120,23 +120,20 @@ wheels = [ [[package]] name = "jsonpath-ng" -version = "1.7.0" +version = "1.8.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ply" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6d/86/08646239a313f895186ff0a4573452038eed8c86f54380b3ebac34d32fb2/jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c", size = 37838, upload-time = "2024-10-11T15:41:42.404Z" } +sdist = { url = "https://files.pythonhosted.org/packages/32/58/250751940d75c8019659e15482d548a4aa3b6ce122c515102a4bfdac50e3/jsonpath_ng-1.8.0.tar.gz", hash = "sha256:54252968134b5e549ea5b872f1df1168bd7defe1a52fed5a358c194e1943ddc3", size = 74513, upload-time = "2026-02-24T14:42:06.182Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/5a/73ecb3d82f8615f32ccdadeb9356726d6cae3a4bbc840b437ceb95708063/jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6", size = 30105, upload-time = "2024-11-20T17:58:30.418Z" }, + { url = "https://files.pythonhosted.org/packages/03/99/33c7d78a3fb70d545fd5411ac67a651c81602cc09c9cf0df383733f068c5/jsonpath_ng-1.8.0-py3-none-any.whl", hash = "sha256:b8dde192f8af58d646fc031fac9c99fe4d00326afc4148f1f043c601a8cfe138", size = 67844, upload-time = "2026-02-28T00:53:19.637Z" }, ] [[package]] name = "jsonpointer" -version = "3.0.0" +version = "3.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/c7/af399a2e7a67fd18d63c40c5e62d3af4e67b836a2107468b6a5ea24c4304/jsonpointer-3.1.1.tar.gz", hash = "sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900", size = 9068, upload-time = "2026-03-23T22:32:32.458Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6a/a83720e953b1682d2d109d3c2dbb0bc9bf28cc1cbc205be4ef4be5da709d/jsonpointer-3.1.1-py3-none-any.whl", hash = "sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca", size = 7659, upload-time = "2026-03-23T22:32:31.568Z" }, ] [[package]] @@ -240,15 +237,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] -[[package]] -name = "ply" -version = "3.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e5/69/882ee5c9d017149285cab114ebeab373308ef0f874fcdac9beb90e0ac4da/ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3", size = 159130, upload-time = "2018-02-15T19:01:31.097Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce", size = 49567, upload-time = "2018-02-15T19:01:27.172Z" }, -] - [[package]] name = "pyrsistent" version = "0.20.0" @@ -477,56 +465,56 @@ wheels = [ [[package]] name = "tomli" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, - { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, - { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, - { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, - { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, - { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, - { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, - { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, - { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, - { url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" }, - { url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" }, - { url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" }, - { url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" }, - { url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" }, - { url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" }, - { url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" }, - { url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" }, - { url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" }, - { url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" }, - { url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" }, - { url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" }, - { url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" }, - { url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" }, - { url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" }, - { url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" }, - { url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" }, - { url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" }, - { url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" }, - { url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" }, - { url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" }, - { url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" }, - { url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" }, - { url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" }, - { url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" }, - { url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" }, - { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, ] [[package]]