Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace $ref & $dynamicRef support / RefResolver with the new referencing library #1049

Merged
merged 33 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0ce3cef
Drop support for 3.7.
Julian Dec 28, 2022
bf94d57
Move to retrieving schemas from the jsonschema-specifications registry.
Julian Dec 28, 2022
238e711
Deprecate jsonschema.RefResolver from both places it is importable.
Julian Dec 29, 2022
f6aa053
Load the test suite into a referencing.Registry for running tests.
Julian Feb 9, 2023
2c8f643
Minor regrouping of some to-be-modified/deprecated RefResolver tests.
Julian Feb 9, 2023
52340d7
Offload a small initial bit of id-related code to referencing.
Julian Feb 14, 2023
4ec24ab
Inline a function that will be RefResolver specific.
Julian Feb 15, 2023
9da55df
Move reference resolution to a (private) Validator method.
Julian Feb 15, 2023
635dc13
Deprecate Validator.resolver.
Julian Feb 15, 2023
69f3899
Actually depend on referencing and update docs requirements.
Julian Feb 16, 2023
2889feb
Make an evolve test not refer to reference resolution.
Julian Feb 16, 2023
a39e5c9
Move Validator._resolver to _ref_resolver.
Julian Feb 16, 2023
e826629
Resolve $ref using the referencing library.
Julian Feb 16, 2023
a93e88b
Claim full support now that we pass all referencing tests.
Julian Feb 16, 2023
bdda723
Flail to get Sphinx to find references again.
Julian Feb 16, 2023
a42bbd9
Fix the benchmark to pass the right type for remotes again.
Julian Feb 16, 2023
bd6a7d0
Update docs requirements.
Julian Feb 19, 2023
33e2882
Pin to newer pyrsistent.
Julian Feb 21, 2023
fcea5ad
Tighten up a type in the tests.
Julian Feb 21, 2023
34d19dc
Add some prose documentation on the new referencing API.
Julian Feb 22, 2023
8c4cd7c
These pass now actually.
Julian Feb 22, 2023
e922e79
Style
Julian Feb 22, 2023
25f40e5
Again bump the referencing version.
Julian Feb 23, 2023
787dbc9
Re-add the direct test of RefResolver's deprecation.
Julian Feb 23, 2023
3801d9a
Improve error messages for deprecation tests when they fail.
Julian Feb 23, 2023
19bdf61
Three more exception-related deprecations.
Julian Feb 23, 2023
84199e9
Elaborate a bit more in the referencing doc
Julian Feb 27, 2023
eb00447
Replace the other usages of pyrsistent with rpds.
Julian Mar 5, 2023
2b547c7
Avoid whatever nonsense pkg_resources error.
Julian Mar 6, 2023
94c60e4
Speed up Validator.evolve by pre-computing fields.
Julian Mar 6, 2023
1854b26
Bump requirements.
Julian Mar 8, 2023
4d6bff9
Link to the new referencing doc page.
Julian Mar 9, 2023
fcbeced
Another version bump.
Julian Mar 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@ jobs:
toxenv: pypy3-formatnongpl-build
- name: pypy-3.9
toxenv: pypy3-formatnongpl-tests
- name: 3.7
toxenv: py37-noextra-build
- name: 3.7
toxenv: py37-noextra-tests
- name: 3.7
toxenv: py37-format-build
- name: 3.7
toxenv: py37-format-tests
- name: 3.7
toxenv: py37-formatnongpl-build
- name: 3.7
toxenv: py37-formatnongpl-tests
- name: 3.8
toxenv: py38-noextra-build
- name: 3.8
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
v4.18.0
=======

* ``jsonschema.RefResolver`` is now deprecated in favor of the new `referencing library <https://github.com/python-jsonschema/referencing/>`_.
``referencing`` will begin in beta, but already is more compliant than the existing ``$ref`` support.
Please file issues on the ``referencing`` tracker if there is functionality missing from it.

v4.17.3
=======

Expand Down
3 changes: 1 addition & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ It can also be used from the command line by installing `check-jsonschema <https
Features
--------

* Partial support for `Draft 2020-12 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft202012Validator>`_ and `Draft 2019-09 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft201909Validator>`_, except for ``dynamicRef`` / ``recursiveRef`` and ``$vocabulary`` (in-progress).
Full support for `Draft 7 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft7Validator>`_, `Draft 6 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft6Validator>`_, `Draft 4 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft4Validator>`_ and `Draft 3 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft3Validator>`_
* Full support for `Draft 2020-12 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft202012Validator>`_, `Draft 2019-09 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft201909Validator>`_, `Draft 7 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft7Validator>`_, `Draft 6 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft6Validator>`_, `Draft 4 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft4Validator>`_ and `Draft 3 <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/validators/#jsonschema.validators.Draft3Validator>`_

* `Lazy validation <https://python-jsonschema.readthedocs.io/en/latest/api/jsonschema/protocols/#jsonschema.protocols.Validator.iter_errors>`_ that can iteratively report *all* validation errors.

