summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwilson chen <willson.chenwx@gmail.com>2020-08-29 10:13:32 +0800
committerGitHub <noreply@github.com>2020-08-29 10:13:32 +0800
commitba914b00e2c150fc722b86e0b53cf0aa82652de7 (patch)
tree743f3c3b3c0a777acfab5775f6923c6931e57294
parent03868b3316ba2f17fbd091df91bcb06bd89a8552 (diff)
parent5fc5b1450a0cdb903ce226105b18169a954dec55 (diff)
downloadjsonschema-ba914b00e2c150fc722b86e0b53cf0aa82652de7.tar.gz
Merge branch 'master' into fix_issue669
-rw-r--r--.github/workflows/ci.yml104
-rw-r--r--.pre-commit-config.yaml27
-rw-r--r--CHANGELOG.rst4
-rw-r--r--DEMO.ipynb167
-rw-r--r--README.rst20
-rw-r--r--demo.yml2
-rw-r--r--docs/conf.py1
-rw-r--r--docs/jsonschema_role.py16
-rw-r--r--docs/validate.rst6
-rwxr-xr-xjson/bin/jsonschema_suite4
-rw-r--r--json/remotes/baseUriChange/folderInteger.json (renamed from json/remotes/folder/folderInteger.json)0
-rw-r--r--json/remotes/baseUriChangeFolder/folderInteger.json3
-rw-r--r--json/remotes/baseUriChangeFolderInSubschema/folderInteger.json3
-rw-r--r--json/tests/draft2019-09/const.json84
-rw-r--r--json/tests/draft2019-09/optional/format/date-time.json10
-rw-r--r--json/tests/draft2019-09/optional/format/date.json10
-rw-r--r--json/tests/draft2019-09/optional/format/ipv6.json35
-rw-r--r--json/tests/draft2019-09/optional/format/uri.json5
-rw-r--r--json/tests/draft2019-09/refRemote.json10
-rw-r--r--json/tests/draft2019-09/uniqueItems.json10
-rw-r--r--json/tests/draft3/optional/format/date-time.json10
-rw-r--r--json/tests/draft3/optional/format/date.json15
-rw-r--r--json/tests/draft3/refRemote.json2
-rw-r--r--json/tests/draft3/uniqueItems.json10
-rw-r--r--json/tests/draft4/optional/format/date-time.json10
-rw-r--r--json/tests/draft4/optional/format/ipv6.json35
-rw-r--r--json/tests/draft4/optional/format/uri.json5
-rw-r--r--json/tests/draft4/refRemote.json6
-rw-r--r--json/tests/draft4/uniqueItems.json10
-rw-r--r--json/tests/draft6/const.json84
-rw-r--r--json/tests/draft6/optional/format/date-time.json12
-rw-r--r--json/tests/draft6/optional/format/ipv6.json35
-rw-r--r--json/tests/draft6/optional/format/uri.json5
-rw-r--r--json/tests/draft6/refRemote.json6
-rw-r--r--json/tests/draft6/uniqueItems.json10
-rw-r--r--json/tests/draft7/const.json84
-rw-r--r--json/tests/draft7/optional/format/date-time.json10
-rw-r--r--json/tests/draft7/optional/format/date.json10
-rw-r--r--json/tests/draft7/optional/format/ipv6.json35
-rw-r--r--json/tests/draft7/optional/format/uri.json5
-rw-r--r--json/tests/draft7/refRemote.json6
-rw-r--r--json/tests/draft7/uniqueItems.json10
-rw-r--r--jsonschema/__init__.py11
-rw-r--r--jsonschema/__main__.py1
-rw-r--r--jsonschema/_format.py70
-rw-r--r--jsonschema/benchmarks/issue232.py1
-rw-r--r--jsonschema/benchmarks/json_schema_test_suite.py1
-rw-r--r--jsonschema/cli.py5
-rw-r--r--jsonschema/exceptions.py1
-rw-r--r--jsonschema/tests/_helpers.py2
-rw-r--r--jsonschema/tests/test_cli.py81
-rw-r--r--jsonschema/tests/test_format.py3
-rw-r--r--jsonschema/tests/test_jsonschema_test_suite.py123
-rw-r--r--jsonschema/validators.py2
-rw-r--r--pyproject.toml5
-rw-r--r--setup.cfg2
-rw-r--r--tox.ini17
57 files changed, 900 insertions, 361 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e0cc77f..d89d6fd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,13 +18,17 @@ jobs:
os: [macos-latest, ubuntu-latest, windows-latest]
python-version:
- name: pypy3
- toxenv: pypy3-build
+ toxenv: pypy3-noextra-build
- name: pypy3
- toxenv: pypy3-tests
+ toxenv: pypy3-noextra-tests
- name: pypy3
- toxenv: pypy3-tests_nongpl
+ toxenv: pypy3-format-build
- name: pypy3
- toxenv: demo
+ toxenv: pypy3-format-tests
+ - name: pypy3
+ toxenv: pypy3-format_nongpl-build
+ - name: pypy3
+ toxenv: pypy3-format_nongpl-tests
- name: pypy3
toxenv: readme
- name: pypy3
@@ -44,36 +48,66 @@ jobs:
- name: pypy3
toxenv: docs-style
- name: 3.6
- toxenv: py36-build
+ toxenv: py36-noextra-build
+ - name: 3.6
+ toxenv: py36-noextra-tests
+ - name: 3.6
+ toxenv: py36-format-build
+ - name: 3.6
+ toxenv: py36-format-tests
- name: 3.6
- toxenv: py36-tests
+ toxenv: py36-format_nongpl-build
- name: 3.6
- toxenv: py36-tests_nongpl
+ toxenv: py36-format_nongpl-tests
- name: 3.7
- toxenv: py37-build
+ toxenv: py37-noextra-build
- name: 3.7
- toxenv: py37-tests
+ toxenv: py37-noextra-tests
- name: 3.7
- toxenv: py37-tests_nongpl
+ toxenv: py37-format-build
+ - name: 3.7
+ toxenv: py37-format-tests
+ - name: 3.7
+ toxenv: py37-format_nongpl-build
+ - name: 3.7
+ toxenv: py37-format_nongpl-tests
+ - name: 3.8
+ toxenv: py38-noextra-build
+ - name: 3.8
+ toxenv: py38-noextra-tests
- name: 3.8
- toxenv: py38-build
+ toxenv: py38-format-build
- name: 3.8
- toxenv: py38-tests
+ toxenv: py38-format-tests
- name: 3.8
- toxenv: py38-tests_nongpl
+ toxenv: py38-format_nongpl-build
+ - name: 3.8
+ toxenv: py38-format_nongpl-tests
exclude:
- os: windows-latest
python-version:
name: pypy3
- toxenv: pypy3-build
+ toxenv: pypy3-noextra-build
+ - os: windows-latest
+ python-version:
+ name: pypy3
+ toxenv: pypy3-format-build
+ - os: windows-latest
+ python-version:
+ name: pypy3
+ toxenv: pypy3-format_nongpl-build
+ - os: windows-latest
+ python-version:
+ name: pypy3
+ toxenv: pypy3-noextra-tests
- os: windows-latest
python-version:
name: pypy3
- toxenv: pypy3-tests
+ toxenv: pypy3-format-tests
- os: windows-latest
python-version:
name: pypy3
- toxenv: pypy3-tests_nongpl
+ toxenv: pypy3-format_nongpl-tests
- os: windows-latest
python-version:
name: pypy3
@@ -89,27 +123,51 @@ jobs:
- os: windows-latest
python-version:
name: 3.6
- toxenv: py36-tests
+ toxenv: py36-noextra-build
- os: windows-latest
python-version:
name: 3.6
- toxenv: py36-tests_nongpl
+ toxenv: py36-format-build
- os: windows-latest
python-version:
name: 3.6
- toxenv: py36-build
+ toxenv: py36-format_nongpl-build
+ - os: windows-latest
+ python-version:
+ name: 3.6
+ toxenv: py36-noextra-tests
+ - os: windows-latest
+ python-version:
+ name: 3.6
+ toxenv: py36-format-tests
+ - os: windows-latest
+ python-version:
+ name: 3.6
+ toxenv: py36-format_nongpl-tests
+ - os: windows-latest
+ python-version:
+ name: 3.7
+ toxenv: py37-noextra-tests
+ - os: windows-latest
+ python-version:
+ name: 3.7
+ toxenv: py37-format-tests
- os: windows-latest
python-version:
name: 3.7
- toxenv: py37-build
+ toxenv: py37-format_nongpl-tests
- os: windows-latest
python-version:
name: 3.8
- toxenv: py38-build
+ toxenv: py38-noextra-tests
- os: windows-latest
python-version:
- name: pypy3
- toxenv: demo
+ name: 3.8
+ toxenv: py38-format-tests
+ - os: windows-latest
+ python-version:
+ name: 3.8
+ toxenv: py38-format_nongpl-tests
- os: windows-latest
python-version:
name: pypy3
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..a1dc799
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,27 @@
+exclude: json
+
+repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.2.0
+ hooks:
+ - id: check-ast
+ - id: check-docstring-first
+ - id: check-json
+ - id: check-toml
+ - id: check-vcs-permalinks
+ - id: check-yaml
+ - id: debug-statements
+ - id: end-of-file-fixer
+ - id: trailing-whitespace
+- repo: https://github.com/timothycrosley/isort
+ rev: 5.3.2
+ hooks:
+ - id: isort
+- repo: https://github.com/myint/docformatter
+ rev: v1.3.1
+ hooks:
+ - id: docformatter
+ args:
+ - --in-place
+ - --pre-summary-newline
+ - --make-summary-multi-line
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8f0a270..7c1a67e 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -43,7 +43,7 @@ v2.6.0
* Support for Python 2.6 has been dropped.
* Improve a few error messages for ``uniqueItems`` (#224) and
``additionalProperties`` (#317)
-* Fixed an issue with ``ErrorTree``'s handling of multiple errors (#288)
+* Fixed an issue with ``ErrorTree``'s handling of multiple errors (#288)
v2.5.0
------
@@ -175,7 +175,7 @@ v0.4
In order to make this happen (and also to clean things up a bit), a number
of deprecations are necessary:
- * ``stop_on_error`` is deprecated in ``Validator.__init__``. Use
+ * ``stop_on_error`` is deprecated in ``Validator.__init__``. Use
``Validator.iter_errors()`` instead.
* ``number_types`` and ``string_types`` are deprecated there as well.
Use ``types={"number" : ..., "string" : ...}`` instead.
diff --git a/DEMO.ipynb b/DEMO.ipynb
deleted file mode 100644
index f008b79..0000000
--- a/DEMO.ipynb
+++ /dev/null
@@ -1,167 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# jsonschema\n",
- "---"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "`jsonschema` is an implementation of [JSON Schema](https://json-schema.org) for Python (supporting 2.7+ including Python 3)."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Usage"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from jsonschema import validate"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# A sample schema, like what we'd get from json.load()\n",
- "schema = {\n",
- " \"type\" : \"object\",\n",
- " \"properties\" : {\n",
- " \"price\" : {\"type\" : \"number\"},\n",
- " \"name\" : {\"type\" : \"string\"},\n",
- " },\n",
- "}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# If no exception is raised by validate(), the instance is valid.\n",
- "validate(instance={\"name\" : \"Eggs\", \"price\" : 34.99}, schema=schema)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [
- {
- "ename": "ValidationError",
- "evalue": "'Invalid' is not of type 'number'\n\nFailed validating 'type' in schema['properties']['price']:\n {'type': 'number'}\n\nOn instance['price']:\n 'Invalid'",
- "output_type": "error",
- "traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)",
- "\u001b[0;32m<ipython-input-5-e1e543273d1f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m validate(\n\u001b[1;32m 2\u001b[0m \u001b[0minstance\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"name\"\u001b[0m \u001b[0;34m:\u001b[0m \u001b[0;34m\"Eggs\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"price\"\u001b[0m \u001b[0;34m:\u001b[0m \u001b[0;34m\"Invalid\"\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mschema\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mschema\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m )\n",
- "\u001b[0;32m~/Development/jsonschema/jsonschema/validators.py\u001b[0m in \u001b[0;36mvalidate\u001b[0;34m(instance, schema, cls, *args, **kwargs)\u001b[0m\n\u001b[1;32m 899\u001b[0m \u001b[0merror\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbest_match\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalidator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miter_errors\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minstance\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 900\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0merror\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 901\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merror\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 902\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
- "\u001b[0;31mValidationError\u001b[0m: 'Invalid' is not of type 'number'\n\nFailed validating 'type' in schema['properties']['price']:\n {'type': 'number'}\n\nOn instance['price']:\n 'Invalid'"
- ]
- }
- ],
- "source": [
- "validate(\n",
- " instance={\"name\" : \"Eggs\", \"price\" : \"Invalid\"},\n",
- " schema=schema,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "It can also be used from console:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!echo '{\"name\" : \"Eggs\", \"price\" : 34.99}' > /tmp/sample.json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!echo '{\"type\" : \"object\", \"properties\" : {\"price\" : {\"type\" : \"number\"}, \"name\" : {\"type\" : \"string\"}}}' > /tmp/sample.schema"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!jsonschema -i /tmp/sample.json /tmp/sample.schema"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Do your own experiments here..."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Try `jsonschema` youself by adding your code below and running your own experiments 👇"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import jsonschema\n",
- "\n",
- "# your code here\n",
- "jsonschema."
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.7.4"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/README.rst b/README.rst
index d2db17f..dc89d72 100644
--- a/README.rst
+++ b/README.rst
@@ -80,24 +80,6 @@ Installation
$ pip install jsonschema
-Demo
-----
-
-Try ``jsonschema`` interactively in this online demo:
-
-.. image:: https://user-images.githubusercontent.com/1155573/56745335-8b158a00-6750-11e9-8776-83fa675939c4.png
- :target: https://notebooks.ai/demo/gh/Julian/jsonschema
- :alt: Open Live Demo
-
-
-Online demo Notebook will look similar to this:
-
-
-.. image:: https://user-images.githubusercontent.com/1155573/56820861-5c1c1880-6823-11e9-802a-ce01c5ec574f.gif
- :alt: Open Live Demo
- :width: 480 px
-
-
Release Notes
-------------
@@ -125,7 +107,7 @@ Benchmarks
----------
``jsonschema``'s benchmarks make use of `pyperf
-<https://pyperf.readthedocs.io>`_. Running them can be done via::
+<https://pyperf.readthedocs.io>`_. Running them can be done via::
$ tox -e perf
diff --git a/demo.yml b/demo.yml
deleted file mode 100644
index a2d7e46..0000000
--- a/demo.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-requirements:
- - jsonschema==3.0.1
diff --git a/docs/conf.py b/docs/conf.py
index 565b00a..fbf6f30 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -9,7 +9,6 @@ import sys
import jsonschema
-
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
diff --git a/docs/jsonschema_role.py b/docs/jsonschema_role.py
index a63ff72..8a4feaa 100644
--- a/docs/jsonschema_role.py
+++ b/docs/jsonschema_role.py
@@ -1,17 +1,13 @@
from datetime import datetime
-from docutils import nodes
import errno
import os
+import urllib.request
-try:
- import urllib2 as urllib
-except ImportError:
- import urllib.request as urllib
-
-import certifi
-import jsonschema
+from docutils import nodes
from lxml import html
+import certifi
+import jsonschema
__version__ = "1.1.0"
VALIDATION_SPEC = "https://json-schema.org/draft-07/json-schema-validation.html"
@@ -68,8 +64,8 @@ def fetch_or_load(spec_path):
if error.errno != errno.ENOENT:
raise
- request = urllib.Request(VALIDATION_SPEC, headers=headers)
- response = urllib.urlopen(request, cafile=certifi.where())
+ request = urllib.request.Request(VALIDATION_SPEC, headers=headers)
+ response = urllib.request.urlopen(request, cafile=certifi.where())
if response.code == 200:
with open(spec_path, "w+b") as spec:
diff --git a/docs/validate.rst b/docs/validate.rst
index 3489f20..dc46017 100644
--- a/docs/validate.rst
+++ b/docs/validate.rst
@@ -277,15 +277,15 @@ validation can be enabled by hooking in a format-checking object into an
.. doctest::
- >>> validate("localhost", {"format" : "hostname"})
+ >>> validate("127.0.0.1", {"format" : "ipv4"})
>>> validate(
... instance="-12",
- ... schema={"format" : "hostname"},
+ ... schema={"format" : "ipv4"},
... format_checker=draft7_format_checker,
... )
Traceback (most recent call last):
...
- ValidationError: "-12" is not a "hostname"
+ ValidationError: "-12" is not a "ipv4"
.. autoclass:: FormatChecker
:members:
diff --git a/json/bin/jsonschema_suite b/json/bin/jsonschema_suite
index 9ccd8e8..628bc5d 100755
--- a/json/bin/jsonschema_suite
+++ b/json/bin/jsonschema_suite
@@ -50,7 +50,9 @@ REMOTES = {
u"refToInteger": {u"$ref": u"#/$defs/integer"},
}
},
- "folder/folderInteger.json": {u"type": u"integer"}
+ "baseUriChange/folderInteger.json": {u"type": u"integer"},
+ "baseUriChangeFolder/folderInteger.json": {u"type": u"integer"},
+ "baseUriChangeFolderInSubschema/folderInteger.json": {u"type": u"integer"},
}
REMOTES_DIR = os.path.join(ROOT_DIR, "remotes")
diff --git a/json/remotes/folder/folderInteger.json b/json/remotes/baseUriChange/folderInteger.json
index 8b50ea3..8b50ea3 100644
--- a/json/remotes/folder/folderInteger.json
+++ b/json/remotes/baseUriChange/folderInteger.json
diff --git a/json/remotes/baseUriChangeFolder/folderInteger.json b/json/remotes/baseUriChangeFolder/folderInteger.json
new file mode 100644
index 0000000..8b50ea3
--- /dev/null
+++ b/json/remotes/baseUriChangeFolder/folderInteger.json
@@ -0,0 +1,3 @@
+{
+ "type": "integer"
+}
diff --git a/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json b/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json
new file mode 100644
index 0000000..8b50ea3
--- /dev/null
+++ b/json/remotes/baseUriChangeFolderInSubschema/folderInteger.json
@@ -0,0 +1,3 @@
+{
+ "type": "integer"
+}
diff --git a/json/tests/draft2019-09/const.json b/json/tests/draft2019-09/const.json
index c53d04d..1c2cafc 100644
--- a/json/tests/draft2019-09/const.json
+++ b/json/tests/draft2019-09/const.json
@@ -126,6 +126,90 @@
]
},
{
+ "description": "const with [false] does not match [0]",
+ "schema": {"const": [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": "const with [true] does not match [1]",
+ "schema": {"const": [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": "const with {\"a\": false} does not match {\"a\": 0}",
+ "schema": {"const": {"a": false}},
+ "tests": [
+ {
+ "description": "{\"a\": false} is valid",
+ "data": {"a": false},
+ "valid": true
+ },
+ {
+ "description": "{\"a\": 0} is invalid",
+ "data": {"a": 0},
+ "valid": false
+ },
+ {
+ "description": "{\"a\": 0.0} is invalid",
+ "data": {"a": 0.0},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "const with {\"a\": true} does not match {\"a\": 1}",
+ "schema": {"const": {"a": true}},
+ "tests": [
+ {
+ "description": "{\"a\": true} is valid",
+ "data": {"a": true},
+ "valid": true
+ },
+ {
+ "description": "{\"a\": 1} is invalid",
+ "data": {"a": 1},
+ "valid": false
+ },
+ {
+ "description": "{\"a\": 1.0} is invalid",
+ "data": {"a": 1.0},
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "const with 0 does not match other zero-like types",
"schema": {"const": 0},
"tests": [
diff --git a/json/tests/draft2019-09/optional/format/date-time.json b/json/tests/draft2019-09/optional/format/date-time.json
index dfccee6..900fcb7 100644
--- a/json/tests/draft2019-09/optional/format/date-time.json
+++ b/json/tests/draft2019-09/optional/format/date-time.json
@@ -47,6 +47,16 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350T01:01:01",
"valid": false
+ },
+ {
+ "description": "invalid non-padded month dates",
+ "data": "1963-6-19T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded day dates",
+ "data": "1963-06-1T08:30:06.283185Z",
+ "valid": false
}
]
}
diff --git a/json/tests/draft2019-09/optional/format/date.json b/json/tests/draft2019-09/optional/format/date.json
index cd23baa..453b51d 100644
--- a/json/tests/draft2019-09/optional/format/date.json
+++ b/json/tests/draft2019-09/optional/format/date.json
@@ -17,6 +17,16 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350",
"valid": false
+ },
+ {
+ "description": "invalidates non-padded month dates",
+ "data": "1998-1-20",
+ "valid": false
+ },
+ {
+ "description": "invalidates non-padded day dates",
+ "data": "1998-01-1",
+ "valid": false
}
]
}
diff --git a/json/tests/draft2019-09/optional/format/ipv6.json b/json/tests/draft2019-09/optional/format/ipv6.json
index 9b0881e..2a08cb4 100644
--- a/json/tests/draft2019-09/optional/format/ipv6.json
+++ b/json/tests/draft2019-09/optional/format/ipv6.json
@@ -112,6 +112,41 @@
"description": "ipv4 segment must have 4 octets",
"data": "1:2:3:4:1.2.3",
"valid": false
+ },
+ {
+ "description": "leading whitespace is invalid",
+ "data": " ::1",
+ "valid": false
+ },
+ {
+ "description": "trailing whitespace is invalid",
+ "data": "::1 ",
+ "valid": false
+ },
+ {
+ "description": "netmask is not a part of ipv6 address",
+ "data": "fe80::/64",
+ "valid": false
+ },
+ {
+ "description": "zone id is not a part of ipv6 address",
+ "data": "fe80::a%eth1",
+ "valid": false
+ },
+ {
+ "description": "a long valid ipv6",
+ "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
+ "valid": true
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, first",
+ "data": "100:100:100:100:100:100:255.255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, second",
+ "data": "100:100:100:100:100:100:100:255.255.255.255",
+ "valid": false
}
]
}
diff --git a/json/tests/draft2019-09/optional/format/uri.json b/json/tests/draft2019-09/optional/format/uri.json
index 25cc40c..4306a68 100644
--- a/json/tests/draft2019-09/optional/format/uri.json
+++ b/json/tests/draft2019-09/optional/format/uri.json
@@ -97,6 +97,11 @@
"description": "an invalid URI with spaces and missing scheme",
"data": ":// should fail",
"valid": false
+ },
+ {
+ "description": "an invalid URI with comma in scheme",
+ "data": "bar,baz:foo",
+ "valid": false
}
]
}
diff --git a/json/tests/draft2019-09/refRemote.json b/json/tests/draft2019-09/refRemote.json
index 515263d..b9c6a28 100644
--- a/json/tests/draft2019-09/refRemote.json
+++ b/json/tests/draft2019-09/refRemote.json
@@ -54,7 +54,7 @@
"schema": {
"$id": "http://localhost:1234/",
"items": {
- "$id": "folder/",
+ "$id": "baseUriChange/",
"items": {"$ref": "folderInteger.json"}
}
},
@@ -76,10 +76,10 @@
"schema": {
"$id": "http://localhost:1234/scope_change_defs1.json",
"type" : "object",
- "properties": {"list": {"$ref": "folder/"}},
+ "properties": {"list": {"$ref": "baseUriChangeFolder/"}},
"$defs": {
"baz": {
- "$id": "folder/",
+ "$id": "baseUriChangeFolder/",
"type": "array",
"items": {"$ref": "folderInteger.json"}
}
@@ -103,10 +103,10 @@
"schema": {
"$id": "http://localhost:1234/scope_change_defs2.json",
"type" : "object",
- "properties": {"list": {"$ref": "folder/#/$defs/bar"}},
+ "properties": {"list": {"$ref": "baseUriChangeFolderInSubschema/#/$defs/bar"}},
"$defs": {
"baz": {
- "$id": "folder/",
+ "$id": "baseUriChangeFolderInSubschema/",
"$defs": {
"bar": {
"type": "array",
diff --git a/json/tests/draft2019-09/uniqueItems.json b/json/tests/draft2019-09/uniqueItems.json
index fb1ddb5..4846c77 100644
--- a/json/tests/draft2019-09/uniqueItems.json
+++ b/json/tests/draft2019-09/uniqueItems.json
@@ -113,6 +113,16 @@
"description": "objects are non-unique despite key order",
"data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}],
"valid": false
+ },
+ {
+ "description": "{\"a\": false} and {\"a\": 0} are unique",
+ "data": [{"a": false}, {"a": 0}],
+ "valid": true
+ },
+ {
+ "description": "{\"a\": true} and {\"a\": 1} are unique",
+ "data": [{"a": true}, {"a": 1}],
+ "valid": true
}
]
},
diff --git a/json/tests/draft3/optional/format/date-time.json b/json/tests/draft3/optional/format/date-time.json
index 90279ba..58261fa 100644
--- a/json/tests/draft3/optional/format/date-time.json
+++ b/json/tests/draft3/optional/format/date-time.json
@@ -22,6 +22,16 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350T01:01:01",
"valid": false
+ },
+ {
+ "description": "invalid non-padded month dates",
+ "data": "1963-6-19T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded day dates",
+ "data": "1963-06-1T08:30:06.283185Z",
+ "valid": false
}
]
}
diff --git a/json/tests/draft3/optional/format/date.json b/json/tests/draft3/optional/format/date.json
index bd83042..4842b48 100644
--- a/json/tests/draft3/optional/format/date.json
+++ b/json/tests/draft3/optional/format/date.json
@@ -12,6 +12,21 @@
"description": "an invalid date string",
"data": "06/19/1963",
"valid": false
+ },
+ {
+ "description": "only RFC3339 not all of ISO 8601 are valid",
+ "data": "2013-350",
+ "valid": false
+ },
+ {
+ "description": "invalidates non-padded month dates",
+ "data": "1998-1-20",
+ "valid": false
+ },
+ {
+ "description": "invalidates non-padded day dates",
+ "data": "1998-01-1",
+ "valid": false
}
]
}
diff --git a/json/tests/draft3/refRemote.json b/json/tests/draft3/refRemote.json
index 4ca8047..de0cb43 100644
--- a/json/tests/draft3/refRemote.json
+++ b/json/tests/draft3/refRemote.json
@@ -54,7 +54,7 @@
"schema": {
"id": "http://localhost:1234/",
"items": {
- "id": "folder/",
+ "id": "baseUriChange/",
"items": {"$ref": "folderInteger.json"}
}
},
diff --git a/json/tests/draft3/uniqueItems.json b/json/tests/draft3/uniqueItems.json
index 8f8dbdd..fd4b849 100644
--- a/json/tests/draft3/uniqueItems.json
+++ b/json/tests/draft3/uniqueItems.json
@@ -93,6 +93,16 @@
"description": "non-unique heterogeneous types are invalid",
"data": [{}, [1], true, null, {}, 1],
"valid": false
+ },
+ {
+ "description": "{\"a\": false} and {\"a\": 0} are unique",
+ "data": [{"a": false}, {"a": 0}],
+ "valid": true
+ },
+ {
+ "description": "{\"a\": true} and {\"a\": 1} are unique",
+ "data": [{"a": true}, {"a": 1}],
+ "valid": true
}
]
},
diff --git a/json/tests/draft4/optional/format/date-time.json b/json/tests/draft4/optional/format/date-time.json
index dfccee6..900fcb7 100644
--- a/json/tests/draft4/optional/format/date-time.json
+++ b/json/tests/draft4/optional/format/date-time.json
@@ -47,6 +47,16 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350T01:01:01",
"valid": false
+ },
+ {
+ "description": "invalid non-padded month dates",
+ "data": "1963-6-19T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded day dates",
+ "data": "1963-06-1T08:30:06.283185Z",
+ "valid": false
}
]
}
diff --git a/json/tests/draft4/optional/format/ipv6.json b/json/tests/draft4/optional/format/ipv6.json
index 9b0881e..2a08cb4 100644
--- a/json/tests/draft4/optional/format/ipv6.json
+++ b/json/tests/draft4/optional/format/ipv6.json
@@ -112,6 +112,41 @@
"description": "ipv4 segment must have 4 octets",
"data": "1:2:3:4:1.2.3",
"valid": false
+ },
+ {
+ "description": "leading whitespace is invalid",
+ "data": " ::1",
+ "valid": false
+ },
+ {
+ "description": "trailing whitespace is invalid",
+ "data": "::1 ",
+ "valid": false
+ },
+ {
+ "description": "netmask is not a part of ipv6 address",
+ "data": "fe80::/64",
+ "valid": false
+ },
+ {
+ "description": "zone id is not a part of ipv6 address",
+ "data": "fe80::a%eth1",
+ "valid": false
+ },
+ {
+ "description": "a long valid ipv6",
+ "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
+ "valid": true
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, first",
+ "data": "100:100:100:100:100:100:255.255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, second",
+ "data": "100:100:100:100:100:100:100:255.255.255.255",
+ "valid": false
}
]
}
diff --git a/json/tests/draft4/optional/format/uri.json b/json/tests/draft4/optional/format/uri.json
index 25cc40c..4306a68 100644
--- a/json/tests/draft4/optional/format/uri.json
+++ b/json/tests/draft4/optional/format/uri.json
@@ -97,6 +97,11 @@
"description": "an invalid URI with spaces and missing scheme",
"data": ":// should fail",
"valid": false
+ },
+ {
+ "description": "an invalid URI with comma in scheme",
+ "data": "bar,baz:foo",
+ "valid": false
}
]
}
diff --git a/json/tests/draft4/refRemote.json b/json/tests/draft4/refRemote.json
index 8611fad..ce5e99a 100644
--- a/json/tests/draft4/refRemote.json
+++ b/json/tests/draft4/refRemote.json
@@ -54,7 +54,7 @@
"schema": {
"id": "http://localhost:1234/",
"items": {
- "id": "folder/",
+ "id": "baseUriChange/",
"items": {"$ref": "folderInteger.json"}
}
},
@@ -81,7 +81,7 @@
},
"definitions": {
"baz": {
- "id": "folder/",
+ "id": "baseUriChangeFolder/",
"type": "array",
"items": {"$ref": "folderInteger.json"}
}
@@ -110,7 +110,7 @@
},
"definitions": {
"baz": {
- "id": "folder/",
+ "id": "baseUriChangeFolderInSubschema/",
"definitions": {
"bar": {
"type": "array",
diff --git a/json/tests/draft4/uniqueItems.json b/json/tests/draft4/uniqueItems.json
index fb1ddb5..4846c77 100644
--- a/json/tests/draft4/uniqueItems.json
+++ b/json/tests/draft4/uniqueItems.json
@@ -113,6 +113,16 @@
"description": "objects are non-unique despite key order",
"data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}],
"valid": false
+ },
+ {
+ "description": "{\"a\": false} and {\"a\": 0} are unique",
+ "data": [{"a": false}, {"a": 0}],
+ "valid": true
+ },
+ {
+ "description": "{\"a\": true} and {\"a\": 1} are unique",
+ "data": [{"a": true}, {"a": 1}],
+ "valid": true
}
]
},
diff --git a/json/tests/draft6/const.json b/json/tests/draft6/const.json
index c53d04d..1c2cafc 100644
--- a/json/tests/draft6/const.json
+++ b/json/tests/draft6/const.json
@@ -126,6 +126,90 @@
]
},
{
+ "description": "const with [false] does not match [0]",
+ "schema": {"const": [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": "const with [true] does not match [1]",
+ "schema": {"const": [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": "const with {\"a\": false} does not match {\"a\": 0}",
+ "schema": {"const": {"a": false}},
+ "tests": [
+ {
+ "description": "{\"a\": false} is valid",
+ "data": {"a": false},
+ "valid": true
+ },
+ {
+ "description": "{\"a\": 0} is invalid",
+ "data": {"a": 0},
+ "valid": false
+ },
+ {
+ "description": "{\"a\": 0.0} is invalid",
+ "data": {"a": 0.0},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "const with {\"a\": true} does not match {\"a\": 1}",
+ "schema": {"const": {"a": true}},
+ "tests": [
+ {
+ "description": "{\"a\": true} is valid",
+ "data": {"a": true},
+ "valid": true
+ },
+ {
+ "description": "{\"a\": 1} is invalid",
+ "data": {"a": 1},
+ "valid": false
+ },
+ {
+ "description": "{\"a\": 1.0} is invalid",
+ "data": {"a": 1.0},
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "const with 0 does not match other zero-like types",
"schema": {"const": 0},
"tests": [
diff --git a/json/tests/draft6/optional/format/date-time.json b/json/tests/draft6/optional/format/date-time.json
index fc949e9..a6320a9 100644
--- a/json/tests/draft6/optional/format/date-time.json
+++ b/json/tests/draft6/optional/format/date-time.json
@@ -37,7 +37,7 @@
"description": "an invalid closing Z after time-zone offset",
"data": "1963-06-19T08:30:06.28123+01:00Z",
"valid": false
- },
+ },
{
"description": "an invalid date-time string",
"data": "06/19/1963 08:30:06 PST",
@@ -52,6 +52,16 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350T01:01:01",
"valid": false
+ },
+ {
+ "description": "invalid non-padded month dates",
+ "data": "1963-6-19T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded day dates",
+ "data": "1963-06-1T08:30:06.283185Z",
+ "valid": false
}
]
}
diff --git a/json/tests/draft6/optional/format/ipv6.json b/json/tests/draft6/optional/format/ipv6.json
index 9b0881e..2a08cb4 100644
--- a/json/tests/draft6/optional/format/ipv6.json
+++ b/json/tests/draft6/optional/format/ipv6.json
@@ -112,6 +112,41 @@
"description": "ipv4 segment must have 4 octets",
"data": "1:2:3:4:1.2.3",
"valid": false
+ },
+ {
+ "description": "leading whitespace is invalid",
+ "data": " ::1",
+ "valid": false
+ },
+ {
+ "description": "trailing whitespace is invalid",
+ "data": "::1 ",
+ "valid": false
+ },
+ {
+ "description": "netmask is not a part of ipv6 address",
+ "data": "fe80::/64",
+ "valid": false
+ },
+ {
+ "description": "zone id is not a part of ipv6 address",
+ "data": "fe80::a%eth1",
+ "valid": false
+ },
+ {
+ "description": "a long valid ipv6",
+ "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
+ "valid": true
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, first",
+ "data": "100:100:100:100:100:100:255.255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, second",
+ "data": "100:100:100:100:100:100:100:255.255.255.255",
+ "valid": false
}
]
}
diff --git a/json/tests/draft6/optional/format/uri.json b/json/tests/draft6/optional/format/uri.json
index 25cc40c..4306a68 100644
--- a/json/tests/draft6/optional/format/uri.json
+++ b/json/tests/draft6/optional/format/uri.json
@@ -97,6 +97,11 @@
"description": "an invalid URI with spaces and missing scheme",
"data": ":// should fail",
"valid": false
+ },
+ {
+ "description": "an invalid URI with comma in scheme",
+ "data": "bar,baz:foo",
+ "valid": false
}
]
}
diff --git a/json/tests/draft6/refRemote.json b/json/tests/draft6/refRemote.json
index 819d326..74a7862 100644
--- a/json/tests/draft6/refRemote.json
+++ b/json/tests/draft6/refRemote.json
@@ -54,7 +54,7 @@
"schema": {
"$id": "http://localhost:1234/",
"items": {
- "$id": "folder/",
+ "$id": "baseUriChange/",
"items": {"$ref": "folderInteger.json"}
}
},
@@ -81,7 +81,7 @@
},
"definitions": {
"baz": {
- "$id": "folder/",
+ "$id": "baseUriChangeFolder/",
"type": "array",
"items": {"$ref": "folderInteger.json"}
}
@@ -110,7 +110,7 @@
},
"definitions": {
"baz": {
- "$id": "folder/",
+ "$id": "baseUriChangeFolderInSubschema/",
"definitions": {
"bar": {
"type": "array",
diff --git a/json/tests/draft6/uniqueItems.json b/json/tests/draft6/uniqueItems.json
index fb1ddb5..4846c77 100644
--- a/json/tests/draft6/uniqueItems.json
+++ b/json/tests/draft6/uniqueItems.json
@@ -113,6 +113,16 @@
"description": "objects are non-unique despite key order",
"data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}],
"valid": false
+ },
+ {
+ "description": "{\"a\": false} and {\"a\": 0} are unique",
+ "data": [{"a": false}, {"a": 0}],
+ "valid": true
+ },
+ {
+ "description": "{\"a\": true} and {\"a\": 1} are unique",
+ "data": [{"a": true}, {"a": 1}],
+ "valid": true
}
]
},
diff --git a/json/tests/draft7/const.json b/json/tests/draft7/const.json
index c53d04d..1c2cafc 100644
--- a/json/tests/draft7/const.json
+++ b/json/tests/draft7/const.json
@@ -126,6 +126,90 @@
]
},
{
+ "description": "const with [false] does not match [0]",
+ "schema": {"const": [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": "const with [true] does not match [1]",
+ "schema": {"const": [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": "const with {\"a\": false} does not match {\"a\": 0}",
+ "schema": {"const": {"a": false}},
+ "tests": [
+ {
+ "description": "{\"a\": false} is valid",
+ "data": {"a": false},
+ "valid": true
+ },
+ {
+ "description": "{\"a\": 0} is invalid",
+ "data": {"a": 0},
+ "valid": false
+ },
+ {
+ "description": "{\"a\": 0.0} is invalid",
+ "data": {"a": 0.0},
+ "valid": false
+ }
+ ]
+ },
+ {
+ "description": "const with {\"a\": true} does not match {\"a\": 1}",
+ "schema": {"const": {"a": true}},
+ "tests": [
+ {
+ "description": "{\"a\": true} is valid",
+ "data": {"a": true},
+ "valid": true
+ },
+ {
+ "description": "{\"a\": 1} is invalid",
+ "data": {"a": 1},
+ "valid": false
+ },
+ {
+ "description": "{\"a\": 1.0} is invalid",
+ "data": {"a": 1.0},
+ "valid": false
+ }
+ ]
+ },
+ {
"description": "const with 0 does not match other zero-like types",
"schema": {"const": 0},
"tests": [
diff --git a/json/tests/draft7/optional/format/date-time.json b/json/tests/draft7/optional/format/date-time.json
index dfccee6..900fcb7 100644
--- a/json/tests/draft7/optional/format/date-time.json
+++ b/json/tests/draft7/optional/format/date-time.json
@@ -47,6 +47,16 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350T01:01:01",
"valid": false
+ },
+ {
+ "description": "invalid non-padded month dates",
+ "data": "1963-6-19T08:30:06.283185Z",
+ "valid": false
+ },
+ {
+ "description": "invalid non-padded day dates",
+ "data": "1963-06-1T08:30:06.283185Z",
+ "valid": false
}
]
}
diff --git a/json/tests/draft7/optional/format/date.json b/json/tests/draft7/optional/format/date.json
index cd23baa..453b51d 100644
--- a/json/tests/draft7/optional/format/date.json
+++ b/json/tests/draft7/optional/format/date.json
@@ -17,6 +17,16 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350",
"valid": false
+ },
+ {
+ "description": "invalidates non-padded month dates",
+ "data": "1998-1-20",
+ "valid": false
+ },
+ {
+ "description": "invalidates non-padded day dates",
+ "data": "1998-01-1",
+ "valid": false
}
]
}
diff --git a/json/tests/draft7/optional/format/ipv6.json b/json/tests/draft7/optional/format/ipv6.json
index 9b0881e..2a08cb4 100644
--- a/json/tests/draft7/optional/format/ipv6.json
+++ b/json/tests/draft7/optional/format/ipv6.json
@@ -112,6 +112,41 @@
"description": "ipv4 segment must have 4 octets",
"data": "1:2:3:4:1.2.3",
"valid": false
+ },
+ {
+ "description": "leading whitespace is invalid",
+ "data": " ::1",
+ "valid": false
+ },
+ {
+ "description": "trailing whitespace is invalid",
+ "data": "::1 ",
+ "valid": false
+ },
+ {
+ "description": "netmask is not a part of ipv6 address",
+ "data": "fe80::/64",
+ "valid": false
+ },
+ {
+ "description": "zone id is not a part of ipv6 address",
+ "data": "fe80::a%eth1",
+ "valid": false
+ },
+ {
+ "description": "a long valid ipv6",
+ "data": "1000:1000:1000:1000:1000:1000:255.255.255.255",
+ "valid": true
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, first",
+ "data": "100:100:100:100:100:100:255.255.255.255.255",
+ "valid": false
+ },
+ {
+ "description": "a long invalid ipv6, below length limit, second",
+ "data": "100:100:100:100:100:100:100:255.255.255.255",
+ "valid": false
}
]
}
diff --git a/json/tests/draft7/optional/format/uri.json b/json/tests/draft7/optional/format/uri.json
index 25cc40c..4306a68 100644
--- a/json/tests/draft7/optional/format/uri.json
+++ b/json/tests/draft7/optional/format/uri.json
@@ -97,6 +97,11 @@
"description": "an invalid URI with spaces and missing scheme",
"data": ":// should fail",
"valid": false
+ },
+ {
+ "description": "an invalid URI with comma in scheme",
+ "data": "bar,baz:foo",
+ "valid": false
}
]
}
diff --git a/json/tests/draft7/refRemote.json b/json/tests/draft7/refRemote.json
index 819d326..74a7862 100644
--- a/json/tests/draft7/refRemote.json
+++ b/json/tests/draft7/refRemote.json
@@ -54,7 +54,7 @@
"schema": {
"$id": "http://localhost:1234/",
"items": {
- "$id": "folder/",
+ "$id": "baseUriChange/",
"items": {"$ref": "folderInteger.json"}
}
},
@@ -81,7 +81,7 @@
},
"definitions": {
"baz": {
- "$id": "folder/",
+ "$id": "baseUriChangeFolder/",
"type": "array",
"items": {"$ref": "folderInteger.json"}
}
@@ -110,7 +110,7 @@
},
"definitions": {
"baz": {
- "$id": "folder/",
+ "$id": "baseUriChangeFolderInSubschema/",
"definitions": {
"bar": {
"type": "array",
diff --git a/json/tests/draft7/uniqueItems.json b/json/tests/draft7/uniqueItems.json
index fb1ddb5..4846c77 100644
--- a/json/tests/draft7/uniqueItems.json
+++ b/json/tests/draft7/uniqueItems.json
@@ -113,6 +113,16 @@
"description": "objects are non-unique despite key order",
"data": [{"a": 1, "b": 2}, {"b": 2, "a": 1}],
"valid": false
+ },
+ {
+ "description": "{\"a\": false} and {\"a\": 0} are unique",
+ "data": [{"a": false}, {"a": 0}],
+ "valid": true
+ },
+ {
+ "description": "{\"a\": true} and {\"a\": 1} are unique",
+ "data": [{"a": true}, {"a": 1}],
+ "valid": true
}
]
},
diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py
index 6b630cd..619a7ea 100644
--- a/jsonschema/__init__.py
+++ b/jsonschema/__init__.py
@@ -8,9 +8,6 @@ Most commonly, `validate` is the quickest way to simply validate a given
instance under a schema, and will create a validator for you.
"""
-from jsonschema.exceptions import (
- ErrorTree, FormatError, RefResolutionError, SchemaError, ValidationError
-)
from jsonschema._format import (
FormatChecker,
draft3_format_checker,
@@ -19,6 +16,13 @@ from jsonschema._format import (
draft7_format_checker,
)
from jsonschema._types import TypeChecker
+from jsonschema.exceptions import (
+ ErrorTree,
+ FormatError,
+ RefResolutionError,
+ SchemaError,
+ ValidationError,
+)
from jsonschema.validators import (
Draft3Validator,
Draft4Validator,
@@ -27,6 +31,7 @@ from jsonschema.validators import (
RefResolver,
validate,
)
+
try:
from importlib import metadata
except ImportError: # for Python<3.8
diff --git a/jsonschema/__main__.py b/jsonschema/__main__.py
index 82c29fd..fdc21e2 100644
--- a/jsonschema/__main__.py
+++ b/jsonschema/__main__.py
@@ -1,2 +1,3 @@
from jsonschema.cli import main
+
main()
diff --git a/jsonschema/_format.py b/jsonschema/_format.py
index 3c1e6fe..ce47864 100644
--- a/jsonschema/_format.py
+++ b/jsonschema/_format.py
@@ -1,7 +1,6 @@
import datetime
+import ipaddress
import re
-import socket
-import struct
from jsonschema.exceptions import FormatError
@@ -183,51 +182,41 @@ def is_email(instance):
return "@" in instance
-_ipv4_re = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
-
-
@_checks_drafts(
- draft3="ip-address", draft4="ipv4", draft6="ipv4", draft7="ipv4",
+ draft3="ip-address",
+ draft4="ipv4",
+ draft6="ipv4",
+ draft7="ipv4",
+ raises=ipaddress.AddressValueError,
)
def is_ipv4(instance):
if not isinstance(instance, str):
return True
- if not _ipv4_re.match(instance):
- return False
- return all(0 <= int(component) <= 255 for component in instance.split("."))
+ return ipaddress.IPv4Address(instance)
+
+
+@_checks_drafts(name="ipv6", raises=ipaddress.AddressValueError)
+def is_ipv6(instance):
+ if not isinstance(instance, str):
+ return True
+ return ipaddress.IPv6Address(instance)
-if hasattr(socket, "inet_pton"):
- # FIXME: Really this only should raise struct.error, but see the sadness
- # that is https://twistedmatrix.com/trac/ticket/9409
+try:
+ from fqdn import FQDN
+except ImportError:
+ pass
+else:
@_checks_drafts(
- name="ipv6", raises=(socket.error, struct.error, ValueError),
+ draft3="host-name",
+ draft4="hostname",
+ draft6="hostname",
+ draft7="hostname",
)
- def is_ipv6(instance):
+ def is_host_name(instance):
if not isinstance(instance, str):
return True
- return socket.inet_pton(socket.AF_INET6, instance)
-
-
-_host_name_re = re.compile(r"^[A-Za-z0-9][A-Za-z0-9\.\-]{1,255}$")
-
-
-@_checks_drafts(
- draft3="host-name",
- draft4="hostname",
- draft6="hostname",
- draft7="hostname",
-)
-def is_host_name(instance):
- if not isinstance(instance, str):
- return True
- if not _host_name_re.match(instance):
- return False
- components = instance.split(".")
- for component in components:
- if len(component) > 63:
- return False
- return True
+ return FQDN(instance).is_valid
try:
@@ -330,11 +319,18 @@ def is_regex(instance):
return re.compile(instance)
+if hasattr(datetime.date, "fromisoformat"):
+ _is_date = datetime.date.fromisoformat
+else:
+ def _is_date(instance):
+ return datetime.datetime.strptime(instance, "%Y-%m-%d")
+
+
@_checks_drafts(draft3="date", draft7="date", raises=ValueError)
def is_date(instance):
if not isinstance(instance, str):
return True
- return datetime.datetime.strptime(instance, "%Y-%m-%d")
+ return _is_date(instance)
@_checks_drafts(draft3="time", raises=ValueError)
diff --git a/jsonschema/benchmarks/issue232.py b/jsonschema/benchmarks/issue232.py
index b1b05b2..e08dff9 100644
--- a/jsonschema/benchmarks/issue232.py
+++ b/jsonschema/benchmarks/issue232.py
@@ -12,7 +12,6 @@ from pyrsistent import m
from jsonschema.tests._suite import Version
import jsonschema
-
issue232 = Version(
path=Path(__file__).parent / "issue232",
remotes=m(),
diff --git a/jsonschema/benchmarks/json_schema_test_suite.py b/jsonschema/benchmarks/json_schema_test_suite.py
index 5add505..4126fdc 100644
--- a/jsonschema/benchmarks/json_schema_test_suite.py
+++ b/jsonschema/benchmarks/json_schema_test_suite.py
@@ -9,6 +9,5 @@ from pyperf import Runner
from jsonschema.tests._suite import Suite
-
if __name__ == "__main__":
Suite().benchmark(runner=Runner())
diff --git a/jsonschema/cli.py b/jsonschema/cli.py
index 649273b..2ae93c2 100644
--- a/jsonschema/cli.py
+++ b/jsonschema/cli.py
@@ -200,8 +200,6 @@ parser.add_argument(
def parse_args(args):
arguments = vars(parser.parse_args(args=args or ["--help"]))
- if arguments["validator"] is None:
- arguments["validator"] = validator_for(arguments["schema"])
if arguments["output"] != "plain" and arguments["error_format"]:
raise parser.error(
"--error-format can only be used with --output plain"
@@ -238,6 +236,9 @@ def run(arguments, stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin):
except _CannotLoadFile:
return 1
+ if arguments["validator"] is None:
+ arguments["validator"] = validator_for(schema)
+
try:
arguments["validator"].check_schema(schema)
except SchemaError as error:
diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py
index 2c2ce4d..46ffced 100644
--- a/jsonschema/exceptions.py
+++ b/jsonschema/exceptions.py
@@ -10,7 +10,6 @@ import attr
from jsonschema import _utils
-
WEAK_MATCHES = frozenset(["anyOf", "oneOf"])
STRONG_MATCHES = frozenset()
diff --git a/jsonschema/tests/_helpers.py b/jsonschema/tests/_helpers.py
index 761b404..51fff4f 100644
--- a/jsonschema/tests/_helpers.py
+++ b/jsonschema/tests/_helpers.py
@@ -1,5 +1,5 @@
-from io import StringIO
from contextlib import contextmanager
+from io import StringIO
import sys
diff --git a/jsonschema/tests/test_cli.py b/jsonschema/tests/test_cli.py
index 8d2fdf7..08e92c4 100644
--- a/jsonschema/tests/test_cli.py
+++ b/jsonschema/tests/test_cli.py
@@ -7,9 +7,8 @@ import json
import os
import subprocess
import sys
-import tempfile
-from jsonschema import Draft4Validator, cli, __version__
+from jsonschema import Draft4Validator, Draft7Validator, __version__, cli
from jsonschema.exceptions import SchemaError, ValidationError
from jsonschema.tests._helpers import captured_output
from jsonschema.validators import _LATEST_VERSION, validate
@@ -676,7 +675,7 @@ class TestCLI(TestCase):
stderr="",
)
- def test_successful_validation__of_just_the_schema_pretty_output(self):
+ def test_successful_validation_of_just_the_schema_pretty_output(self):
self.assertOutputs(
files=dict(some_schema="{}", some_instance="{}"),
argv=["--output", "pretty", "-i", "some_instance", "some_schema"],
@@ -684,35 +683,54 @@ class TestCLI(TestCase):
stderr="",
)
- def test_successful_validation_with_specifying_base_uri(self):
- try:
- schema_file = tempfile.NamedTemporaryFile(
- mode='w+',
- prefix='schema',
- suffix='.json',
- dir='..',
- delete=False
- )
- self.addCleanup(os.remove, schema_file.name)
- schema = """
- {"type": "object", "properties": {"KEY1":
- {"$ref": %s%s#definitions/schemas"}},
- "definitions": {"schemas": {"type": "string"}}}
- """ % ("\"", os.path.basename(schema_file.name))
- schema_file.write(schema)
- finally:
- schema_file.close()
+ def test_it_validates_using_the_latest_validator_when_unspecified(self):
+ # There isn't a better way now I can think of to ensure that the
+ # latest version was used, given that the call to validator_for
+ # is hidden inside the CLI, so guard that that's the case, and
+ # this test will have to be updated when versions change until
+ # we can think of a better way to ensure this behavior.
+ self.assertIs(Draft7Validator, _LATEST_VERSION)
self.assertOutputs(
- files=dict(some_schema=schema, some_instance='{"KEY1": "1"}'),
- argv=["-i", "some_instance", "--base-uri", "..", "some_schema"],
+ files=dict(some_schema='{"const": "check"}', some_instance='"a"'),
+ argv=["-i", "some_instance", "some_schema"],
+ exit_code=1,
stdout="",
- stderr="",
+ stderr="a: 'check' was expected\n",
+ )
+
+ def test_it_validates_using_draft7_when_specified(self):
+ """
+ Specifically, `const` validation applies for Draft 7.
+ """
+ schema = """
+ {
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "const": "check"
+ }
+ """
+ instance = '"foo"'
+ self.assertOutputs(
+ files=dict(some_schema=schema, some_instance=instance),
+ argv=["-i", "some_instance", "some_schema"],
+ exit_code=1,
+ stdout="",
+ stderr="foo: 'check' was expected\n",
)
- def test_real_validator(self):
+ def test_it_validates_using_draft4_when_specified(self):
+ """
+ Specifically, `const` validation *does not* apply for Draft 4.
+ """
+ schema = """
+ {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "const": "check"
+ }
+ """
+ instance = '"foo"'
self.assertOutputs(
- files=dict(some_schema='{"minimum": 30}', some_instance="37"),
+ files=dict(some_schema=schema, some_instance=instance),
argv=["-i", "some_instance", "some_schema"],
stdout="",
stderr="",
@@ -744,15 +762,6 @@ class TestParser(TestCase):
)
self.assertIs(arguments["validator"], Draft4Validator)
- def test_latest_validator_is_the_default(self):
- arguments = cli.parse_args(
- [
- "--instance", "mem://some/instance",
- "mem://some/schema",
- ]
- )
- self.assertIs(arguments["validator"], _LATEST_VERSION)
-
def test_unknown_output(self):
# Avoid the help message on stdout
with captured_output() as (stdout, stderr):
@@ -809,4 +818,4 @@ class TestCLIIntegration(TestCase):
[sys.executable, "-m", "jsonschema", "--help"],
stderr=subprocess.STDOUT,
)
- self.assertEqual(output, output_for_help)
+ self.assertEqual(output, output_for_help) \ No newline at end of file
diff --git a/jsonschema/tests/test_format.py b/jsonschema/tests/test_format.py
index 254985f..6dba484 100644
--- a/jsonschema/tests/test_format.py
+++ b/jsonschema/tests/test_format.py
@@ -4,10 +4,9 @@ Tests for the parts of jsonschema related to the :validator:`format` property.
from unittest import TestCase
-from jsonschema import FormatError, ValidationError, FormatChecker
+from jsonschema import FormatChecker, FormatError, ValidationError
from jsonschema.validators import Draft4Validator
-
BOOM = ValueError("Boom!")
BANG = ZeroDivisionError("Bang!")
diff --git a/jsonschema/tests/test_jsonschema_test_suite.py b/jsonschema/tests/test_jsonschema_test_suite.py
index e561f3e..0f9698a 100644
--- a/jsonschema/tests/test_jsonschema_test_suite.py
+++ b/jsonschema/tests/test_jsonschema_test_suite.py
@@ -23,7 +23,6 @@ from jsonschema.tests._helpers import bug
from jsonschema.tests._suite import Suite
from jsonschema.validators import _DEPRECATED_DEFAULT_TYPES, create
-
SUITE = Suite()
DRAFT3 = SUITE.version(name="draft3")
DRAFT4 = SUITE.version(name="draft4")
@@ -88,6 +87,24 @@ else:
return
+if sys.version_info < (3, 7):
+ message = "datetime.date.fromisoformat is new in 3.7+"
+
+ def missing_date_fromisoformat(test):
+ return skip(
+ message=message,
+ subject="date",
+ description="invalidates non-padded month dates",
+ )(test) or skip(
+ message=message,
+ subject="date",
+ description="invalidates non-padded day dates",
+ )(test)
+else:
+ def missing_date_fromisoformat(test):
+ return
+
+
TestDraft3 = DRAFT3.to_unittest_testcase(
DRAFT3.tests(),
DRAFT3.format_tests(),
@@ -98,6 +115,7 @@ TestDraft3 = DRAFT3.to_unittest_testcase(
format_checker=draft3_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
+ or missing_date_fromisoformat(test)
or missing_format(draft3_format_checker)(test)
or complex_email_validation(test)
or skip(
@@ -106,11 +124,6 @@ TestDraft3 = DRAFT3.to_unittest_testcase(
description="case-insensitive T and Z",
)(test)
or skip(
- message=bug(),
- subject="host-name",
- description="ends with hyphen",
- )(test)
- or skip(
message=bug(686),
subject="uniqueItems",
description="[0] and [false] are unique",
@@ -130,6 +143,16 @@ TestDraft3 = DRAFT3.to_unittest_testcase(
subject="uniqueItems",
description="nested [1] and [true] are unique",
)(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": false} and {"a": 0} are unique',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": true} and {"a": 1} are unique',
+ )(test)
),
)
@@ -144,6 +167,7 @@ TestDraft4 = DRAFT4.to_unittest_testcase(
format_checker=draft4_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
+ or missing_date_fromisoformat(test)
or missing_format(draft4_format_checker)(test)
or complex_email_validation(test)
or skip(
@@ -181,11 +205,6 @@ TestDraft4 = DRAFT4.to_unittest_testcase(
description="case-insensitive T and Z",
)(test)
or skip(
- message=bug(),
- subject="hostname",
- description="ends with hyphen",
- )(test)
- or skip(
message=bug(686),
subject="uniqueItems",
description="[0] and [false] are unique",
@@ -205,6 +224,16 @@ TestDraft4 = DRAFT4.to_unittest_testcase(
subject="uniqueItems",
description="nested [1] and [true] are unique",
)(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": false} and {"a": 0} are unique',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": true} and {"a": 1} are unique',
+ )(test)
),
)
@@ -218,6 +247,7 @@ TestDraft6 = DRAFT6.to_unittest_testcase(
format_checker=draft6_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
+ or missing_date_fromisoformat(test)
or missing_format(draft6_format_checker)(test)
or complex_email_validation(test)
or skip(
@@ -255,11 +285,6 @@ TestDraft6 = DRAFT6.to_unittest_testcase(
description="case-insensitive T and Z",
)(test)
or skip(
- message=bug(),
- subject="hostname",
- description="ends with hyphen",
- )(test)
- or skip(
message=bug(686),
subject="uniqueItems",
description="[0] and [false] are unique",
@@ -279,6 +304,36 @@ TestDraft6 = DRAFT6.to_unittest_testcase(
subject="uniqueItems",
description="nested [1] and [true] are unique",
)(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": false} and {"a": 0} are unique',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": true} and {"a": 1} are unique',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description="const with [false] does not match [0]",
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description="const with [true] does not match [1]",
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description='const with {"a": false} does not match {"a": 0}',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description='const with {"a": true} does not match {"a": 1}',
+ )(test)
),
)
@@ -293,6 +348,7 @@ TestDraft7 = DRAFT7.to_unittest_testcase(
format_checker=draft7_format_checker,
skip=lambda test: (
narrow_unicode_build(test)
+ or missing_date_fromisoformat(test)
or missing_format(draft7_format_checker)(test)
or complex_email_validation(test)
or skip(
@@ -330,11 +386,6 @@ TestDraft7 = DRAFT7.to_unittest_testcase(
description="case-insensitive T and Z",
)(test)
or skip(
- message=bug(),
- subject="hostname",
- description="ends with hyphen",
- )(test)
- or skip(
message=bug(593),
subject="content",
valid=False,
@@ -376,6 +427,36 @@ TestDraft7 = DRAFT7.to_unittest_testcase(
subject="uniqueItems",
description="nested [1] and [true] are unique",
)(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": false} and {"a": 0} are unique',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="uniqueItems",
+ description='{"a": true} and {"a": 1} are unique',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description="const with [false] does not match [0]",
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description="const with [true] does not match [1]",
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description='const with {"a": false} does not match {"a": 0}',
+ )(test)
+ or skip(
+ message=bug(686),
+ subject="const",
+ case_description='const with {"a": true} does not match {"a": 1}',
+ )(test)
),
)
diff --git a/jsonschema/validators.py b/jsonschema/validators.py
index 2ea23ac..d6e0a0c 100644
--- a/jsonschema/validators.py
+++ b/jsonschema/validators.py
@@ -17,11 +17,11 @@ from jsonschema import (
_validators,
exceptions,
)
-
# Sigh. https://gitlab.com/pycqa/flake8/issues/280
# https://github.com/pyga/ebb-lint/issues/7
# Imported for backwards compatibility.
from jsonschema.exceptions import ErrorTree
+
ErrorTree
diff --git a/pyproject.toml b/pyproject.toml
index 9cdcbf7..477d5e6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,4 +8,9 @@ requires = [
]
build-backend = "setuptools.build_meta"
+[tool.isort]
+from_first = true
+include_trailing_comma = true
+multi_line_output = 3
+
[tool.setuptools_scm]
diff --git a/setup.cfg b/setup.cfg
index 4b61748..6464c6e 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -32,12 +32,14 @@ install_requires =
[options.extras_require]
format =
+ fqdn
idna
jsonpointer>1.13
rfc3987
strict-rfc3339
webcolors
format_nongpl =
+ fqdn
idna
jsonpointer>1.13
webcolors
diff --git a/tox.ini b/tox.ini
index f60161c..3deb5a3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,6 @@
[tox]
envlist =
- py{36,37,38,py3}-{build,tests,tests_nongpl},
- demo
+ py{36,37,38,py3}-{noextra,format,format_nongpl}-{build,tests},
readme
safety
secrets
@@ -16,10 +15,11 @@ setenv =
whitelist_externals =
mkdir
commands =
- perf,tests: {envpython} -m pip install '{toxinidir}[format]'
- tests_nongpl: {envpython} -m pip install '{toxinidir}[format_nongpl]'
+ noextra: {envpython} -m pip install {toxinidir}
+ format: {envpython} -m pip install '{toxinidir}[format]'
+ format_nongpl: {envpython} -m pip install '{toxinidir}[format_nongpl]'
- tests,tests_nongpl: {envpython} -m twisted.trial {posargs:jsonschema}
+ tests: {envpython} -m twisted.trial {posargs:jsonschema}
tests: {envpython} -m doctest {toxinidir}/README.rst
perf: mkdir {envtmpdir}/benchmarks/
@@ -33,7 +33,7 @@ deps =
perf: pyperf
- tests,tests_nongpl,coverage,codecov: twisted
+ tests,coverage,codecov: twisted
coverage,codecov: coverage
codecov: codecov
@@ -42,11 +42,6 @@ deps =
deps = bandit
commands = {envbindir}/bandit --recursive {toxinidir}/jsonschema
-[testenv:demo]
-deps = jupyter
-commands =
- {envbindir}/jupyter nbconvert --output-dir {envtmpdir} {toxinidir}/DEMO.ipynb
-
[testenv:readme]
deps =
docutils