├── .github ├── FUNDING.yml ├── SECURITY.md ├── dependabot.yml ├── release.yml └── workflows │ └── ci.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yml ├── COPYING ├── README.rst ├── docs ├── Makefile ├── api.rst ├── conf.py ├── index.rst ├── requirements.in ├── requirements.txt └── spelling-wordlist.txt ├── jsonschema_specifications ├── __init__.py ├── _core.py ├── schemas │ ├── draft201909 │ │ ├── metaschema.json │ │ └── vocabularies │ │ │ ├── applicator │ │ │ ├── content │ │ │ ├── core │ │ │ ├── meta-data │ │ │ └── validation │ ├── draft202012 │ │ ├── metaschema.json │ │ └── vocabularies │ │ │ ├── applicator │ │ │ ├── content │ │ │ ├── core │ │ │ ├── format │ │ │ ├── format-annotation │ │ │ ├── format-assertion │ │ │ ├── meta-data │ │ │ ├── unevaluated │ │ │ └── validation │ ├── draft3 │ │ └── metaschema.json │ ├── draft4 │ │ └── metaschema.json │ ├── draft6 │ │ └── metaschema.json │ └── draft7 │ │ └── metaschema.json └── tests │ ├── __init__.py │ └── test_jsonschema_specifications.py ├── noxfile.py └── pyproject.toml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: "Julian" 4 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | In general, only the latest released `jsonschema-specifications` version is supported and will receive updates. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | To report a security vulnerability, please send an email to `Julian+Security` at `GrayVines.com` with subject line `SECURITY (jsonschema-specifications)`. 10 | 11 | I will do my best to respond within 48 hours to acknowledge the message and discuss further steps. 12 | 13 | If the vulnerability is accepted, an advisory will be sent out via GitHub's security advisory functionality. 14 | 15 | For non-sensitive discussion related to this policy itself, feel free to open an issue on the issue tracker. 16 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | authors: 4 | - dependabot 5 | - pre-commit-ci 6 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - "wip*" 7 | tags: 8 | - "v*" 9 | pull_request: 10 | schedule: 11 | # Daily at 6:43 12 | - cron: "43 6 * * *" 13 | workflow_dispatch: 14 | 15 | jobs: 16 | list: 17 | runs-on: ubuntu-latest 18 | outputs: 19 | noxenvs: ${{ steps.noxenvs-matrix.outputs.noxenvs }} 20 | steps: 21 | - uses: actions/checkout@v4 22 | - name: Set up nox 23 | uses: wntrblm/nox@2025.02.09 24 | - id: noxenvs-matrix 25 | run: | 26 | echo >>$GITHUB_OUTPUT noxenvs=$( 27 | nox --list-sessions --json | jq '[.[].session]' 28 | ) 29 | 30 | ci: 31 | needs: list 32 | runs-on: ${{ matrix.os }} 33 | 34 | strategy: 35 | fail-fast: false 36 | matrix: 37 | os: [macos-latest, ubuntu-latest] 38 | noxenv: ${{ fromJson(needs.list.outputs.noxenvs) }} 39 | 40 | steps: 41 | - uses: actions/checkout@v4 42 | - name: Install dependencies 43 | run: sudo apt-get update && sudo apt-get install -y libenchant-2-dev 44 | if: runner.os == 'Linux' && startsWith(matrix.noxenv, 'docs') 45 | - name: Install dependencies 46 | run: brew install enchant 47 | if: runner.os == 'macOS' && startsWith(matrix.noxenv, 'docs') 48 | - name: Set up Python 49 | uses: actions/setup-python@v5 50 | with: 51 | python-version: | 52 | 3.9 53 | 3.10 54 | 3.11 55 | 3.12 56 | 3.13 57 | pypy3.10 58 | allow-prereleases: true 59 | 60 | - name: Set up uv 61 | uses: hynek/setup-cached-uv@v2 62 | - name: Set up nox 63 | uses: wntrblm/nox@2025.02.09 64 | 65 | - name: Run nox 66 | run: nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }} 67 | 68 | packaging: 69 | needs: ci 70 | runs-on: ubuntu-latest 71 | environment: 72 | name: PyPI 73 | url: https://pypi.org/p/jsonschema-specifications 74 | 75 | permissions: 76 | contents: write 77 | id-token: write 78 | 79 | steps: 80 | - uses: actions/checkout@v4 81 | - name: Set up Python 82 | uses: actions/setup-python@v5 83 | with: 84 | python-version: "3.x" 85 | - name: Set up uv 86 | uses: hynek/setup-cached-uv@v2 87 | - name: Install dependencies 88 | run: uv pip install --system build 89 | 90 | - name: Create packages 91 | run: python -m build . 92 | 93 | - name: Publish to PyPI 94 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') 95 | uses: pypa/gh-action-pypi-publish@release/v1 96 | - name: Create a Release 97 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') 98 | uses: softprops/action-gh-release@v2 99 | with: 100 | files: | 101 | dist/* 102 | generate_release_notes: true 103 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 110 | .pdm.toml 111 | .pdm-python 112 | .pdm-build/ 113 | 114 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 115 | __pypackages__/ 116 | 117 | # Celery stuff 118 | celerybeat-schedule 119 | celerybeat.pid 120 | 121 | # SageMath parsed files 122 | *.sage.py 123 | 124 | # Environments 125 | .env 126 | .venv 127 | env/ 128 | venv/ 129 | ENV/ 130 | env.bak/ 131 | venv.bak/ 132 | 133 | # Spyder project settings 134 | .spyderproject 135 | .spyproject 136 | 137 | # Rope project settings 138 | .ropeproject 139 | 140 | # mkdocs documentation 141 | /site 142 | 143 | # mypy 144 | .mypy_cache/ 145 | .dmypy.json 146 | dmypy.json 147 | 148 | # Pyre type checker 149 | .pyre/ 150 | 151 | # pytype static type analyzer 152 | .pytype/ 153 | 154 | # Cython debug symbols 155 | cython_debug/ 156 | 157 | # PyCharm 158 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 159 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 160 | # and can be added to the global gitignore or merged into this file. For a more nuclear 161 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 162 | #.idea/ 163 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | exclude: jsonschema_specifications/schemas/ 2 | 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v5.0.0 6 | hooks: 7 | - id: check-ast 8 | - id: check-json 9 | - id: check-toml 10 | - id: check-vcs-permalinks 11 | - id: check-yaml 12 | - id: debug-statements 13 | - id: end-of-file-fixer 14 | - id: mixed-line-ending 15 | args: [--fix, lf] 16 | - id: trailing-whitespace 17 | - repo: https://github.com/astral-sh/ruff-pre-commit 18 | rev: "v0.11.6" 19 | hooks: 20 | - id: ruff 21 | args: [--fix, --exit-non-zero-on-fix] 22 | - repo: https://github.com/psf/black 23 | rev: 25.1.0 24 | hooks: 25 | - name: black 26 | id: black 27 | args: ["--line-length", "79"] 28 | - repo: https://github.com/pre-commit/mirrors-prettier 29 | rev: "v4.0.0-alpha.8" 30 | hooks: 31 | - id: prettier 32 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | build: 4 | os: ubuntu-22.04 5 | tools: 6 | python: "3.11" 7 | 8 | sphinx: 9 | builder: dirhtml 10 | configuration: docs/conf.py 11 | fail_on_warning: true 12 | 13 | formats: all 14 | 15 | python: 16 | install: 17 | - requirements: docs/requirements.txt 18 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 Julian Berman 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | ``jsonschema-specifications`` 3 | ============================= 4 | 5 | |PyPI| |Pythons| |CI| |ReadTheDocs| 6 | 7 | JSON support files from the `JSON Schema Specifications `_ (metaschemas, vocabularies, etc.), packaged for runtime access from Python as a `referencing-based Schema Registry `_. 8 | 9 | .. |PyPI| image:: https://img.shields.io/pypi/v/jsonschema-specifications.svg 10 | :alt: PyPI version 11 | :target: https://pypi.org/project/jsonschema-specifications/ 12 | 13 | .. |Pythons| image:: https://img.shields.io/pypi/pyversions/jsonschema-specifications.svg 14 | :alt: Supported Python versions 15 | :target: https://pypi.org/project/jsonschema-specifications/ 16 | 17 | .. |CI| image:: https://github.com/python-jsonschema/jsonschema-specifications/workflows/CI/badge.svg 18 | :alt: Build status 19 | :target: https://github.com/python-jsonschema/jsonschema-specifications/actions?query=workflow%3ACI 20 | 21 | .. |ReadTheDocs| image:: https://readthedocs.org/projects/jsonschema-specifications/badge/?version=stable&style=flat 22 | :alt: ReadTheDocs status 23 | :target: https://jsonschema-specifications.readthedocs.io/en/stable/ 24 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============= 3 | 4 | .. automodule:: jsonschema_specifications 5 | :members: 6 | :undoc-members: 7 | :imported-members: 8 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | import importlib.metadata 2 | import re 3 | 4 | HOMEPAGE = "https://github.com/python-jsonschema/jsonschema-specifications" 5 | 6 | project = "jsonschema-specifications" 7 | author = "Julian Berman" 8 | copyright = f"2022, {author}" 9 | 10 | release = importlib.metadata.version("jsonschema-specifications") 11 | version = release.partition("-")[0] 12 | 13 | language = "en" 14 | default_role = "any" 15 | 16 | extensions = [ 17 | "sphinx.ext.autodoc", 18 | "sphinx.ext.autosectionlabel", 19 | "sphinx.ext.coverage", 20 | "sphinx.ext.doctest", 21 | "sphinx.ext.intersphinx", 22 | "sphinx.ext.napoleon", 23 | "sphinx.ext.viewcode", 24 | "sphinx_copybutton", 25 | "sphinxcontrib.spelling", 26 | "sphinxext.opengraph", 27 | ] 28 | 29 | pygments_style = "lovelace" 30 | pygments_dark_style = "one-dark" 31 | 32 | html_theme = "furo" 33 | 34 | # = Builders = 35 | 36 | 37 | def entire_domain(host): 38 | return r"http.?://" + re.escape(host) + r"($|/.*)" 39 | 40 | 41 | linkcheck_ignore = [ 42 | entire_domain("img.shields.io"), 43 | f"{HOMEPAGE}/actions", 44 | f"{HOMEPAGE}/workflows/CI/badge.svg", 45 | ] 46 | 47 | # = Extensions = 48 | 49 | # -- autodoc -- 50 | 51 | autodoc_default_options = { 52 | "members": True, 53 | "member-order": "bysource", 54 | } 55 | 56 | # -- autosectionlabel -- 57 | 58 | autosectionlabel_prefix_document = True 59 | 60 | # -- intersphinx -- 61 | 62 | intersphinx_mapping = { 63 | "python": ("https://docs.python.org/3", None), 64 | "referencing": ("https://referencing.readthedocs.io/en/latest/", None), 65 | } 66 | 67 | # -- sphinxcontrib-spelling -- 68 | 69 | spelling_word_list_filename = "spelling-wordlist.txt" 70 | spelling_show_suggestions = True 71 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | 3 | Resources are exposed via a `referencing.Registry`. 4 | 5 | The purpose of this package is to provide these schemas via an explicit public API. 6 | In other words, if you're authoring schemas, or building JSON Schema tooling, or otherwise need access to the JSON Schema official metaschemas and vocabularies, they're exposed here for runtime use in a way that doesn't require you to copy them, or to reach into the data files of a Python package you didn't necessarily author. 7 | 8 | Usage 9 | ----- 10 | 11 | There is essentially one main object provided, `jsonschema_specifications.REGISTRY`, which is a `referencing.Registry` (or more specifically a `referencing.jsonschema.SchemaRegistry`) containing all of the "official" JSON Schemas. 12 | 13 | For full details on using it, see the `referencing documentation `, but for example: 14 | 15 | .. code:: 16 | 17 | from jsonschema_specifications import REGISTRY as SPECIFICATIONS 18 | 19 | DRAFT202012_DIALECT_URI = "https://json-schema.org/draft/2020-12/schema" 20 | print(SPECIFICATIONS.contents(DRAFT202012_DIALECT_URI)) 21 | 22 | # -> prints the Draft 2020-12 meta-schema 23 | 24 | 25 | Contents 26 | -------- 27 | 28 | .. toctree:: 29 | :glob: 30 | :maxdepth: 2 31 | 32 | api 33 | -------------------------------------------------------------------------------- /docs/requirements.in: -------------------------------------------------------------------------------- 1 | file:.#egg=jsonschema_specifications 2 | furo 3 | pygments-github-lexers 4 | sphinx-copybutton 5 | sphinx>5 6 | sphinxcontrib-spelling>5 7 | sphinxext-opengraph 8 | 9 | # Until pyenchant/pyenchant#302 is released... 10 | pyenchant>=3.3.0rc1 11 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by uv via the following command: 2 | # uv pip compile --output-file /Users/julian/Development/jsonschema-specifications/docs/requirements.txt docs/requirements.in 3 | alabaster==1.0.0 4 | # via sphinx 5 | attrs==24.3.0 6 | # via referencing 7 | babel==2.16.0 8 | # via sphinx 9 | beautifulsoup4==4.12.3 10 | # via furo 11 | certifi==2024.12.14 12 | # via requests 13 | charset-normalizer==3.4.1 14 | # via requests 15 | docutils==0.21.2 16 | # via sphinx 17 | furo==2024.8.6 18 | # via -r docs/requirements.in 19 | idna==3.10 20 | # via requests 21 | imagesize==1.4.1 22 | # via sphinx 23 | jinja2==3.1.5 24 | # via sphinx 25 | jsonschema-specifications @ file:.#egg=jsonschema_specifications 26 | # via -r docs/requirements.in 27 | markupsafe==3.0.2 28 | # via jinja2 29 | packaging==24.2 30 | # via sphinx 31 | pyenchant==3.3.0rc1 32 | # via 33 | # -r docs/requirements.in 34 | # sphinxcontrib-spelling 35 | pygments==2.19.1 36 | # via 37 | # furo 38 | # pygments-github-lexers 39 | # sphinx 40 | pygments-github-lexers==0.0.5 41 | # via -r docs/requirements.in 42 | referencing==0.35.1 43 | # via jsonschema-specifications 44 | requests==2.32.3 45 | # via 46 | # sphinx 47 | # sphinxcontrib-spelling 48 | rpds-py==0.22.3 49 | # via referencing 50 | snowballstemmer==2.2.0 51 | # via sphinx 52 | soupsieve==2.6 53 | # via beautifulsoup4 54 | sphinx==8.1.3 55 | # via 56 | # -r docs/requirements.in 57 | # furo 58 | # sphinx-basic-ng 59 | # sphinx-copybutton 60 | # sphinxcontrib-spelling 61 | # sphinxext-opengraph 62 | sphinx-basic-ng==1.0.0b2 63 | # via furo 64 | sphinx-copybutton==0.5.2 65 | # via -r docs/requirements.in 66 | sphinxcontrib-applehelp==2.0.0 67 | # via sphinx 68 | sphinxcontrib-devhelp==2.0.0 69 | # via sphinx 70 | sphinxcontrib-htmlhelp==2.1.0 71 | # via sphinx 72 | sphinxcontrib-jsmath==1.0.1 73 | # via sphinx 74 | sphinxcontrib-qthelp==2.0.0 75 | # via sphinx 76 | sphinxcontrib-serializinghtml==2.0.0 77 | # via sphinx 78 | sphinxcontrib-spelling==8.0.1 79 | # via -r docs/requirements.in 80 | sphinxext-opengraph==0.9.1 81 | # via -r docs/requirements.in 82 | urllib3==2.3.0 83 | # via requests 84 | -------------------------------------------------------------------------------- /docs/spelling-wordlist.txt: -------------------------------------------------------------------------------- 1 | metaschemas 2 | runtime 3 | schemas 4 | -------------------------------------------------------------------------------- /jsonschema_specifications/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | The JSON Schema meta-schemas and vocabularies, exposed as a Registry. 3 | """ 4 | 5 | from referencing.jsonschema import EMPTY_REGISTRY as _EMPTY_REGISTRY 6 | 7 | from jsonschema_specifications._core import _schemas 8 | 9 | #: A `referencing.jsonschema.SchemaRegistry` containing all of the official 10 | #: meta-schemas and vocabularies. 11 | REGISTRY = (_schemas() @ _EMPTY_REGISTRY).crawl() 12 | __all__ = ["REGISTRY"] 13 | -------------------------------------------------------------------------------- /jsonschema_specifications/_core.py: -------------------------------------------------------------------------------- 1 | """ 2 | Load all the JSON Schema specification's official schemas. 3 | """ 4 | 5 | import json 6 | 7 | try: 8 | from importlib.resources import files 9 | except ImportError: 10 | from importlib_resources import ( # type: ignore[import-not-found, no-redef] 11 | files, 12 | ) 13 | 14 | from referencing import Resource 15 | 16 | 17 | def _schemas(): 18 | """ 19 | All schemas we ship. 20 | """ 21 | # importlib.resources.abc.Traversal doesn't have nice ways to do this that 22 | # I'm aware of... 23 | # 24 | # It can't recurse arbitrarily, e.g. no ``.glob()``. 25 | # 26 | # So this takes some liberties given the real layout of what we ship 27 | # (only 2 levels of nesting, no directories within the second level). 28 | 29 | for version in files(__package__).joinpath("schemas").iterdir(): 30 | if version.name.startswith("."): 31 | continue 32 | for child in version.iterdir(): 33 | children = [child] if child.is_file() else child.iterdir() 34 | for path in children: 35 | if path.name.startswith("."): 36 | continue 37 | contents = json.loads(path.read_text(encoding="utf-8")) 38 | yield Resource.from_contents(contents) 39 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft201909/metaschema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://json-schema.org/draft/2019-09/schema", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2019-09/vocab/core": true, 6 | "https://json-schema.org/draft/2019-09/vocab/applicator": true, 7 | "https://json-schema.org/draft/2019-09/vocab/validation": true, 8 | "https://json-schema.org/draft/2019-09/vocab/meta-data": true, 9 | "https://json-schema.org/draft/2019-09/vocab/format": false, 10 | "https://json-schema.org/draft/2019-09/vocab/content": true 11 | }, 12 | "$recursiveAnchor": true, 13 | 14 | "title": "Core and Validation specifications meta-schema", 15 | "allOf": [ 16 | {"$ref": "meta/core"}, 17 | {"$ref": "meta/applicator"}, 18 | {"$ref": "meta/validation"}, 19 | {"$ref": "meta/meta-data"}, 20 | {"$ref": "meta/format"}, 21 | {"$ref": "meta/content"} 22 | ], 23 | "type": ["object", "boolean"], 24 | "properties": { 25 | "definitions": { 26 | "$comment": "While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.", 27 | "type": "object", 28 | "additionalProperties": { "$recursiveRef": "#" }, 29 | "default": {} 30 | }, 31 | "dependencies": { 32 | "$comment": "\"dependencies\" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to \"dependentSchemas\" and \"dependentRequired\"", 33 | "type": "object", 34 | "additionalProperties": { 35 | "anyOf": [ 36 | { "$recursiveRef": "#" }, 37 | { "$ref": "meta/validation#/$defs/stringArray" } 38 | ] 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft201909/vocabularies/applicator: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://json-schema.org/draft/2019-09/meta/applicator", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2019-09/vocab/applicator": true 6 | }, 7 | "$recursiveAnchor": true, 8 | 9 | "title": "Applicator vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "additionalItems": { "$recursiveRef": "#" }, 13 | "unevaluatedItems": { "$recursiveRef": "#" }, 14 | "items": { 15 | "anyOf": [ 16 | { "$recursiveRef": "#" }, 17 | { "$ref": "#/$defs/schemaArray" } 18 | ] 19 | }, 20 | "contains": { "$recursiveRef": "#" }, 21 | "additionalProperties": { "$recursiveRef": "#" }, 22 | "unevaluatedProperties": { "$recursiveRef": "#" }, 23 | "properties": { 24 | "type": "object", 25 | "additionalProperties": { "$recursiveRef": "#" }, 26 | "default": {} 27 | }, 28 | "patternProperties": { 29 | "type": "object", 30 | "additionalProperties": { "$recursiveRef": "#" }, 31 | "propertyNames": { "format": "regex" }, 32 | "default": {} 33 | }, 34 | "dependentSchemas": { 35 | "type": "object", 36 | "additionalProperties": { 37 | "$recursiveRef": "#" 38 | } 39 | }, 40 | "propertyNames": { "$recursiveRef": "#" }, 41 | "if": { "$recursiveRef": "#" }, 42 | "then": { "$recursiveRef": "#" }, 43 | "else": { "$recursiveRef": "#" }, 44 | "allOf": { "$ref": "#/$defs/schemaArray" }, 45 | "anyOf": { "$ref": "#/$defs/schemaArray" }, 46 | "oneOf": { "$ref": "#/$defs/schemaArray" }, 47 | "not": { "$recursiveRef": "#" } 48 | }, 49 | "$defs": { 50 | "schemaArray": { 51 | "type": "array", 52 | "minItems": 1, 53 | "items": { "$recursiveRef": "#" } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft201909/vocabularies/content: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://json-schema.org/draft/2019-09/meta/content", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2019-09/vocab/content": true 6 | }, 7 | "$recursiveAnchor": true, 8 | 9 | "title": "Content vocabulary meta-schema", 10 | 11 | "type": ["object", "boolean"], 12 | "properties": { 13 | "contentMediaType": { "type": "string" }, 14 | "contentEncoding": { "type": "string" }, 15 | "contentSchema": { "$recursiveRef": "#" } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft201909/vocabularies/core: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://json-schema.org/draft/2019-09/meta/core", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2019-09/vocab/core": true 6 | }, 7 | "$recursiveAnchor": true, 8 | 9 | "title": "Core vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "$id": { 13 | "type": "string", 14 | "format": "uri-reference", 15 | "$comment": "Non-empty fragments not allowed.", 16 | "pattern": "^[^#]*#?$" 17 | }, 18 | "$schema": { 19 | "type": "string", 20 | "format": "uri" 21 | }, 22 | "$anchor": { 23 | "type": "string", 24 | "pattern": "^[A-Za-z][-A-Za-z0-9.:_]*$" 25 | }, 26 | "$ref": { 27 | "type": "string", 28 | "format": "uri-reference" 29 | }, 30 | "$recursiveRef": { 31 | "type": "string", 32 | "format": "uri-reference" 33 | }, 34 | "$recursiveAnchor": { 35 | "type": "boolean", 36 | "default": false 37 | }, 38 | "$vocabulary": { 39 | "type": "object", 40 | "propertyNames": { 41 | "type": "string", 42 | "format": "uri" 43 | }, 44 | "additionalProperties": { 45 | "type": "boolean" 46 | } 47 | }, 48 | "$comment": { 49 | "type": "string" 50 | }, 51 | "$defs": { 52 | "type": "object", 53 | "additionalProperties": { "$recursiveRef": "#" }, 54 | "default": {} 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft201909/vocabularies/meta-data: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://json-schema.org/draft/2019-09/meta/meta-data", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2019-09/vocab/meta-data": true 6 | }, 7 | "$recursiveAnchor": true, 8 | 9 | "title": "Meta-data vocabulary meta-schema", 10 | 11 | "type": ["object", "boolean"], 12 | "properties": { 13 | "title": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "default": true, 20 | "deprecated": { 21 | "type": "boolean", 22 | "default": false 23 | }, 24 | "readOnly": { 25 | "type": "boolean", 26 | "default": false 27 | }, 28 | "writeOnly": { 29 | "type": "boolean", 30 | "default": false 31 | }, 32 | "examples": { 33 | "type": "array", 34 | "items": true 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft201909/vocabularies/validation: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://json-schema.org/draft/2019-09/meta/validation", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2019-09/vocab/validation": true 6 | }, 7 | "$recursiveAnchor": true, 8 | 9 | "title": "Validation vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "multipleOf": { 13 | "type": "number", 14 | "exclusiveMinimum": 0 15 | }, 16 | "maximum": { 17 | "type": "number" 18 | }, 19 | "exclusiveMaximum": { 20 | "type": "number" 21 | }, 22 | "minimum": { 23 | "type": "number" 24 | }, 25 | "exclusiveMinimum": { 26 | "type": "number" 27 | }, 28 | "maxLength": { "$ref": "#/$defs/nonNegativeInteger" }, 29 | "minLength": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, 30 | "pattern": { 31 | "type": "string", 32 | "format": "regex" 33 | }, 34 | "maxItems": { "$ref": "#/$defs/nonNegativeInteger" }, 35 | "minItems": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, 36 | "uniqueItems": { 37 | "type": "boolean", 38 | "default": false 39 | }, 40 | "maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, 41 | "minContains": { 42 | "$ref": "#/$defs/nonNegativeInteger", 43 | "default": 1 44 | }, 45 | "maxProperties": { "$ref": "#/$defs/nonNegativeInteger" }, 46 | "minProperties": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, 47 | "required": { "$ref": "#/$defs/stringArray" }, 48 | "dependentRequired": { 49 | "type": "object", 50 | "additionalProperties": { 51 | "$ref": "#/$defs/stringArray" 52 | } 53 | }, 54 | "const": true, 55 | "enum": { 56 | "type": "array", 57 | "items": true 58 | }, 59 | "type": { 60 | "anyOf": [ 61 | { "$ref": "#/$defs/simpleTypes" }, 62 | { 63 | "type": "array", 64 | "items": { "$ref": "#/$defs/simpleTypes" }, 65 | "minItems": 1, 66 | "uniqueItems": true 67 | } 68 | ] 69 | } 70 | }, 71 | "$defs": { 72 | "nonNegativeInteger": { 73 | "type": "integer", 74 | "minimum": 0 75 | }, 76 | "nonNegativeIntegerDefault0": { 77 | "$ref": "#/$defs/nonNegativeInteger", 78 | "default": 0 79 | }, 80 | "simpleTypes": { 81 | "enum": [ 82 | "array", 83 | "boolean", 84 | "integer", 85 | "null", 86 | "number", 87 | "object", 88 | "string" 89 | ] 90 | }, 91 | "stringArray": { 92 | "type": "array", 93 | "items": { "type": "string" }, 94 | "uniqueItems": true, 95 | "default": [] 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/metaschema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/schema", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/core": true, 6 | "https://json-schema.org/draft/2020-12/vocab/applicator": true, 7 | "https://json-schema.org/draft/2020-12/vocab/unevaluated": true, 8 | "https://json-schema.org/draft/2020-12/vocab/validation": true, 9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true, 10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true, 11 | "https://json-schema.org/draft/2020-12/vocab/content": true 12 | }, 13 | "$dynamicAnchor": "meta", 14 | 15 | "title": "Core and Validation specifications meta-schema", 16 | "allOf": [ 17 | {"$ref": "meta/core"}, 18 | {"$ref": "meta/applicator"}, 19 | {"$ref": "meta/unevaluated"}, 20 | {"$ref": "meta/validation"}, 21 | {"$ref": "meta/meta-data"}, 22 | {"$ref": "meta/format-annotation"}, 23 | {"$ref": "meta/content"} 24 | ], 25 | "type": ["object", "boolean"], 26 | "$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.", 27 | "properties": { 28 | "definitions": { 29 | "$comment": "\"definitions\" has been replaced by \"$defs\".", 30 | "type": "object", 31 | "additionalProperties": { "$dynamicRef": "#meta" }, 32 | "deprecated": true, 33 | "default": {} 34 | }, 35 | "dependencies": { 36 | "$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.", 37 | "type": "object", 38 | "additionalProperties": { 39 | "anyOf": [ 40 | { "$dynamicRef": "#meta" }, 41 | { "$ref": "meta/validation#/$defs/stringArray" } 42 | ] 43 | }, 44 | "deprecated": true, 45 | "default": {} 46 | }, 47 | "$recursiveAnchor": { 48 | "$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".", 49 | "$ref": "meta/core#/$defs/anchorString", 50 | "deprecated": true 51 | }, 52 | "$recursiveRef": { 53 | "$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".", 54 | "$ref": "meta/core#/$defs/uriReferenceString", 55 | "deprecated": true 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/applicator: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/applicator", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/applicator": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Applicator vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "prefixItems": { "$ref": "#/$defs/schemaArray" }, 13 | "items": { "$dynamicRef": "#meta" }, 14 | "contains": { "$dynamicRef": "#meta" }, 15 | "additionalProperties": { "$dynamicRef": "#meta" }, 16 | "properties": { 17 | "type": "object", 18 | "additionalProperties": { "$dynamicRef": "#meta" }, 19 | "default": {} 20 | }, 21 | "patternProperties": { 22 | "type": "object", 23 | "additionalProperties": { "$dynamicRef": "#meta" }, 24 | "propertyNames": { "format": "regex" }, 25 | "default": {} 26 | }, 27 | "dependentSchemas": { 28 | "type": "object", 29 | "additionalProperties": { "$dynamicRef": "#meta" }, 30 | "default": {} 31 | }, 32 | "propertyNames": { "$dynamicRef": "#meta" }, 33 | "if": { "$dynamicRef": "#meta" }, 34 | "then": { "$dynamicRef": "#meta" }, 35 | "else": { "$dynamicRef": "#meta" }, 36 | "allOf": { "$ref": "#/$defs/schemaArray" }, 37 | "anyOf": { "$ref": "#/$defs/schemaArray" }, 38 | "oneOf": { "$ref": "#/$defs/schemaArray" }, 39 | "not": { "$dynamicRef": "#meta" } 40 | }, 41 | "$defs": { 42 | "schemaArray": { 43 | "type": "array", 44 | "minItems": 1, 45 | "items": { "$dynamicRef": "#meta" } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/content: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/content", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/content": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Content vocabulary meta-schema", 10 | 11 | "type": ["object", "boolean"], 12 | "properties": { 13 | "contentEncoding": { "type": "string" }, 14 | "contentMediaType": { "type": "string" }, 15 | "contentSchema": { "$dynamicRef": "#meta" } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/core: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/core", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/core": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Core vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "$id": { 13 | "$ref": "#/$defs/uriReferenceString", 14 | "$comment": "Non-empty fragments not allowed.", 15 | "pattern": "^[^#]*#?$" 16 | }, 17 | "$schema": { "$ref": "#/$defs/uriString" }, 18 | "$ref": { "$ref": "#/$defs/uriReferenceString" }, 19 | "$anchor": { "$ref": "#/$defs/anchorString" }, 20 | "$dynamicRef": { "$ref": "#/$defs/uriReferenceString" }, 21 | "$dynamicAnchor": { "$ref": "#/$defs/anchorString" }, 22 | "$vocabulary": { 23 | "type": "object", 24 | "propertyNames": { "$ref": "#/$defs/uriString" }, 25 | "additionalProperties": { 26 | "type": "boolean" 27 | } 28 | }, 29 | "$comment": { 30 | "type": "string" 31 | }, 32 | "$defs": { 33 | "type": "object", 34 | "additionalProperties": { "$dynamicRef": "#meta" } 35 | } 36 | }, 37 | "$defs": { 38 | "anchorString": { 39 | "type": "string", 40 | "pattern": "^[A-Za-z_][-A-Za-z0-9._]*$" 41 | }, 42 | "uriString": { 43 | "type": "string", 44 | "format": "uri" 45 | }, 46 | "uriReferenceString": { 47 | "type": "string", 48 | "format": "uri-reference" 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/format: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2019-09/schema", 3 | "$id": "https://json-schema.org/draft/2019-09/meta/format", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2019-09/vocab/format": true 6 | }, 7 | "$recursiveAnchor": true, 8 | 9 | "title": "Format vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "format": { "type": "string" } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/format-annotation: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/format-annotation", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Format vocabulary meta-schema for annotation results", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "format": { "type": "string" } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/format-assertion: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/format-assertion", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/format-assertion": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Format vocabulary meta-schema for assertion results", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "format": { "type": "string" } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/meta-data: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/meta-data", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Meta-data vocabulary meta-schema", 10 | 11 | "type": ["object", "boolean"], 12 | "properties": { 13 | "title": { 14 | "type": "string" 15 | }, 16 | "description": { 17 | "type": "string" 18 | }, 19 | "default": true, 20 | "deprecated": { 21 | "type": "boolean", 22 | "default": false 23 | }, 24 | "readOnly": { 25 | "type": "boolean", 26 | "default": false 27 | }, 28 | "writeOnly": { 29 | "type": "boolean", 30 | "default": false 31 | }, 32 | "examples": { 33 | "type": "array", 34 | "items": true 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/unevaluated: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/unevaluated", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/unevaluated": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Unevaluated applicator vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "unevaluatedItems": { "$dynamicRef": "#meta" }, 13 | "unevaluatedProperties": { "$dynamicRef": "#meta" } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft202012/vocabularies/validation: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json-schema.org/draft/2020-12/schema", 3 | "$id": "https://json-schema.org/draft/2020-12/meta/validation", 4 | "$vocabulary": { 5 | "https://json-schema.org/draft/2020-12/vocab/validation": true 6 | }, 7 | "$dynamicAnchor": "meta", 8 | 9 | "title": "Validation vocabulary meta-schema", 10 | "type": ["object", "boolean"], 11 | "properties": { 12 | "type": { 13 | "anyOf": [ 14 | { "$ref": "#/$defs/simpleTypes" }, 15 | { 16 | "type": "array", 17 | "items": { "$ref": "#/$defs/simpleTypes" }, 18 | "minItems": 1, 19 | "uniqueItems": true 20 | } 21 | ] 22 | }, 23 | "const": true, 24 | "enum": { 25 | "type": "array", 26 | "items": true 27 | }, 28 | "multipleOf": { 29 | "type": "number", 30 | "exclusiveMinimum": 0 31 | }, 32 | "maximum": { 33 | "type": "number" 34 | }, 35 | "exclusiveMaximum": { 36 | "type": "number" 37 | }, 38 | "minimum": { 39 | "type": "number" 40 | }, 41 | "exclusiveMinimum": { 42 | "type": "number" 43 | }, 44 | "maxLength": { "$ref": "#/$defs/nonNegativeInteger" }, 45 | "minLength": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, 46 | "pattern": { 47 | "type": "string", 48 | "format": "regex" 49 | }, 50 | "maxItems": { "$ref": "#/$defs/nonNegativeInteger" }, 51 | "minItems": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, 52 | "uniqueItems": { 53 | "type": "boolean", 54 | "default": false 55 | }, 56 | "maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, 57 | "minContains": { 58 | "$ref": "#/$defs/nonNegativeInteger", 59 | "default": 1 60 | }, 61 | "maxProperties": { "$ref": "#/$defs/nonNegativeInteger" }, 62 | "minProperties": { "$ref": "#/$defs/nonNegativeIntegerDefault0" }, 63 | "required": { "$ref": "#/$defs/stringArray" }, 64 | "dependentRequired": { 65 | "type": "object", 66 | "additionalProperties": { 67 | "$ref": "#/$defs/stringArray" 68 | } 69 | } 70 | }, 71 | "$defs": { 72 | "nonNegativeInteger": { 73 | "type": "integer", 74 | "minimum": 0 75 | }, 76 | "nonNegativeIntegerDefault0": { 77 | "$ref": "#/$defs/nonNegativeInteger", 78 | "default": 0 79 | }, 80 | "simpleTypes": { 81 | "enum": [ 82 | "array", 83 | "boolean", 84 | "integer", 85 | "null", 86 | "number", 87 | "object", 88 | "string" 89 | ] 90 | }, 91 | "stringArray": { 92 | "type": "array", 93 | "items": { "type": "string" }, 94 | "uniqueItems": true, 95 | "default": [] 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft3/metaschema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema" : "http://json-schema.org/draft-03/schema#", 3 | "id" : "http://json-schema.org/draft-03/schema#", 4 | "type" : "object", 5 | 6 | "properties" : { 7 | "type" : { 8 | "type" : ["string", "array"], 9 | "items" : { 10 | "type" : ["string", {"$ref" : "#"}] 11 | }, 12 | "uniqueItems" : true, 13 | "default" : "any" 14 | }, 15 | 16 | "properties" : { 17 | "type" : "object", 18 | "additionalProperties" : {"$ref" : "#"}, 19 | "default" : {} 20 | }, 21 | 22 | "patternProperties" : { 23 | "type" : "object", 24 | "additionalProperties" : {"$ref" : "#"}, 25 | "default" : {} 26 | }, 27 | 28 | "additionalProperties" : { 29 | "type" : [{"$ref" : "#"}, "boolean"], 30 | "default" : {} 31 | }, 32 | 33 | "items" : { 34 | "type" : [{"$ref" : "#"}, "array"], 35 | "items" : {"$ref" : "#"}, 36 | "default" : {} 37 | }, 38 | 39 | "additionalItems" : { 40 | "type" : [{"$ref" : "#"}, "boolean"], 41 | "default" : {} 42 | }, 43 | 44 | "required" : { 45 | "type" : "boolean", 46 | "default" : false 47 | }, 48 | 49 | "dependencies" : { 50 | "type" : "object", 51 | "additionalProperties" : { 52 | "type" : ["string", "array", {"$ref" : "#"}], 53 | "items" : { 54 | "type" : "string" 55 | } 56 | }, 57 | "default" : {} 58 | }, 59 | 60 | "minimum" : { 61 | "type" : "number" 62 | }, 63 | 64 | "maximum" : { 65 | "type" : "number" 66 | }, 67 | 68 | "exclusiveMinimum" : { 69 | "type" : "boolean", 70 | "default" : false 71 | }, 72 | 73 | "exclusiveMaximum" : { 74 | "type" : "boolean", 75 | "default" : false 76 | }, 77 | 78 | "minItems" : { 79 | "type" : "integer", 80 | "minimum" : 0, 81 | "default" : 0 82 | }, 83 | 84 | "maxItems" : { 85 | "type" : "integer", 86 | "minimum" : 0 87 | }, 88 | 89 | "uniqueItems" : { 90 | "type" : "boolean", 91 | "default" : false 92 | }, 93 | 94 | "pattern" : { 95 | "type" : "string", 96 | "format" : "regex" 97 | }, 98 | 99 | "minLength" : { 100 | "type" : "integer", 101 | "minimum" : 0, 102 | "default" : 0 103 | }, 104 | 105 | "maxLength" : { 106 | "type" : "integer" 107 | }, 108 | 109 | "enum" : { 110 | "type" : "array", 111 | "minItems" : 1, 112 | "uniqueItems" : true 113 | }, 114 | 115 | "default" : { 116 | "type" : "any" 117 | }, 118 | 119 | "title" : { 120 | "type" : "string" 121 | }, 122 | 123 | "description" : { 124 | "type" : "string" 125 | }, 126 | 127 | "format" : { 128 | "type" : "string" 129 | }, 130 | 131 | "divisibleBy" : { 132 | "type" : "number", 133 | "minimum" : 0, 134 | "exclusiveMinimum" : true, 135 | "default" : 1 136 | }, 137 | 138 | "disallow" : { 139 | "type" : ["string", "array"], 140 | "items" : { 141 | "type" : ["string", {"$ref" : "#"}] 142 | }, 143 | "uniqueItems" : true 144 | }, 145 | 146 | "extends" : { 147 | "type" : [{"$ref" : "#"}, "array"], 148 | "items" : {"$ref" : "#"}, 149 | "default" : {} 150 | }, 151 | 152 | "id" : { 153 | "type" : "string" 154 | }, 155 | 156 | "$ref" : { 157 | "type" : "string" 158 | }, 159 | 160 | "$schema" : { 161 | "type" : "string", 162 | "format" : "uri" 163 | } 164 | }, 165 | 166 | "dependencies" : { 167 | "exclusiveMinimum" : "minimum", 168 | "exclusiveMaximum" : "maximum" 169 | }, 170 | 171 | "default" : {} 172 | } 173 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft4/metaschema.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "http://json-schema.org/draft-04/schema#", 3 | "$schema": "http://json-schema.org/draft-04/schema#", 4 | "description": "Core schema meta-schema", 5 | "definitions": { 6 | "schemaArray": { 7 | "type": "array", 8 | "minItems": 1, 9 | "items": { "$ref": "#" } 10 | }, 11 | "positiveInteger": { 12 | "type": "integer", 13 | "minimum": 0 14 | }, 15 | "positiveIntegerDefault0": { 16 | "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ] 17 | }, 18 | "simpleTypes": { 19 | "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] 20 | }, 21 | "stringArray": { 22 | "type": "array", 23 | "items": { "type": "string" }, 24 | "minItems": 1, 25 | "uniqueItems": true 26 | } 27 | }, 28 | "type": "object", 29 | "properties": { 30 | "id": { 31 | "type": "string" 32 | }, 33 | "$schema": { 34 | "type": "string" 35 | }, 36 | "title": { 37 | "type": "string" 38 | }, 39 | "description": { 40 | "type": "string" 41 | }, 42 | "default": {}, 43 | "multipleOf": { 44 | "type": "number", 45 | "minimum": 0, 46 | "exclusiveMinimum": true 47 | }, 48 | "maximum": { 49 | "type": "number" 50 | }, 51 | "exclusiveMaximum": { 52 | "type": "boolean", 53 | "default": false 54 | }, 55 | "minimum": { 56 | "type": "number" 57 | }, 58 | "exclusiveMinimum": { 59 | "type": "boolean", 60 | "default": false 61 | }, 62 | "maxLength": { "$ref": "#/definitions/positiveInteger" }, 63 | "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" }, 64 | "pattern": { 65 | "type": "string", 66 | "format": "regex" 67 | }, 68 | "additionalItems": { 69 | "anyOf": [ 70 | { "type": "boolean" }, 71 | { "$ref": "#" } 72 | ], 73 | "default": {} 74 | }, 75 | "items": { 76 | "anyOf": [ 77 | { "$ref": "#" }, 78 | { "$ref": "#/definitions/schemaArray" } 79 | ], 80 | "default": {} 81 | }, 82 | "maxItems": { "$ref": "#/definitions/positiveInteger" }, 83 | "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" }, 84 | "uniqueItems": { 85 | "type": "boolean", 86 | "default": false 87 | }, 88 | "maxProperties": { "$ref": "#/definitions/positiveInteger" }, 89 | "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" }, 90 | "required": { "$ref": "#/definitions/stringArray" }, 91 | "additionalProperties": { 92 | "anyOf": [ 93 | { "type": "boolean" }, 94 | { "$ref": "#" } 95 | ], 96 | "default": {} 97 | }, 98 | "definitions": { 99 | "type": "object", 100 | "additionalProperties": { "$ref": "#" }, 101 | "default": {} 102 | }, 103 | "properties": { 104 | "type": "object", 105 | "additionalProperties": { "$ref": "#" }, 106 | "default": {} 107 | }, 108 | "patternProperties": { 109 | "type": "object", 110 | "additionalProperties": { "$ref": "#" }, 111 | "default": {} 112 | }, 113 | "dependencies": { 114 | "type": "object", 115 | "additionalProperties": { 116 | "anyOf": [ 117 | { "$ref": "#" }, 118 | { "$ref": "#/definitions/stringArray" } 119 | ] 120 | } 121 | }, 122 | "enum": { 123 | "type": "array", 124 | "minItems": 1, 125 | "uniqueItems": true 126 | }, 127 | "type": { 128 | "anyOf": [ 129 | { "$ref": "#/definitions/simpleTypes" }, 130 | { 131 | "type": "array", 132 | "items": { "$ref": "#/definitions/simpleTypes" }, 133 | "minItems": 1, 134 | "uniqueItems": true 135 | } 136 | ] 137 | }, 138 | "format": { "type": "string" }, 139 | "allOf": { "$ref": "#/definitions/schemaArray" }, 140 | "anyOf": { "$ref": "#/definitions/schemaArray" }, 141 | "oneOf": { "$ref": "#/definitions/schemaArray" }, 142 | "not": { "$ref": "#" } 143 | }, 144 | "dependencies": { 145 | "exclusiveMaximum": [ "maximum" ], 146 | "exclusiveMinimum": [ "minimum" ] 147 | }, 148 | "default": {} 149 | } 150 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft6/metaschema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-06/schema#", 3 | "$id": "http://json-schema.org/draft-06/schema#", 4 | "title": "Core schema meta-schema", 5 | "definitions": { 6 | "schemaArray": { 7 | "type": "array", 8 | "minItems": 1, 9 | "items": { "$ref": "#" } 10 | }, 11 | "nonNegativeInteger": { 12 | "type": "integer", 13 | "minimum": 0 14 | }, 15 | "nonNegativeIntegerDefault0": { 16 | "allOf": [ 17 | { "$ref": "#/definitions/nonNegativeInteger" }, 18 | { "default": 0 } 19 | ] 20 | }, 21 | "simpleTypes": { 22 | "enum": [ 23 | "array", 24 | "boolean", 25 | "integer", 26 | "null", 27 | "number", 28 | "object", 29 | "string" 30 | ] 31 | }, 32 | "stringArray": { 33 | "type": "array", 34 | "items": { "type": "string" }, 35 | "uniqueItems": true, 36 | "default": [] 37 | } 38 | }, 39 | "type": ["object", "boolean"], 40 | "properties": { 41 | "$id": { 42 | "type": "string", 43 | "format": "uri-reference" 44 | }, 45 | "$schema": { 46 | "type": "string", 47 | "format": "uri" 48 | }, 49 | "$ref": { 50 | "type": "string", 51 | "format": "uri-reference" 52 | }, 53 | "title": { 54 | "type": "string" 55 | }, 56 | "description": { 57 | "type": "string" 58 | }, 59 | "default": {}, 60 | "examples": { 61 | "type": "array", 62 | "items": {} 63 | }, 64 | "multipleOf": { 65 | "type": "number", 66 | "exclusiveMinimum": 0 67 | }, 68 | "maximum": { 69 | "type": "number" 70 | }, 71 | "exclusiveMaximum": { 72 | "type": "number" 73 | }, 74 | "minimum": { 75 | "type": "number" 76 | }, 77 | "exclusiveMinimum": { 78 | "type": "number" 79 | }, 80 | "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, 81 | "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, 82 | "pattern": { 83 | "type": "string", 84 | "format": "regex" 85 | }, 86 | "additionalItems": { "$ref": "#" }, 87 | "items": { 88 | "anyOf": [ 89 | { "$ref": "#" }, 90 | { "$ref": "#/definitions/schemaArray" } 91 | ], 92 | "default": {} 93 | }, 94 | "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, 95 | "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, 96 | "uniqueItems": { 97 | "type": "boolean", 98 | "default": false 99 | }, 100 | "contains": { "$ref": "#" }, 101 | "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, 102 | "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, 103 | "required": { "$ref": "#/definitions/stringArray" }, 104 | "additionalProperties": { "$ref": "#" }, 105 | "definitions": { 106 | "type": "object", 107 | "additionalProperties": { "$ref": "#" }, 108 | "default": {} 109 | }, 110 | "properties": { 111 | "type": "object", 112 | "additionalProperties": { "$ref": "#" }, 113 | "default": {} 114 | }, 115 | "patternProperties": { 116 | "type": "object", 117 | "additionalProperties": { "$ref": "#" }, 118 | "propertyNames": { "format": "regex" }, 119 | "default": {} 120 | }, 121 | "dependencies": { 122 | "type": "object", 123 | "additionalProperties": { 124 | "anyOf": [ 125 | { "$ref": "#" }, 126 | { "$ref": "#/definitions/stringArray" } 127 | ] 128 | } 129 | }, 130 | "propertyNames": { "$ref": "#" }, 131 | "const": {}, 132 | "enum": { 133 | "type": "array" 134 | }, 135 | "type": { 136 | "anyOf": [ 137 | { "$ref": "#/definitions/simpleTypes" }, 138 | { 139 | "type": "array", 140 | "items": { "$ref": "#/definitions/simpleTypes" }, 141 | "minItems": 1, 142 | "uniqueItems": true 143 | } 144 | ] 145 | }, 146 | "format": { "type": "string" }, 147 | "allOf": { "$ref": "#/definitions/schemaArray" }, 148 | "anyOf": { "$ref": "#/definitions/schemaArray" }, 149 | "oneOf": { "$ref": "#/definitions/schemaArray" }, 150 | "not": { "$ref": "#" } 151 | }, 152 | "default": {} 153 | } 154 | -------------------------------------------------------------------------------- /jsonschema_specifications/schemas/draft7/metaschema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "http://json-schema.org/draft-07/schema#", 4 | "title": "Core schema meta-schema", 5 | "definitions": { 6 | "schemaArray": { 7 | "type": "array", 8 | "minItems": 1, 9 | "items": { "$ref": "#" } 10 | }, 11 | "nonNegativeInteger": { 12 | "type": "integer", 13 | "minimum": 0 14 | }, 15 | "nonNegativeIntegerDefault0": { 16 | "allOf": [ 17 | { "$ref": "#/definitions/nonNegativeInteger" }, 18 | { "default": 0 } 19 | ] 20 | }, 21 | "simpleTypes": { 22 | "enum": [ 23 | "array", 24 | "boolean", 25 | "integer", 26 | "null", 27 | "number", 28 | "object", 29 | "string" 30 | ] 31 | }, 32 | "stringArray": { 33 | "type": "array", 34 | "items": { "type": "string" }, 35 | "uniqueItems": true, 36 | "default": [] 37 | } 38 | }, 39 | "type": ["object", "boolean"], 40 | "properties": { 41 | "$id": { 42 | "type": "string", 43 | "format": "uri-reference" 44 | }, 45 | "$schema": { 46 | "type": "string", 47 | "format": "uri" 48 | }, 49 | "$ref": { 50 | "type": "string", 51 | "format": "uri-reference" 52 | }, 53 | "$comment": { 54 | "type": "string" 55 | }, 56 | "title": { 57 | "type": "string" 58 | }, 59 | "description": { 60 | "type": "string" 61 | }, 62 | "default": true, 63 | "readOnly": { 64 | "type": "boolean", 65 | "default": false 66 | }, 67 | "examples": { 68 | "type": "array", 69 | "items": true 70 | }, 71 | "multipleOf": { 72 | "type": "number", 73 | "exclusiveMinimum": 0 74 | }, 75 | "maximum": { 76 | "type": "number" 77 | }, 78 | "exclusiveMaximum": { 79 | "type": "number" 80 | }, 81 | "minimum": { 82 | "type": "number" 83 | }, 84 | "exclusiveMinimum": { 85 | "type": "number" 86 | }, 87 | "maxLength": { "$ref": "#/definitions/nonNegativeInteger" }, 88 | "minLength": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, 89 | "pattern": { 90 | "type": "string", 91 | "format": "regex" 92 | }, 93 | "additionalItems": { "$ref": "#" }, 94 | "items": { 95 | "anyOf": [ 96 | { "$ref": "#" }, 97 | { "$ref": "#/definitions/schemaArray" } 98 | ], 99 | "default": true 100 | }, 101 | "maxItems": { "$ref": "#/definitions/nonNegativeInteger" }, 102 | "minItems": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, 103 | "uniqueItems": { 104 | "type": "boolean", 105 | "default": false 106 | }, 107 | "contains": { "$ref": "#" }, 108 | "maxProperties": { "$ref": "#/definitions/nonNegativeInteger" }, 109 | "minProperties": { "$ref": "#/definitions/nonNegativeIntegerDefault0" }, 110 | "required": { "$ref": "#/definitions/stringArray" }, 111 | "additionalProperties": { "$ref": "#" }, 112 | "definitions": { 113 | "type": "object", 114 | "additionalProperties": { "$ref": "#" }, 115 | "default": {} 116 | }, 117 | "properties": { 118 | "type": "object", 119 | "additionalProperties": { "$ref": "#" }, 120 | "default": {} 121 | }, 122 | "patternProperties": { 123 | "type": "object", 124 | "additionalProperties": { "$ref": "#" }, 125 | "propertyNames": { "format": "regex" }, 126 | "default": {} 127 | }, 128 | "dependencies": { 129 | "type": "object", 130 | "additionalProperties": { 131 | "anyOf": [ 132 | { "$ref": "#" }, 133 | { "$ref": "#/definitions/stringArray" } 134 | ] 135 | } 136 | }, 137 | "propertyNames": { "$ref": "#" }, 138 | "const": true, 139 | "enum": { 140 | "type": "array", 141 | "items": true 142 | }, 143 | "type": { 144 | "anyOf": [ 145 | { "$ref": "#/definitions/simpleTypes" }, 146 | { 147 | "type": "array", 148 | "items": { "$ref": "#/definitions/simpleTypes" }, 149 | "minItems": 1, 150 | "uniqueItems": true 151 | } 152 | ] 153 | }, 154 | "format": { "type": "string" }, 155 | "contentMediaType": { "type": "string" }, 156 | "contentEncoding": { "type": "string" }, 157 | "if": {"$ref": "#"}, 158 | "then": {"$ref": "#"}, 159 | "else": {"$ref": "#"}, 160 | "allOf": { "$ref": "#/definitions/schemaArray" }, 161 | "anyOf": { "$ref": "#/definitions/schemaArray" }, 162 | "oneOf": { "$ref": "#/definitions/schemaArray" }, 163 | "not": { "$ref": "#" } 164 | }, 165 | "default": true 166 | } 167 | -------------------------------------------------------------------------------- /jsonschema_specifications/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/python-jsonschema/jsonschema-specifications/e3b0c79cd8797087a847768f5e0b21590c8040a5/jsonschema_specifications/tests/__init__.py -------------------------------------------------------------------------------- /jsonschema_specifications/tests/test_jsonschema_specifications.py: -------------------------------------------------------------------------------- 1 | from collections.abc import Mapping 2 | from pathlib import Path 3 | 4 | import pytest 5 | 6 | from jsonschema_specifications import REGISTRY 7 | 8 | 9 | def test_it_contains_metaschemas(): 10 | schema = REGISTRY.contents("http://json-schema.org/draft-07/schema#") 11 | assert isinstance(schema, Mapping) 12 | assert schema["$id"] == "http://json-schema.org/draft-07/schema#" 13 | assert schema["title"] == "Core schema meta-schema" 14 | 15 | 16 | def test_it_is_crawled(): 17 | assert REGISTRY.crawl() == REGISTRY 18 | 19 | 20 | @pytest.mark.parametrize( 21 | "ignored_relative_path", 22 | ["schemas/.DS_Store", "schemas/draft7/.DS_Store"], 23 | ) 24 | def test_it_copes_with_dotfiles(ignored_relative_path): 25 | """ 26 | Ignore files like .DS_Store if someone has actually caused one to exist. 27 | 28 | We test here through the private interface as of course the global has 29 | already loaded our schemas. 30 | """ 31 | 32 | import jsonschema_specifications 33 | 34 | package = Path(jsonschema_specifications.__file__).parent 35 | 36 | ignored = package / ignored_relative_path 37 | ignored.touch() 38 | try: 39 | list(jsonschema_specifications._schemas()) 40 | finally: 41 | ignored.unlink() 42 | -------------------------------------------------------------------------------- /noxfile.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from tempfile import TemporaryDirectory 3 | import os 4 | 5 | import nox 6 | 7 | ROOT = Path(__file__).parent 8 | PYPROJECT = ROOT / "pyproject.toml" 9 | DOCS = ROOT / "docs" 10 | PACKAGE = ROOT / "jsonschema_specifications" 11 | 12 | REQUIREMENTS = dict( 13 | docs=DOCS / "requirements.txt", 14 | ) 15 | REQUIREMENTS_IN = [ # this is actually ordered, as files depend on each other 16 | (path.parent / f"{path.stem}.in", path) for path in REQUIREMENTS.values() 17 | ] 18 | 19 | SUPPORTED = ["3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"] 20 | LATEST = "3.12" # until 3.13 matures 21 | 22 | nox.options.default_venv_backend = "uv|virtualenv" 23 | nox.options.sessions = [] 24 | 25 | 26 | def session(default=True, python=LATEST, **kwargs): # noqa: D103 27 | def _session(fn): 28 | if default: 29 | nox.options.sessions.append(kwargs.get("name", fn.__name__)) 30 | return nox.session(python=python, **kwargs)(fn) 31 | 32 | return _session 33 | 34 | 35 | @session(python=SUPPORTED) 36 | def tests(session): 37 | """ 38 | Run the test suite with a corresponding Python version. 39 | """ 40 | session.install("pytest", ROOT) 41 | env = dict(os.environ, PYTHONWARNDEFAULTENCODING="1") 42 | session.run("pytest", "--verbosity=3", "--pythonwarnings=error", env=env) 43 | 44 | 45 | @session() 46 | def audit(session): 47 | """ 48 | Audit dependencies for vulnerabilities. 49 | """ 50 | session.install("pip-audit", ROOT) 51 | session.run("python", "-m", "pip_audit") 52 | 53 | 54 | @session(tags=["build"]) 55 | def build(session): 56 | """ 57 | Build a distribution suitable for PyPI and check its validity. 58 | """ 59 | session.install("build", "twine") 60 | with TemporaryDirectory() as tmpdir: 61 | session.run("python", "-m", "build", ROOT, "--outdir", tmpdir) 62 | session.run("twine", "check", "--strict", tmpdir + "/*") 63 | 64 | 65 | @session(tags=["style"]) 66 | def style(session): 67 | """ 68 | Check Python code style. 69 | """ 70 | session.install("ruff") 71 | session.run("ruff", "check", ROOT, __file__) 72 | 73 | 74 | @session() 75 | def typing(session): 76 | """ 77 | Check static typing. 78 | """ 79 | session.install("mypy", "pytest", ROOT) 80 | session.run("python", "-m", "mypy", PACKAGE) 81 | 82 | 83 | @session(tags=["docs"]) 84 | @nox.parametrize( 85 | "builder", 86 | [ 87 | nox.param(name, id=name) 88 | for name in [ 89 | "dirhtml", 90 | "doctest", 91 | "linkcheck", 92 | "man", 93 | "spelling", 94 | ] 95 | ], 96 | ) 97 | def docs(session, builder): 98 | """ 99 | Build the documentation using a specific Sphinx builder. 100 | """ 101 | session.install("-r", REQUIREMENTS["docs"]) 102 | with TemporaryDirectory() as tmpdir_str: 103 | tmpdir = Path(tmpdir_str) 104 | argv = ["-n", "-T", "-W"] 105 | if builder != "spelling": 106 | argv += ["-q"] 107 | posargs = session.posargs or [tmpdir / builder] 108 | session.run( 109 | "python", 110 | "-m", 111 | "sphinx", 112 | "-b", 113 | builder, 114 | DOCS, 115 | *argv, 116 | *posargs, 117 | ) 118 | 119 | 120 | @session(tags=["docs", "style"], name="docs(style)") 121 | def docs_style(session): 122 | """ 123 | Check the documentation style. 124 | """ 125 | session.install( 126 | "doc8", 127 | "pygments", 128 | "pygments-github-lexers", 129 | ) 130 | session.run("python", "-m", "doc8", "--config", PYPROJECT, DOCS) 131 | 132 | 133 | @session(default=False) 134 | def requirements(session): 135 | """ 136 | Update the project's pinned requirements. 137 | 138 | You should commit the result afterwards. 139 | """ 140 | if session.venv_backend == "uv": 141 | cmd = ["uv", "pip", "compile"] 142 | else: 143 | session.install("pip-tools") 144 | cmd = ["pip-compile", "--resolver", "backtracking", "--strip-extras"] 145 | 146 | for each, out in REQUIREMENTS_IN: 147 | # otherwise output files end up with silly absolute path comments... 148 | relative = each.relative_to(ROOT) 149 | session.run(*cmd, "--upgrade", "--output-file", out, relative) 150 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling>=1.27.0", "hatch-vcs"] 3 | build-backend = "hatchling.build" 4 | 5 | [tool.hatch.version] 6 | source = "vcs" 7 | 8 | [project] 9 | name = "jsonschema-specifications" 10 | license = "MIT" 11 | license-files = ["COPYING"] 12 | description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" 13 | requires-python = ">=3.9" 14 | readme = "README.rst" 15 | keywords = [ 16 | "validation", 17 | "data validation", 18 | "jsonschema", 19 | "json", 20 | "json schema", 21 | ] 22 | authors = [ 23 | { name = "Julian Berman", email = "Julian+jsonschema-specifications@GrayVines.com" }, 24 | ] 25 | classifiers = [ 26 | "Development Status :: 5 - Production/Stable", 27 | "Intended Audience :: Developers", 28 | "Operating System :: OS Independent", 29 | "Programming Language :: Python", 30 | "Programming Language :: Python :: 3.9", 31 | "Programming Language :: Python :: 3.10", 32 | "Programming Language :: Python :: 3.11", 33 | "Programming Language :: Python :: 3.12", 34 | "Programming Language :: Python :: 3.13", 35 | "Programming Language :: Python :: Implementation :: CPython", 36 | "Programming Language :: Python :: Implementation :: PyPy", 37 | "Topic :: File Formats :: JSON", 38 | "Topic :: File Formats :: JSON :: JSON Schema", 39 | ] 40 | dynamic = ["version"] 41 | dependencies = [ 42 | "referencing>=0.31.0", 43 | ] 44 | 45 | [project.urls] 46 | Documentation = "https://jsonschema-specifications.readthedocs.io/" 47 | Homepage = "https://github.com/python-jsonschema/jsonschema-specifications" 48 | Issues = "https://github.com/python-jsonschema/jsonschema-specifications/issues/" 49 | Funding = "https://github.com/sponsors/Julian" 50 | Tidelift = "https://tidelift.com/subscription/pkg/pypi-jsonschema-specifications?utm_source=pypi-jsonschema-specifications&utm_medium=referral&utm_campaign=pypi-link" 51 | Source = "https://github.com/python-jsonschema/jsonschema-specifications" 52 | 53 | [tool.coverage.html] 54 | show_contexts = true 55 | skip_covered = false 56 | 57 | [tool.coverage.run] 58 | branch = true 59 | source = ["jsonschema-specifications"] 60 | dynamic_context = "test_function" 61 | 62 | [tool.coverage.report] 63 | exclude_also = [ 64 | "if TYPE_CHECKING:", 65 | "\\s*\\.\\.\\.\\s*", 66 | ] 67 | fail_under = 100 68 | show_missing = true 69 | skip_covered = true 70 | 71 | [tool.doc8] 72 | ignore = [ 73 | "D000", # see PyCQA/doc8#125 74 | "D001", # one sentence per line, so max length doesn't make sense 75 | ] 76 | 77 | [tool.ruff] 78 | line-length = 79 79 | 80 | [tool.ruff.lint] 81 | select = ["ALL"] 82 | ignore = [ 83 | "A001", # It's fine to shadow builtins 84 | "A002", 85 | "A003", 86 | "ARG", # This is all wrong whenever an interface is involved 87 | "ANN", # Just let the type checker do this 88 | "B006", # Mutable arguments require care but are OK if you don't abuse them 89 | "B008", # It's totally OK to call functions for default arguments. 90 | "B904", # raise SomeException(...) is fine. 91 | "B905", # No need for explicit strict, this is simply zip's default behavior 92 | "C408", # Calling dict is fine when it saves quoting the keys 93 | "C901", # Not really something to focus on 94 | "D105", # It's fine to not have docstrings for magic methods. 95 | "D107", # __init__ especially doesn't need a docstring 96 | "D200", # This rule makes diffs uglier when expanding docstrings 97 | "D203", # No blank lines before docstrings. 98 | "D212", # Start docstrings on the second line. 99 | "D400", # This rule misses sassy docstrings ending with ! or ? 100 | "D401", # This rule is too flaky. 101 | "D406", # Section headers should end with a colon not a newline 102 | "D407", # Underlines aren't needed 103 | "D412", # Plz spaces after section headers 104 | "EM101", # These don't bother me, it's fine there's some duplication. 105 | "EM102", 106 | "FBT", # It's worth avoiding boolean args but I don't care to enforce it 107 | "FIX", # Yes thanks, if I could it wouldn't be there 108 | "N", # These naming rules are silly 109 | "PLR0912", # These metrics are fine to be aware of but not to enforce 110 | "PLR0913", 111 | "PLR0915", 112 | "PLW2901", # Shadowing for loop variables is occasionally fine. 113 | "PT006", # pytest parametrize takes strings as well 114 | "PYI025", # wat, I'm not confused, thanks. 115 | "RET502", # Returning None implicitly is fine 116 | "RET503", 117 | "RET505", # These push you to use `if` instead of `elif`, but for no reason 118 | "RET506", 119 | "RSE102", # Ha, what, who even knew you could leave the parens off. But no. 120 | "SIM300", # Not sure what heuristic this uses, but it's easily incorrect 121 | "SLF001", # Private usage within this package itself is fine 122 | "TD", # These TODO style rules are also silly 123 | "TRY003", # Some exception classes are essentially intended for free-form 124 | ] 125 | 126 | [tool.ruff.lint.flake8-pytest-style] 127 | mark-parentheses = false 128 | 129 | [tool.ruff.lint.flake8-quotes] 130 | docstring-quotes = "double" 131 | 132 | [tool.ruff.lint.isort] 133 | combine-as-imports = true 134 | from-first = true 135 | 136 | [tool.ruff.lint.per-file-ignores] 137 | "noxfile.py" = ["ANN", "D100", "S101", "T201"] 138 | "docs/*" = ["ANN", "D", "INP001"] 139 | "jsonschema_specifications/tests/*" = ["ANN", "D", "RUF012", "S"] 140 | --------------------------------------------------------------------------------