Expand Down
1 change: 1 addition & 0 deletions docs/api/jsonschema/validators/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
.. automodule:: jsonschema.validators
:members:
:undoc-members:
:private-members: _RefResolver
28 changes: 18 additions & 10 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,36 @@

# See sphinx-doc/sphinx#10785
_TYPE_ALIASES = {
"jsonschema._format._F", # format checkers
"jsonschema._format._F": ("data", "_F"),
}


def _resolve_type_aliases(app, env, node, contnode):
if (
node["refdomain"] == "py"
and node["reftype"] == "class"
and node["reftarget"] in _TYPE_ALIASES
):
def _resolve_broken_refs(app, env, node, contnode):
if node["refdomain"] != "py":
return

if node["reftarget"].startswith("referencing."): # :( :( :( :( :(
node["reftype"] = "data"
from sphinx.ext import intersphinx
return intersphinx.resolve_reference_in_inventory(
env, "referencing", node, contnode,
)

kind, target = _TYPE_ALIASES.get(node["reftarget"], (None, None))
if kind is not None:
return app.env.get_domain("py").resolve_xref(
env,
node["refdoc"],
app.builder,
"data",
node["reftarget"],
kind,
target,
node,
contnode,
)


def setup(app):
app.connect("missing-reference", _resolve_type_aliases)
app.connect("missing-reference", _resolve_broken_refs)


# = Builders =
Expand Down Expand Up @@ -116,6 +123,7 @@ def entire_domain(host):

intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
"referencing": ("https://referencing.readthedocs.io/en/stable/", None),
"ujs": ("https://json-schema.org/understanding-json-schema/", None),
}

Expand Down
1 change: 1 addition & 0 deletions docs/errors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ error objects.

.. testcode::

from jsonschema.exceptions import ErrorTree
tree = ErrorTree(v.iter_errors(instance))

As you can see, `jsonschema.exceptions.ErrorTree` takes an
Expand Down
57 changes: 2 additions & 55 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,10 @@ The JSON object ``{}`` is simply the Python `dict` ``{}``, and a JSON Schema lik

The :kw:`$ref` keyword is a single notable exception.

Specifically, in the case where `jsonschema` is asked to `resolve a remote reference <jsonschema.validators.RefResolver>`, it has no choice but to assume that the remote reference is serialized as JSON, and to deserialize it using the `json` module.
Specifically, in the case where `jsonschema` is asked to resolve a remote reference, it has no choice but to assume that the remote reference is serialized as JSON, and to deserialize it using the `json` module.

One cannot today therefore reference some remote piece of YAML and have it deserialized into Python objects by this library without doing some additional work.
See `Resolving References to Schemas Written in YAML <referencing:Resolving References to Schemas Written in YAML>` for details.

In practice what this means for JSON-like formats like YAML and TOML is that indeed one can generally schematize and then validate them exactly as if they were JSON by simply first deserializing them using libraries like ``PyYAML`` or the like, and passing the resulting Python objects into functions within this library.

Expand All @@ -99,60 +100,6 @@ In such cases one is recommended to first pre-process the data such that the res
In the previous example, if the desired behavior is to transparently coerce numeric properties to strings, as Javascript might, then do the conversion explicitly before passing data to this library.


How do I configure a base URI for $ref resolution using local files?
--------------------------------------------------------------------

`jsonschema` supports loading schemas from the filesystem.

The most common mistake when configuring a `jsonschema.validators.RefResolver`
to retrieve schemas from the local filesystem is to give it a base URI
which points to a directory, but forget to add a trailing slash.

For example, given a directory ``/tmp/foo/`` with ``bar/schema.json``
within it, you should use something like:

.. code-block:: python

from pathlib import Path

import jsonschema.validators

path = Path("/tmp/foo")
resolver = jsonschema.validators.RefResolver(
base_uri=f"{path.as_uri()}/",
referrer=True,
)
jsonschema.validate(
instance={},
schema={"$ref": "bar/schema.json"},
resolver=resolver,
)

where note:

* the base URI has a trailing slash, even though
`pathlib.PurePath.as_uri` does not add it!
* any relative refs are now given relative to the provided directory

If you forget the trailing slash, you'll find references are resolved a
directory too high.

You're likely familiar with this behavior from your browser. If you
visit a page at ``https://example.com/foo``, then links on it like
``<a href="./bar">`` take you to ``https://example.com/bar``, not
``https://example.com/foo/bar``. For this reason many sites will
redirect ``https://example.com/foo`` to ``https://example.com/foo/``,
i.e. add the trailing slash, so that relative links on the page will keep the
last path component.

There are, in summary, 2 ways to do this properly:

* Remember to include a trailing slash, so your base URI is
``file:///foo/bar/`` rather than ``file:///foo/bar``, as shown above
* Use a file within the directory as your base URI rather than the
directory itself, i.e. ``file://foo/bar/baz.json``, which will of course
cause ``baz.json`` to be removed while resolving relative URIs

Why doesn't my schema's default property set the default on my instance?
------------------------------------------------------------------------

Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Contents

validate
errors
referencing
creating
faq
api/index
Expand Down
Loading