🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

jsonschema

Package Overview
Dependencies
Maintainers
0
Versions
109
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsonschema - pypi Package Compare versions

Comparing version
4.23.0
to
4.24.0
+35
.github/workflows/zizmor.yml
name: GitHub Actions Security Analysis with zizmor 🌈
on:
push:
branches: ["main"]
pull_request:
branches: ["**"]
jobs:
zizmor:
name: Run zizmor
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb
- name: Run zizmor 🌈
run: uvx zizmor --format=sarif .github > results.sarif
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
category: zizmor
name: Validate annotation tests
on:
pull_request:
paths:
- "annotations/**"
jobs:
annotate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Deno
uses: denoland/setup-deno@v2
with:
deno-version: "2.x"
- name: Validate annotation tests
run: deno --node-modules-dir=auto --allow-read --no-prompt bin/annotation-tests.ts
name: Check PR Dependencies
on: pull_request
jobs:
check_dependencies:
runs-on: ubuntu-latest
name: Check Dependencies
steps:
- uses: gregsdennis/dependencies-action@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: Show Specification Annotations
on:
pull_request:
paths:
- 'tests/**'
jobs:
annotate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate Annotations
run: pip install uritemplate && bin/annotate-specification-links
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"location": {
"markdownDescription": "The instance location.",
"type": "string",
"format": "json-pointer"
},
"keyword": {
"markdownDescription": "The annotation keyword.",
"type": "string"
},
"expected": {
"markdownDescription": "An object of schemaLocation/annotations pairs for `keyword` annotations expected on the instance at `location`.",
"type": "object",
"propertyNames": {
"format": "uri"
}
}
},
"required": ["location", "keyword", "expected"]
}
# Annotations Tests Suite
The Annotations Test Suite tests which annotations should appear (or not appear)
on which values of an instance. These tests are agnostic of any output format.
## Supported Dialects
Although the annotation terminology of didn't appear in the spec until 2019-09,
the concept is compatible with every version of JSON Schema. Test Cases in this
Test Suite are designed to be compatible with as many releases of JSON Schema as
possible. They do not include `$schema` or `$id`/`id` keywords so
implementations can run the same Test Suite for each dialect they support.
Since this Test Suite can be used for a variety of dialects, there are a couple
of options that can be used by Test Runners to filter out Test Cases that don't
apply to the dialect under test.
## Test Case Components
### description
A short description of what behavior the Test Case is covering.
### compatibility
The `compatibility` option allows you to set which dialects the Test Case is
compatible with. Test Runners can use this value to filter out Test Cases that
don't apply the to dialect currently under test. The terminology for annotations
didn't appear in the spec until 2019-09, but the concept is compatible with
older releases as well. When setting `compatibility`, test authors should take
into account dialects before 2019-09 for implementations that chose to support
annotations for older dialects.
Dialects are indicated by the number corresponding to their release. Date-based
releases use just the year. If this option isn't present, it means the Test Case
is compatible with any dialect.
If this option is present with a number, the number indicates the minimum
release the Test Case is compatible with. This example indicates that the Test
Case is compatible with draft-07 and up.
**Example**: `"compatibility": "7"`
You can use a `<=` operator to indicate that the Test Case is compatible with
releases less then or equal to the given release. This example indicates that
the Test Case is compatible with 2019-09 and under.
**Example**: `"compatibility": "<=2019"`
You can use comma-separated values to indicate multiple constraints if needed.
This example indicates that the Test Case is compatible with releases between
draft-06 and 2019-09.
**Example**: `"compatibility": "6,<=2019"`
For convenience, you can use the `=` operator to indicate a Test Case is only
compatible with a single release. This example indicates that the Test Case is
compatible only with 2020-12.
**Example**: `"compatibility": "=2020"`
### schema
The schema that will serve as the subject for the tests. Whenever possible, this
schema shouldn't include `$schema` or `id`/`$id` because Test Cases should be
designed to work with as many releases as possible.
### externalSchemas
This allows you to define additional schemas that `schema` makes references to.
The value is an object where the keys are retrieval URIs and values are schemas.
Most external schemas aren't self identifying (using `id`/`$id`) and rely on the
retrieval URI for identification. This is done to increase the number of
dialects that the test is compatible with. Because `id` changed to `$id` in
draft-06, if you use `$id`, the test becomes incompatible with draft-03/4 and in
most cases, that's not necessary.
### tests
A collection of Tests to run to verify the Test Case.
## Test Components
### instance
The JSON instance to be annotated.
### assertions
A collection of assertions that must be true for the test to pass.
## Assertions Components
### location
The instance location.
### keyword
The annotating keyword.
### expected
A collection of `keyword` annotations expected on the instance at `location`.
`expected` is an object where the keys are schema locations and the values are
the annotation that schema location contributed for the given `keyword`.
There can be more than one expected annotation because multiple schema locations
could contribute annotations for a single keyword.
An empty object is an assertion that the annotation must not appear at the
`location` for the `keyword`.
As a convention for this Test Suite, the `expected` array should be sorted such
that the most recently encountered value for an annotation given top-down
evaluation of the schema comes before previously encountered values.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"description": {
"markdownDescription": "A short description of what behavior the Test Case is covering.",
"type": "string"
},
"compatibility": {
"markdownDescription": "Set which dialects the Test Case is compatible with. Examples:\n- `\"7\"` -- draft-07 and above\n- `\"<=2019\"` -- 2019-09 and previous\n- `\"6,<=2019\"` -- Between draft-06 and 2019-09\n- `\"=2020\"` -- 2020-12 only",
"type": "string",
"pattern": "^(<=|=)?([123467]|2019|2020)(,(<=|=)?([123467]|2019|2020))*$"
},
"schema": {
"markdownDescription": "This schema shouldn't include `$schema` or `id`/`$id` unless necesary for the test because Test Cases should be designed to work with as many releases as possible.",
"type": ["boolean", "object"]
},
"externalSchemas": {
"markdownDescription": "The keys are retrieval URIs and values are schemas.",
"type": "object",
"patternProperties": {
"": {
"type": ["boolean", "object"]
}
},
"propertyNames": {
"format": "uri"
}
},
"tests": {
"markdownDescription": "A collection of Tests to run to verify the Test Case.",
"type": "array",
"items": { "$ref": "./test.schema.json" }
}
},
"required": ["description", "schema", "tests"]
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"description": {
"type": "string"
},
"suite": {
"type": "array",
"items": { "$ref": "./test-case.schema.json" }
}
},
"required": ["description", "suite"]
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"instance": {
"markdownDescription": "The JSON instance to be annotated."
},
"assertions": {
"markdownDescription": "A collection of assertions that must be true for the test to pass.",
"type": "array",
"items": { "$ref": "./assertion.schema.json" }
}
},
"required": ["instance", "assertions"]
}
{
"$schema": "../test-suite.schema.json",
"description": "The applicator vocabulary",
"suite": [
{
"description": "`properties`, `patternProperties`, and `additionalProperties`",
"compatibility": "3",
"schema": {
"properties": {
"foo": {
"title": "Foo"
}
},
"patternProperties": {
"^a": {
"title": "Bar"
}
},
"additionalProperties": {
"title": "Baz"
}
},
"tests": [
{
"instance": {},
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {}
},
{
"location": "/apple",
"keyword": "title",
"expected": {}
},
{
"location": "/bar",
"keyword": "title",
"expected": {}
}
]
},
{
"instance": {
"foo": {},
"apple": {},
"baz": {}
},
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/properties/foo": "Foo"
}
},
{
"location": "/apple",
"keyword": "title",
"expected": {
"#/patternProperties/%5Ea": "Bar"
}
},
{
"location": "/baz",
"keyword": "title",
"expected": {
"#/additionalProperties": "Baz"
}
}
]
}
]
},
{
"description": "`propertyNames` doesn't annotate property values",
"compatibility": "6",
"schema": {
"propertyNames": {
"const": "foo",
"title": "Foo"
}
},
"tests": [
{
"instance": {
"foo": 42
},
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {}
}
]
}
]
},
{
"description": "`prefixItems` and `items`",
"compatibility": "2020",
"schema": {
"prefixItems": [
{
"title": "Foo"
}
],
"items": {
"title": "Bar"
}
},
"tests": [
{
"instance": [
"foo",
"bar"
],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/prefixItems/0": "Foo"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/items": "Bar"
}
},
{
"location": "/2",
"keyword": "title",
"expected": {}
}
]
}
]
},
{
"description": "`contains`",
"compatibility": "6",
"schema": {
"contains": {
"type": "number",
"title": "Foo"
}
},
"tests": [
{
"instance": [
"foo",
42,
true
],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/contains": "Foo"
}
},
{
"location": "/2",
"keyword": "title",
"expected": {}
},
{
"location": "/3",
"keyword": "title",
"expected": {}
}
]
}
]
},
{
"description": "`allOf`",
"compatibility": "4",
"schema": {
"allOf": [
{
"title": "Foo"
},
{
"title": "Bar"
}
]
},
"tests": [
{
"instance": "foo",
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/allOf/1": "Bar",
"#/allOf/0": "Foo"
}
}
]
}
]
},
{
"description": "`anyOf`",
"compatibility": "4",
"schema": {
"anyOf": [
{
"type": "integer",
"title": "Foo"
},
{
"type": "number",
"title": "Bar"
}
]
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/anyOf/1": "Bar",
"#/anyOf/0": "Foo"
}
}
]
},
{
"instance": 4.2,
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/anyOf/1": "Bar"
}
}
]
}
]
},
{
"description": "`oneOf`",
"compatibility": "4",
"schema": {
"oneOf": [
{
"type": "string",
"title": "Foo"
},
{
"type": "number",
"title": "Bar"
}
]
},
"tests": [
{
"instance": "foo",
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/oneOf/0": "Foo"
}
}
]
},
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/oneOf/1": "Bar"
}
}
]
}
]
},
{
"description": "`not`",
"compatibility": "4",
"schema": {
"title": "Foo",
"not": {
"not": {
"title": "Bar"
}
}
},
"tests": [
{
"instance": {},
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#": "Foo"
}
}
]
}
]
},
{
"description": "`dependentSchemas`",
"compatibility": "2019",
"schema": {
"dependentSchemas": {
"foo": {
"title": "Foo"
}
}
},
"tests": [
{
"instance": {
"foo": 42
},
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/dependentSchemas/foo": "Foo"
}
}
]
},
{
"instance": {
"foo": 42
},
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {}
}
]
}
]
},
{
"description": "`if`, `then`, and `else`",
"compatibility": "7",
"schema": {
"if": {
"title": "If",
"type": "string"
},
"then": {
"title": "Then"
},
"else": {
"title": "Else"
}
},
"tests": [
{
"instance": "foo",
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/then": "Then",
"#/if": "If"
}
}
]
},
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/else": "Else"
}
}
]
}
]
}
]
}
{
"$schema": "../test-suite.schema.json",
"description": "The content vocabulary",
"suite": [
{
"description": "`contentMediaType` is an annotation for string instances",
"compatibility": "7",
"schema": {
"contentMediaType": "application/json"
},
"tests": [
{
"instance": "{ \"foo\": \"bar\" }",
"assertions": [
{
"location": "",
"keyword": "contentMediaType",
"expected": {
"#": "application/json"
}
}
]
},
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "contentMediaType",
"expected": {}
}
]
}
]
},
{
"description": "`contentEncoding` is an annotation for string instances",
"compatibility": "7",
"schema": {
"contentEncoding": "base64"
},
"tests": [
{
"instance": "SGVsbG8gZnJvbSBKU09OIFNjaGVtYQ==",
"assertions": [
{
"location": "",
"keyword": "contentEncoding",
"expected": {
"#": "base64"
}
}
]
},
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "contentEncoding",
"expected": {}
}
]
}
]
},
{
"description": "`contentSchema` is an annotation for string instances",
"compatibility": "2019",
"schema": {
"$id": "https://annotations.json-schema.org/test/contentSchema-is-an-annotation",
"contentMediaType": "application/json",
"contentSchema": { "type": "number" }
},
"tests": [
{
"instance": "42",
"assertions": [
{
"location": "",
"keyword": "contentSchema",
"expected": {
"#": { "type": "number" }
}
}
]
},
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "contentSchema",
"expected": {}
}
]
}
]
},
{
"description": "`contentSchema` requires `contentMediaType`",
"compatibility": "2019",
"schema": {
"$id": "https://annotations.json-schema.org/test/contentSchema-is-an-annotation",
"contentSchema": { "type": "number" }
},
"tests": [
{
"instance": "42",
"assertions": [
{
"location": "",
"keyword": "contentSchema",
"expected": {}
}
]
}
]
}
]
}
{
"$schema": "../test-suite.schema.json",
"description": "The core vocabulary",
"suite": [
{
"description": "`$ref` and `$defs`",
"compatibility": "2019",
"schema": {
"$ref": "#/$defs/foo",
"$defs": {
"foo": { "title": "Foo" }
}
},
"tests": [
{
"instance": "foo",
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#/$defs/foo": "Foo"
}
}
]
}
]
}
]
}
{
"$schema": "../test-suite.schema.json",
"description": "The format vocabulary",
"suite": [
{
"description": "`format` is an annotation",
"schema": {
"format": "email"
},
"tests": [
{
"instance": "foo@bar.com",
"assertions": [
{
"location": "",
"keyword": "format",
"expected": {
"#": "email"
}
}
]
}
]
}
]
}
{
"$schema": "../test-suite.schema.json",
"description": "The meta-data vocabulary",
"suite": [
{
"description": "`title` is an annotation",
"schema": {
"title": "Foo"
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "title",
"expected": {
"#": "Foo"
}
}
]
}
]
},
{
"description": "`description` is an annotation",
"schema": {
"description": "Foo"
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "description",
"expected": {
"#": "Foo"
}
}
]
}
]
},
{
"description": "`default` is an annotation",
"schema": {
"default": "Foo"
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "default",
"expected": {
"#": "Foo"
}
}
]
}
]
},
{
"description": "`deprecated` is an annotation",
"compatibility": "2019",
"schema": {
"deprecated": true
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "deprecated",
"expected": {
"#": true
}
}
]
}
]
},
{
"description": "`readOnly` is an annotation",
"compatibility": "7",
"schema": {
"readOnly": true
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "readOnly",
"expected": {
"#": true
}
}
]
}
]
},
{
"description": "`writeOnly` is an annotation",
"compatibility": "7",
"schema": {
"writeOnly": true
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "writeOnly",
"expected": {
"#": true
}
}
]
}
]
},
{
"description": "`examples` is an annotation",
"compatibility": "6",
"schema": {
"examples": ["Foo", "Bar"]
},
"tests": [
{
"instance": "Foo",
"assertions": [
{
"location": "",
"keyword": "examples",
"expected": {
"#": ["Foo", "Bar"]
}
}
]
}
]
}
]
}
{
"$schema": "../test-suite.schema.json",
"description": "The unevaluated vocabulary",
"suite": [
{
"description": "`unevaluatedProperties` alone",
"compatibility": "2019",
"schema": {
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `properties`",
"compatibility": "2019",
"schema": {
"properties": {
"foo": { "title": "Evaluated" }
},
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/properties/foo": "Evaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `patternProperties`",
"compatibility": "2019",
"schema": {
"patternProperties": {
"^a": { "title": "Evaluated" }
},
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "apple": 42, "bar": 24 },
"assertions": [
{
"location": "/apple",
"keyword": "title",
"expected": {
"#/patternProperties/%5Ea": "Evaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `additionalProperties`",
"compatibility": "2019",
"schema": {
"additionalProperties": { "title": "Evaluated" },
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/additionalProperties": "Evaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/additionalProperties": "Evaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `dependentSchemas`",
"compatibility": "2019",
"schema": {
"dependentSchemas": {
"foo": {
"properties": {
"bar": { "title": "Evaluated" }
}
}
},
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/dependentSchemas/foo/properties/bar": "Evaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `if`, `then`, and `else`",
"compatibility": "2019",
"schema": {
"if": {
"properties": {
"foo": {
"type": "string",
"title": "If"
}
}
},
"then": {
"properties": {
"foo": { "title": "Then" }
}
},
"else": {
"properties": {
"foo": { "title": "Else" }
}
},
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": "", "bar": 42 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/then/properties/foo": "Then",
"#/if/properties/foo": "If"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
},
{
"instance": { "foo": 42, "bar": "" },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/else/properties/foo": "Else"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `allOf`",
"compatibility": "2019",
"schema": {
"allOf": [
{
"properties": {
"foo": { "title": "Evaluated" }
}
}
],
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/allOf/0/properties/foo": "Evaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `anyOf`",
"compatibility": "2019",
"schema": {
"anyOf": [
{
"properties": {
"foo": { "title": "Evaluated" }
}
}
],
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/anyOf/0/properties/foo": "Evaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `oneOf`",
"compatibility": "2019",
"schema": {
"oneOf": [
{
"properties": {
"foo": { "title": "Evaluated" }
}
}
],
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/oneOf/0/properties/foo": "Evaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedProperties` with `not`",
"compatibility": "2019",
"schema": {
"not": {
"not": {
"properties": {
"foo": { "title": "Evaluated" }
}
}
},
"unevaluatedProperties": { "title": "Unevaluated" }
},
"tests": [
{
"instance": { "foo": 42, "bar": 24 },
"assertions": [
{
"location": "/foo",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
},
{
"location": "/bar",
"keyword": "title",
"expected": {
"#/unevaluatedProperties": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` alone",
"compatibility": "2019",
"schema": {
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": [42, 24],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` with `prefixItems`",
"compatibility": "2020",
"schema": {
"prefixItems": [{ "title": "Evaluated" }],
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": [42, 24],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/prefixItems/0": "Evaluated"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` with `contains`",
"compatibility": "2020",
"schema": {
"contains": {
"type": "string",
"title": "Evaluated"
},
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": ["foo", 42],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/contains": "Evaluated"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` with `if`, `then`, and `else`",
"compatibility": "2020",
"schema": {
"if": {
"prefixItems": [
{
"type": "string",
"title": "If"
}
]
},
"then": {
"prefixItems": [
{ "title": "Then" }
]
},
"else": {
"prefixItems": [
{ "title": "Else" }
]
},
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": ["", 42],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/then/prefixItems/0": "Then",
"#/if/prefixItems/0": "If"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
},
{
"instance": [42, ""],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/else/prefixItems/0": "Else"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` with `allOf`",
"compatibility": "2020",
"schema": {
"allOf": [
{
"prefixItems": [
{ "title": "Evaluated" }
]
}
],
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": [42, 24],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/allOf/0/prefixItems/0": "Evaluated"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` with `anyOf`",
"compatibility": "2020",
"schema": {
"anyOf": [
{
"prefixItems": [
{ "title": "Evaluated" }
]
}
],
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": [42, 24],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/anyOf/0/prefixItems/0": "Evaluated"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` with `oneOf`",
"compatibility": "2020",
"schema": {
"oneOf": [
{
"prefixItems": [
{ "title": "Evaluated" }
]
}
],
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": [42, 24],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/oneOf/0/prefixItems/0": "Evaluated"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
},
{
"description": "`unevaluatedItems` with `not`",
"compatibility": "2020",
"schema": {
"not": {
"not": {
"prefixItems": [
{ "title": "Evaluated" }
]
}
},
"unevaluatedItems": { "title": "Unevaluated" }
},
"tests": [
{
"instance": [42, 24],
"assertions": [
{
"location": "/0",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
},
{
"location": "/1",
"keyword": "title",
"expected": {
"#/unevaluatedItems": "Unevaluated"
}
}
]
}
]
}
]
}
{
"$schema": "../test-suite.schema.json",
"description": "Unknown keywords",
"suite": [
{
"description": "`unknownKeyword` is an annotation",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"x-unknownKeyword": "Foo"
},
"tests": [
{
"instance": 42,
"assertions": [
{
"location": "",
"keyword": "x-unknownKeyword",
"expected": {
"#": "Foo"
}
}
]
}
]
}
]
}

Sorry, the diff of this file is not supported yet

#!/usr/bin/env deno
import { validate } from "npm:@hyperjump/json-schema/draft-07";
import { BASIC } from "npm:@hyperjump/json-schema/experimental";
const validateTestSuite = await validate("./annotations/test-suite.schema.json");
console.log("Validating annotation tests ...");
let isValid = true;
for await (const entry of Deno.readDir("./annotations/tests")) {
if (entry.isFile) {
const json = await Deno.readTextFile(`./annotations/tests/${entry.name}`);
const suite = JSON.parse(json);
const output = validateTestSuite(suite, BASIC);
if (output.valid) {
console.log(`\x1b[32m✔\x1b[0m ${entry.name}`);
} else {
isValid = false;
console.log(`\x1b[31m✖\x1b[0m ${entry.name}`);
console.log(output);
}
}
}
console.log("Done.");
if (!isValid) {
Deno.exit(1);
}
{
"json-schema": {
"draft2020-12": {
"core": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-01#section-{section}",
"validation": "https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#section-{section}"
},
"draft2019-09": {
"core": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-02#rfc.section.{section}",
"validation": "https://json-schema.org/draft/2019-09/draft-handrews-json-schema-validation-02#rfc.section.{section}"
},
"draft7": {
"core": "https://json-schema.org/draft-07/draft-handrews-json-schema-01#rfc.section.{section}",
"validation": "https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01#rfc.section.{section}"
},
"draft6": {
"core": "https://json-schema.org/draft-06/draft-wright-json-schema-01#rfc.section.{section}",
"validation": "https://json-schema.org/draft-06/draft-wright-json-schema-validation-01#rfc.section.{section}"
},
"draft4": {
"core": "https://json-schema.org/draft-04/draft-zyp-json-schema-04#rfc.section.{section}",
"validation": "https://json-schema.org/draft-04/draft-fge-json-schema-validation-00#rfc.section.{section}"
},
"draft3": {
"core": "https://json-schema.org/draft-03/draft-zyp-json-schema-03.pdf"
}
},
"external": {
"ecma262": "https://262.ecma-international.org/{section}",
"perl5": "https://perldoc.perl.org/perlre#{section}",
"rfc": "https://www.rfc-editor.org/rfc/rfc{spec}.html#section-{section}",
"iso": "https://www.iso.org/obp/ui"
}
}
{
"definitions": {
"integer": {
"type": "integer"
},
"refToInteger": {
"$ref": "#/definitions/integer"
}
}
}
{
"definitions": {
"refToInteger": {
"$ref": "#foo"
},
"A": {
"id": "#foo",
"type": "integer"
}
}
}
{
"definitions": {
"orNull": {
"anyOf": [
{
"type": "null"
},
{
"$ref": "#"
}
]
}
},
"type": "string"
}
{
"definitions": {
"integer": {
"type": "integer"
},
"refToInteger": {
"$ref": "#/definitions/integer"
}
}
}
{
"definitions": {
"refToInteger": {
"$ref": "#foo"
},
"A": {
"$id": "#foo",
"type": "integer"
}
}
}
{
"definitions": {
"orNull": {
"anyOf": [
{
"type": "null"
},
{
"$ref": "#"
}
]
}
},
"type": "string"
}
{
"$id": "http://localhost:1234/draft6/ref-and-definitions.json",
"definitions": {
"inner": {
"properties": {
"bar": { "type": "string" }
}
}
},
"allOf": [ { "$ref": "#/definitions/inner" } ]
}
{
"definitions": {
"integer": {
"type": "integer"
},
"refToInteger": {
"$ref": "#/definitions/integer"
}
}
}
{
"definitions": {
"refToInteger": {
"$ref": "#foo"
},
"A": {
"$id": "#foo",
"type": "integer"
}
}
}
{
"definitions": {
"orNull": {
"anyOf": [
{
"type": "null"
},
{
"$ref": "#"
}
]
}
},
"type": "string"
}
{
"$id": "http://localhost:1234/draft7/ref-and-definitions.json",
"definitions": {
"inner": {
"properties": {
"bar": { "type": "string" }
}
}
},
"allOf": [ { "$ref": "#/definitions/inner" } ]
}
{
"definitions": {
"integer": {
"type": "integer"
},
"refToInteger": {
"$ref": "#/definitions/integer"
}
}
}
[
{
"description": "\\a is not an ECMA 262 control escape",
"schema": {
"$schema": "https://json-schema.org/draft/next/schema",
"format": "regex"
},
"tests": [
{
"description": "when used as a pattern",
"data": "\\a",
"valid": false
}
]
}
]
[
{
"description": "\\a is not an ECMA 262 control escape",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"format": "regex"
},
"tests": [
{
"description": "when used as a pattern",
"data": "\\a",
"valid": false
}
]
}
]
[
{
"description": "ECMA 262 regex dialect recognition",
"schema": { "format": "regex" },
"tests": [
{
"description": "[^] is a valid regex",
"data": "[^]",
"valid": true
},
{
"description": "ECMA 262 has no support for lookbehind",
"data": "(?<=foo)bar",
"valid": false
}
]
}
]
version = 1
revision = 2
requires-python = ">=3.9"
[[package]]
name = "arrow"
version = "1.3.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "python-dateutil" },
{ name = "types-python-dateutil" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" },
]
[[package]]
name = "attrs"
version = "25.3.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" },
]
[[package]]
name = "fqdn"
version = "1.5.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" },
]
[[package]]
name = "idna"
version = "3.10"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
]
[[package]]
name = "isoduration"
version = "20.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "arrow" },
]
sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" },
]
[[package]]
name = "jsonpointer"
version = "3.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" },
]
[[package]]
name = "jsonschema"
source = { editable = "." }
dependencies = [
{ name = "attrs" },
{ name = "jsonschema-specifications" },
{ name = "referencing" },
{ name = "rpds-py" },
]
[package.optional-dependencies]
format = [
{ name = "fqdn" },
{ name = "idna" },
{ name = "isoduration" },
{ name = "jsonpointer" },
{ name = "rfc3339-validator" },
{ name = "rfc3987" },
{ name = "uri-template" },
{ name = "webcolors" },
]
format-nongpl = [
{ name = "fqdn" },
{ name = "idna" },
{ name = "isoduration" },
{ name = "jsonpointer" },
{ name = "rfc3339-validator" },
{ name = "rfc3986-validator" },
{ name = "uri-template" },
{ name = "webcolors" },
]
[package.metadata]
requires-dist = [
{ name = "attrs", specifier = ">=22.2.0" },
{ name = "fqdn", marker = "extra == 'format'" },
{ name = "fqdn", marker = "extra == 'format-nongpl'" },
{ name = "idna", marker = "extra == 'format'" },
{ name = "idna", marker = "extra == 'format-nongpl'" },
{ name = "importlib-resources", marker = "python_full_version < '3.9'", specifier = ">=1.4.0" },
{ name = "isoduration", marker = "extra == 'format'" },
{ name = "isoduration", marker = "extra == 'format-nongpl'" },
{ name = "jsonpointer", marker = "extra == 'format'", specifier = ">1.13" },
{ name = "jsonpointer", marker = "extra == 'format-nongpl'", specifier = ">1.13" },
{ name = "jsonschema-specifications", specifier = ">=2023.3.6" },
{ name = "pkgutil-resolve-name", marker = "python_full_version < '3.9'", specifier = ">=1.3.10" },
{ name = "referencing", specifier = ">=0.28.4" },
{ name = "rfc3339-validator", marker = "extra == 'format'" },
{ name = "rfc3339-validator", marker = "extra == 'format-nongpl'" },
{ name = "rfc3986-validator", marker = "extra == 'format-nongpl'", specifier = ">0.1.0" },
{ name = "rfc3987", marker = "extra == 'format'" },
{ name = "rpds-py", specifier = ">=0.7.1" },
{ name = "uri-template", marker = "extra == 'format'" },
{ name = "uri-template", marker = "extra == 'format-nongpl'" },
{ name = "webcolors", marker = "extra == 'format'", specifier = ">=1.11" },
{ name = "webcolors", marker = "extra == 'format-nongpl'", specifier = ">=24.6.0" },
]
provides-extras = ["format", "format-nongpl"]
[[package]]
name = "jsonschema-specifications"
version = "2025.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "referencing" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" },
]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
]
[[package]]
name = "referencing"
version = "0.36.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
{ name = "rpds-py" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
]
[[package]]
name = "rfc3339-validator"
version = "0.1.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "six" },
]
sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" },
]
[[package]]
name = "rfc3986-validator"
version = "0.1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" },
]
[[package]]
name = "rfc3987"
version = "1.3.8"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/14/bb/f1395c4b62f251a1cb503ff884500ebd248eed593f41b469f89caa3547bd/rfc3987-1.3.8.tar.gz", hash = "sha256:d3c4d257a560d544e9826b38bc81db676890c79ab9d7ac92b39c7a253d5ca733", size = 20700, upload-time = "2018-07-29T17:23:47.954Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/65/d4/f7407c3d15d5ac779c3dd34fbbc6ea2090f77bd7dd12f207ccf881551208/rfc3987-1.3.8-py2.py3-none-any.whl", hash = "sha256:10702b1e51e5658843460b189b185c0366d2cf4cff716f13111b0ea9fd2dce53", size = 13377, upload-time = "2018-07-29T17:23:45.313Z" },
]
[[package]]
name = "rpds-py"
version = "0.25.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304, upload-time = "2025-05-21T12:46:12.502Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cb/09/e1158988e50905b7f8306487a576b52d32aa9a87f79f7ab24ee8db8b6c05/rpds_py-0.25.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f4ad628b5174d5315761b67f212774a32f5bad5e61396d38108bd801c0a8f5d9", size = 373140, upload-time = "2025-05-21T12:42:38.834Z" },
{ url = "https://files.pythonhosted.org/packages/e0/4b/a284321fb3c45c02fc74187171504702b2934bfe16abab89713eedfe672e/rpds_py-0.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8c742af695f7525e559c16f1562cf2323db0e3f0fbdcabdf6865b095256b2d40", size = 358860, upload-time = "2025-05-21T12:42:41.394Z" },
{ url = "https://files.pythonhosted.org/packages/4e/46/8ac9811150c75edeae9fc6fa0e70376c19bc80f8e1f7716981433905912b/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:605ffe7769e24b1800b4d024d24034405d9404f0bc2f55b6db3362cd34145a6f", size = 386179, upload-time = "2025-05-21T12:42:43.213Z" },
{ url = "https://files.pythonhosted.org/packages/f3/ec/87eb42d83e859bce91dcf763eb9f2ab117142a49c9c3d17285440edb5b69/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc6f3ddef93243538be76f8e47045b4aad7a66a212cd3a0f23e34469473d36b", size = 400282, upload-time = "2025-05-21T12:42:44.92Z" },
{ url = "https://files.pythonhosted.org/packages/68/c8/2a38e0707d7919c8c78e1d582ab15cf1255b380bcb086ca265b73ed6db23/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f70316f760174ca04492b5ab01be631a8ae30cadab1d1081035136ba12738cfa", size = 521824, upload-time = "2025-05-21T12:42:46.856Z" },
{ url = "https://files.pythonhosted.org/packages/5e/2c/6a92790243569784dde84d144bfd12bd45102f4a1c897d76375076d730ab/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1dafef8df605fdb46edcc0bf1573dea0d6d7b01ba87f85cd04dc855b2b4479e", size = 411644, upload-time = "2025-05-21T12:42:48.838Z" },
{ url = "https://files.pythonhosted.org/packages/eb/76/66b523ffc84cf47db56efe13ae7cf368dee2bacdec9d89b9baca5e2e6301/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da", size = 386955, upload-time = "2025-05-21T12:42:50.835Z" },
{ url = "https://files.pythonhosted.org/packages/b6/b9/a362d7522feaa24dc2b79847c6175daa1c642817f4a19dcd5c91d3e2c316/rpds_py-0.25.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e87798852ae0b37c88babb7f7bbbb3e3fecc562a1c340195b44c7e24d403e380", size = 421039, upload-time = "2025-05-21T12:42:52.348Z" },
{ url = "https://files.pythonhosted.org/packages/0f/c4/b5b6f70b4d719b6584716889fd3413102acf9729540ee76708d56a76fa97/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3bcce0edc1488906c2d4c75c94c70a0417e83920dd4c88fec1078c94843a6ce9", size = 563290, upload-time = "2025-05-21T12:42:54.404Z" },
{ url = "https://files.pythonhosted.org/packages/87/a3/2e6e816615c12a8f8662c9d8583a12eb54c52557521ef218cbe3095a8afa/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e2f6a2347d3440ae789505693a02836383426249d5293541cd712e07e7aecf54", size = 592089, upload-time = "2025-05-21T12:42:55.976Z" },
{ url = "https://files.pythonhosted.org/packages/c0/08/9b8e1050e36ce266135994e2c7ec06e1841f1c64da739daeb8afe9cb77a4/rpds_py-0.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4fd52d3455a0aa997734f3835cbc4c9f32571345143960e7d7ebfe7b5fbfa3b2", size = 558400, upload-time = "2025-05-21T12:42:58.032Z" },
{ url = "https://files.pythonhosted.org/packages/f2/df/b40b8215560b8584baccd839ff5c1056f3c57120d79ac41bd26df196da7e/rpds_py-0.25.1-cp310-cp310-win32.whl", hash = "sha256:3f0b1798cae2bbbc9b9db44ee068c556d4737911ad53a4e5093d09d04b3bbc24", size = 219741, upload-time = "2025-05-21T12:42:59.479Z" },
{ url = "https://files.pythonhosted.org/packages/10/99/e4c58be18cf5d8b40b8acb4122bc895486230b08f978831b16a3916bd24d/rpds_py-0.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3ebd879ab996537fc510a2be58c59915b5dd63bccb06d1ef514fee787e05984a", size = 231553, upload-time = "2025-05-21T12:43:01.425Z" },
{ url = "https://files.pythonhosted.org/packages/95/e1/df13fe3ddbbea43567e07437f097863b20c99318ae1f58a0fe389f763738/rpds_py-0.25.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5f048bbf18b1f9120685c6d6bb70cc1a52c8cc11bdd04e643d28d3be0baf666d", size = 373341, upload-time = "2025-05-21T12:43:02.978Z" },
{ url = "https://files.pythonhosted.org/packages/7a/58/deef4d30fcbcbfef3b6d82d17c64490d5c94585a2310544ce8e2d3024f83/rpds_py-0.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fbb0dbba559959fcb5d0735a0f87cdbca9e95dac87982e9b95c0f8f7ad10255", size = 359111, upload-time = "2025-05-21T12:43:05.128Z" },
{ url = "https://files.pythonhosted.org/packages/bb/7e/39f1f4431b03e96ebaf159e29a0f82a77259d8f38b2dd474721eb3a8ac9b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4ca54b9cf9d80b4016a67a0193ebe0bcf29f6b0a96f09db942087e294d3d4c2", size = 386112, upload-time = "2025-05-21T12:43:07.13Z" },
{ url = "https://files.pythonhosted.org/packages/db/e7/847068a48d63aec2ae695a1646089620b3b03f8ccf9f02c122ebaf778f3c/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ee3e26eb83d39b886d2cb6e06ea701bba82ef30a0de044d34626ede51ec98b0", size = 400362, upload-time = "2025-05-21T12:43:08.693Z" },
{ url = "https://files.pythonhosted.org/packages/3b/3d/9441d5db4343d0cee759a7ab4d67420a476cebb032081763de934719727b/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89706d0683c73a26f76a5315d893c051324d771196ae8b13e6ffa1ffaf5e574f", size = 522214, upload-time = "2025-05-21T12:43:10.694Z" },
{ url = "https://files.pythonhosted.org/packages/a2/ec/2cc5b30d95f9f1a432c79c7a2f65d85e52812a8f6cbf8768724571710786/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2013ee878c76269c7b557a9a9c042335d732e89d482606990b70a839635feb7", size = 411491, upload-time = "2025-05-21T12:43:12.739Z" },
{ url = "https://files.pythonhosted.org/packages/dc/6c/44695c1f035077a017dd472b6a3253553780837af2fac9b6ac25f6a5cb4d/rpds_py-0.25.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45e484db65e5380804afbec784522de84fa95e6bb92ef1bd3325d33d13efaebd", size = 386978, upload-time = "2025-05-21T12:43:14.25Z" },
{ url = "https://files.pythonhosted.org/packages/b1/74/b4357090bb1096db5392157b4e7ed8bb2417dc7799200fcbaee633a032c9/rpds_py-0.25.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:48d64155d02127c249695abb87d39f0faf410733428d499867606be138161d65", size = 420662, upload-time = "2025-05-21T12:43:15.8Z" },
{ url = "https://files.pythonhosted.org/packages/26/dd/8cadbebf47b96e59dfe8b35868e5c38a42272699324e95ed522da09d3a40/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:048893e902132fd6548a2e661fb38bf4896a89eea95ac5816cf443524a85556f", size = 563385, upload-time = "2025-05-21T12:43:17.78Z" },
{ url = "https://files.pythonhosted.org/packages/c3/ea/92960bb7f0e7a57a5ab233662f12152085c7dc0d5468534c65991a3d48c9/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0317177b1e8691ab5879f4f33f4b6dc55ad3b344399e23df2e499de7b10a548d", size = 592047, upload-time = "2025-05-21T12:43:19.457Z" },
{ url = "https://files.pythonhosted.org/packages/61/ad/71aabc93df0d05dabcb4b0c749277881f8e74548582d96aa1bf24379493a/rpds_py-0.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bffcf57826d77a4151962bf1701374e0fc87f536e56ec46f1abdd6a903354042", size = 557863, upload-time = "2025-05-21T12:43:21.69Z" },
{ url = "https://files.pythonhosted.org/packages/93/0f/89df0067c41f122b90b76f3660028a466eb287cbe38efec3ea70e637ca78/rpds_py-0.25.1-cp311-cp311-win32.whl", hash = "sha256:cda776f1967cb304816173b30994faaf2fd5bcb37e73118a47964a02c348e1bc", size = 219627, upload-time = "2025-05-21T12:43:23.311Z" },
{ url = "https://files.pythonhosted.org/packages/7c/8d/93b1a4c1baa903d0229374d9e7aa3466d751f1d65e268c52e6039c6e338e/rpds_py-0.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:dc3c1ff0abc91444cd20ec643d0f805df9a3661fcacf9c95000329f3ddf268a4", size = 231603, upload-time = "2025-05-21T12:43:25.145Z" },
{ url = "https://files.pythonhosted.org/packages/cb/11/392605e5247bead2f23e6888e77229fbd714ac241ebbebb39a1e822c8815/rpds_py-0.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:5a3ddb74b0985c4387719fc536faced33cadf2172769540c62e2a94b7b9be1c4", size = 223967, upload-time = "2025-05-21T12:43:26.566Z" },
{ url = "https://files.pythonhosted.org/packages/7f/81/28ab0408391b1dc57393653b6a0cf2014cc282cc2909e4615e63e58262be/rpds_py-0.25.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b5ffe453cde61f73fea9430223c81d29e2fbf412a6073951102146c84e19e34c", size = 364647, upload-time = "2025-05-21T12:43:28.559Z" },
{ url = "https://files.pythonhosted.org/packages/2c/9a/7797f04cad0d5e56310e1238434f71fc6939d0bc517192a18bb99a72a95f/rpds_py-0.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:115874ae5e2fdcfc16b2aedc95b5eef4aebe91b28e7e21951eda8a5dc0d3461b", size = 350454, upload-time = "2025-05-21T12:43:30.615Z" },
{ url = "https://files.pythonhosted.org/packages/69/3c/93d2ef941b04898011e5d6eaa56a1acf46a3b4c9f4b3ad1bbcbafa0bee1f/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a714bf6e5e81b0e570d01f56e0c89c6375101b8463999ead3a93a5d2a4af91fa", size = 389665, upload-time = "2025-05-21T12:43:32.629Z" },
{ url = "https://files.pythonhosted.org/packages/c1/57/ad0e31e928751dde8903a11102559628d24173428a0f85e25e187defb2c1/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35634369325906bcd01577da4c19e3b9541a15e99f31e91a02d010816b49bfda", size = 403873, upload-time = "2025-05-21T12:43:34.576Z" },
{ url = "https://files.pythonhosted.org/packages/16/ad/c0c652fa9bba778b4f54980a02962748479dc09632e1fd34e5282cf2556c/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4cb2b3ddc16710548801c6fcc0cfcdeeff9dafbc983f77265877793f2660309", size = 525866, upload-time = "2025-05-21T12:43:36.123Z" },
{ url = "https://files.pythonhosted.org/packages/2a/39/3e1839bc527e6fcf48d5fec4770070f872cdee6c6fbc9b259932f4e88a38/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9ceca1cf097ed77e1a51f1dbc8d174d10cb5931c188a4505ff9f3e119dfe519b", size = 416886, upload-time = "2025-05-21T12:43:38.034Z" },
{ url = "https://files.pythonhosted.org/packages/7a/95/dd6b91cd4560da41df9d7030a038298a67d24f8ca38e150562644c829c48/rpds_py-0.25.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2cd1a4b0c2b8c5e31ffff50d09f39906fe351389ba143c195566056c13a7ea", size = 390666, upload-time = "2025-05-21T12:43:40.065Z" },
{ url = "https://files.pythonhosted.org/packages/64/48/1be88a820e7494ce0a15c2d390ccb7c52212370badabf128e6a7bb4cb802/rpds_py-0.25.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1de336a4b164c9188cb23f3703adb74a7623ab32d20090d0e9bf499a2203ad65", size = 425109, upload-time = "2025-05-21T12:43:42.263Z" },
{ url = "https://files.pythonhosted.org/packages/cf/07/3e2a17927ef6d7720b9949ec1b37d1e963b829ad0387f7af18d923d5cfa5/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9fca84a15333e925dd59ce01da0ffe2ffe0d6e5d29a9eeba2148916d1824948c", size = 567244, upload-time = "2025-05-21T12:43:43.846Z" },
{ url = "https://files.pythonhosted.org/packages/d2/e5/76cf010998deccc4f95305d827847e2eae9c568099c06b405cf96384762b/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88ec04afe0c59fa64e2f6ea0dd9657e04fc83e38de90f6de201954b4d4eb59bd", size = 596023, upload-time = "2025-05-21T12:43:45.932Z" },
{ url = "https://files.pythonhosted.org/packages/52/9a/df55efd84403736ba37a5a6377b70aad0fd1cb469a9109ee8a1e21299a1c/rpds_py-0.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8bd2f19e312ce3e1d2c635618e8a8d8132892bb746a7cf74780a489f0f6cdcb", size = 561634, upload-time = "2025-05-21T12:43:48.263Z" },
{ url = "https://files.pythonhosted.org/packages/ab/aa/dc3620dd8db84454aaf9374bd318f1aa02578bba5e567f5bf6b79492aca4/rpds_py-0.25.1-cp312-cp312-win32.whl", hash = "sha256:e5e2f7280d8d0d3ef06f3ec1b4fd598d386cc6f0721e54f09109a8132182fbfe", size = 222713, upload-time = "2025-05-21T12:43:49.897Z" },
{ url = "https://files.pythonhosted.org/packages/a3/7f/7cef485269a50ed5b4e9bae145f512d2a111ca638ae70cc101f661b4defd/rpds_py-0.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:db58483f71c5db67d643857404da360dce3573031586034b7d59f245144cc192", size = 235280, upload-time = "2025-05-21T12:43:51.893Z" },
{ url = "https://files.pythonhosted.org/packages/99/f2/c2d64f6564f32af913bf5f3f7ae41c7c263c5ae4c4e8f1a17af8af66cd46/rpds_py-0.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:6d50841c425d16faf3206ddbba44c21aa3310a0cebc3c1cdfc3e3f4f9f6f5728", size = 225399, upload-time = "2025-05-21T12:43:53.351Z" },
{ url = "https://files.pythonhosted.org/packages/2b/da/323848a2b62abe6a0fec16ebe199dc6889c5d0a332458da8985b2980dffe/rpds_py-0.25.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559", size = 364498, upload-time = "2025-05-21T12:43:54.841Z" },
{ url = "https://files.pythonhosted.org/packages/1f/b4/4d3820f731c80fd0cd823b3e95b9963fec681ae45ba35b5281a42382c67d/rpds_py-0.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1", size = 350083, upload-time = "2025-05-21T12:43:56.428Z" },
{ url = "https://files.pythonhosted.org/packages/d5/b1/3a8ee1c9d480e8493619a437dec685d005f706b69253286f50f498cbdbcf/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c", size = 389023, upload-time = "2025-05-21T12:43:57.995Z" },
{ url = "https://files.pythonhosted.org/packages/3b/31/17293edcfc934dc62c3bf74a0cb449ecd549531f956b72287203e6880b87/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb", size = 403283, upload-time = "2025-05-21T12:43:59.546Z" },
{ url = "https://files.pythonhosted.org/packages/d1/ca/e0f0bc1a75a8925024f343258c8ecbd8828f8997ea2ac71e02f67b6f5299/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40", size = 524634, upload-time = "2025-05-21T12:44:01.087Z" },
{ url = "https://files.pythonhosted.org/packages/3e/03/5d0be919037178fff33a6672ffc0afa04ea1cfcb61afd4119d1b5280ff0f/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79", size = 416233, upload-time = "2025-05-21T12:44:02.604Z" },
{ url = "https://files.pythonhosted.org/packages/05/7c/8abb70f9017a231c6c961a8941403ed6557664c0913e1bf413cbdc039e75/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325", size = 390375, upload-time = "2025-05-21T12:44:04.162Z" },
{ url = "https://files.pythonhosted.org/packages/7a/ac/a87f339f0e066b9535074a9f403b9313fd3892d4a164d5d5f5875ac9f29f/rpds_py-0.25.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295", size = 424537, upload-time = "2025-05-21T12:44:06.175Z" },
{ url = "https://files.pythonhosted.org/packages/1f/8f/8d5c1567eaf8c8afe98a838dd24de5013ce6e8f53a01bd47fe8bb06b5533/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b", size = 566425, upload-time = "2025-05-21T12:44:08.242Z" },
{ url = "https://files.pythonhosted.org/packages/95/33/03016a6be5663b389c8ab0bbbcca68d9e96af14faeff0a04affcb587e776/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98", size = 595197, upload-time = "2025-05-21T12:44:10.449Z" },
{ url = "https://files.pythonhosted.org/packages/33/8d/da9f4d3e208c82fda311bff0cf0a19579afceb77cf456e46c559a1c075ba/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd", size = 561244, upload-time = "2025-05-21T12:44:12.387Z" },
{ url = "https://files.pythonhosted.org/packages/e2/b3/39d5dcf7c5f742ecd6dbc88f6f84ae54184b92f5f387a4053be2107b17f1/rpds_py-0.25.1-cp313-cp313-win32.whl", hash = "sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31", size = 222254, upload-time = "2025-05-21T12:44:14.261Z" },
{ url = "https://files.pythonhosted.org/packages/5f/19/2d6772c8eeb8302c5f834e6d0dfd83935a884e7c5ce16340c7eaf89ce925/rpds_py-0.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500", size = 234741, upload-time = "2025-05-21T12:44:16.236Z" },
{ url = "https://files.pythonhosted.org/packages/5b/5a/145ada26cfaf86018d0eb304fe55eafdd4f0b6b84530246bb4a7c4fb5c4b/rpds_py-0.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5", size = 224830, upload-time = "2025-05-21T12:44:17.749Z" },
{ url = "https://files.pythonhosted.org/packages/4b/ca/d435844829c384fd2c22754ff65889c5c556a675d2ed9eb0e148435c6690/rpds_py-0.25.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129", size = 359668, upload-time = "2025-05-21T12:44:19.322Z" },
{ url = "https://files.pythonhosted.org/packages/1f/01/b056f21db3a09f89410d493d2f6614d87bb162499f98b649d1dbd2a81988/rpds_py-0.25.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d", size = 345649, upload-time = "2025-05-21T12:44:20.962Z" },
{ url = "https://files.pythonhosted.org/packages/e0/0f/e0d00dc991e3d40e03ca36383b44995126c36b3eafa0ccbbd19664709c88/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72", size = 384776, upload-time = "2025-05-21T12:44:22.516Z" },
{ url = "https://files.pythonhosted.org/packages/9f/a2/59374837f105f2ca79bde3c3cd1065b2f8c01678900924949f6392eab66d/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34", size = 395131, upload-time = "2025-05-21T12:44:24.147Z" },
{ url = "https://files.pythonhosted.org/packages/9c/dc/48e8d84887627a0fe0bac53f0b4631e90976fd5d35fff8be66b8e4f3916b/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9", size = 520942, upload-time = "2025-05-21T12:44:25.915Z" },
{ url = "https://files.pythonhosted.org/packages/7c/f5/ee056966aeae401913d37befeeab57a4a43a4f00099e0a20297f17b8f00c/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5", size = 411330, upload-time = "2025-05-21T12:44:27.638Z" },
{ url = "https://files.pythonhosted.org/packages/ab/74/b2cffb46a097cefe5d17f94ede7a174184b9d158a0aeb195f39f2c0361e8/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194", size = 387339, upload-time = "2025-05-21T12:44:29.292Z" },
{ url = "https://files.pythonhosted.org/packages/7f/9a/0ff0b375dcb5161c2b7054e7d0b7575f1680127505945f5cabaac890bc07/rpds_py-0.25.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6", size = 418077, upload-time = "2025-05-21T12:44:30.877Z" },
{ url = "https://files.pythonhosted.org/packages/0d/a1/fda629bf20d6b698ae84c7c840cfb0e9e4200f664fc96e1f456f00e4ad6e/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78", size = 562441, upload-time = "2025-05-21T12:44:32.541Z" },
{ url = "https://files.pythonhosted.org/packages/20/15/ce4b5257f654132f326f4acd87268e1006cc071e2c59794c5bdf4bebbb51/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72", size = 590750, upload-time = "2025-05-21T12:44:34.557Z" },
{ url = "https://files.pythonhosted.org/packages/fb/ab/e04bf58a8d375aeedb5268edcc835c6a660ebf79d4384d8e0889439448b0/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66", size = 558891, upload-time = "2025-05-21T12:44:37.358Z" },
{ url = "https://files.pythonhosted.org/packages/90/82/cb8c6028a6ef6cd2b7991e2e4ced01c854b6236ecf51e81b64b569c43d73/rpds_py-0.25.1-cp313-cp313t-win32.whl", hash = "sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523", size = 218718, upload-time = "2025-05-21T12:44:38.969Z" },
{ url = "https://files.pythonhosted.org/packages/b6/97/5a4b59697111c89477d20ba8a44df9ca16b41e737fa569d5ae8bff99e650/rpds_py-0.25.1-cp313-cp313t-win_amd64.whl", hash = "sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763", size = 232218, upload-time = "2025-05-21T12:44:40.512Z" },
{ url = "https://files.pythonhosted.org/packages/89/74/716d42058ef501e2c08f27aa3ff455f6fc1bbbd19a6ab8dea07e6322d217/rpds_py-0.25.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ce4c8e485a3c59593f1a6f683cf0ea5ab1c1dc94d11eea5619e4fb5228b40fbd", size = 373475, upload-time = "2025-05-21T12:44:42.136Z" },
{ url = "https://files.pythonhosted.org/packages/e1/21/3faa9c523e2496a2505d7440b6f24c9166f37cb7ac027cac6cfbda9b4b5f/rpds_py-0.25.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8222acdb51a22929c3b2ddb236b69c59c72af4019d2cba961e2f9add9b6e634", size = 359349, upload-time = "2025-05-21T12:44:43.813Z" },
{ url = "https://files.pythonhosted.org/packages/6a/1c/c747fe568d21b1d679079b52b926ebc4d1497457510a1773dc5fd4b7b4e2/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4593c4eae9b27d22df41cde518b4b9e4464d139e4322e2127daa9b5b981b76be", size = 386526, upload-time = "2025-05-21T12:44:45.452Z" },
{ url = "https://files.pythonhosted.org/packages/0b/cc/4a41703de4fb291f13660fa3d882cbd39db5d60497c6e7fa7f5142e5e69f/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd035756830c712b64725a76327ce80e82ed12ebab361d3a1cdc0f51ea21acb0", size = 400526, upload-time = "2025-05-21T12:44:47.011Z" },
{ url = "https://files.pythonhosted.org/packages/f1/78/60c980bedcad8418b614f0b4d6d420ecf11225b579cec0cb4e84d168b4da/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:114a07e85f32b125404f28f2ed0ba431685151c037a26032b213c882f26eb908", size = 525726, upload-time = "2025-05-21T12:44:48.838Z" },
{ url = "https://files.pythonhosted.org/packages/3f/37/f2f36b7f1314b3c3200d663decf2f8e29480492a39ab22447112aead4693/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dec21e02e6cc932538b5203d3a8bd6aa1480c98c4914cb88eea064ecdbc6396a", size = 412045, upload-time = "2025-05-21T12:44:50.433Z" },
{ url = "https://files.pythonhosted.org/packages/df/96/e03783e87a775b1242477ccbc35895f8e9b2bbdb60e199034a6da03c2687/rpds_py-0.25.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09eab132f41bf792c7a0ea1578e55df3f3e7f61888e340779b06050a9a3f16e9", size = 386953, upload-time = "2025-05-21T12:44:52.092Z" },
{ url = "https://files.pythonhosted.org/packages/7c/7d/1418f4b69bfb4b40481a3d84782113ad7d4cca0b38ae70b982dd5b20102a/rpds_py-0.25.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c98f126c4fc697b84c423e387337d5b07e4a61e9feac494362a59fd7a2d9ed80", size = 421144, upload-time = "2025-05-21T12:44:53.734Z" },
{ url = "https://files.pythonhosted.org/packages/b3/0e/61469912c6493ee3808012e60f4930344b974fcb6b35c4348e70b6be7bc7/rpds_py-0.25.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0e6a327af8ebf6baba1c10fadd04964c1965d375d318f4435d5f3f9651550f4a", size = 563730, upload-time = "2025-05-21T12:44:55.846Z" },
{ url = "https://files.pythonhosted.org/packages/f6/86/6d0a5cc56481ac61977b7c839677ed5c63d38cf0fcb3e2280843a8a6f476/rpds_py-0.25.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bc120d1132cff853ff617754196d0ac0ae63befe7c8498bd67731ba368abe451", size = 592321, upload-time = "2025-05-21T12:44:57.514Z" },
{ url = "https://files.pythonhosted.org/packages/5d/87/d1e2453fe336f71e6aa296452a8c85c2118b587b1d25ce98014f75838a60/rpds_py-0.25.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:140f61d9bed7839446bdd44852e30195c8e520f81329b4201ceead4d64eb3a9f", size = 558162, upload-time = "2025-05-21T12:44:59.564Z" },
{ url = "https://files.pythonhosted.org/packages/ad/92/349f04b1644c5cef3e2e6c53b7168a28531945f9e6fca7425f6d20ddbc3c/rpds_py-0.25.1-cp39-cp39-win32.whl", hash = "sha256:9c006f3aadeda131b438c3092124bd196b66312f0caa5823ef09585a669cf449", size = 219920, upload-time = "2025-05-21T12:45:01.186Z" },
{ url = "https://files.pythonhosted.org/packages/f2/84/3969bef883a3f37ff2213795257cb7b7e93a115829670befb8de0e003031/rpds_py-0.25.1-cp39-cp39-win_amd64.whl", hash = "sha256:a61d0b2c7c9a0ae45732a77844917b427ff16ad5464b4d4f5e4adb955f582890", size = 231452, upload-time = "2025-05-21T12:45:02.85Z" },
{ url = "https://files.pythonhosted.org/packages/78/ff/566ce53529b12b4f10c0a348d316bd766970b7060b4fd50f888be3b3b281/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b24bf3cd93d5b6ecfbedec73b15f143596c88ee249fa98cefa9a9dc9d92c6f28", size = 373931, upload-time = "2025-05-21T12:45:05.01Z" },
{ url = "https://files.pythonhosted.org/packages/83/5d/deba18503f7c7878e26aa696e97f051175788e19d5336b3b0e76d3ef9256/rpds_py-0.25.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:0eb90e94f43e5085623932b68840b6f379f26db7b5c2e6bcef3179bd83c9330f", size = 359074, upload-time = "2025-05-21T12:45:06.714Z" },
{ url = "https://files.pythonhosted.org/packages/0d/74/313415c5627644eb114df49c56a27edba4d40cfd7c92bd90212b3604ca84/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d50e4864498a9ab639d6d8854b25e80642bd362ff104312d9770b05d66e5fb13", size = 387255, upload-time = "2025-05-21T12:45:08.669Z" },
{ url = "https://files.pythonhosted.org/packages/8c/c8/c723298ed6338963d94e05c0f12793acc9b91d04ed7c4ba7508e534b7385/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c9409b47ba0650544b0bb3c188243b83654dfe55dcc173a86832314e1a6a35d", size = 400714, upload-time = "2025-05-21T12:45:10.39Z" },
{ url = "https://files.pythonhosted.org/packages/33/8a/51f1f6aa653c2e110ed482ef2ae94140d56c910378752a1b483af11019ee/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:796ad874c89127c91970652a4ee8b00d56368b7e00d3477f4415fe78164c8000", size = 523105, upload-time = "2025-05-21T12:45:12.273Z" },
{ url = "https://files.pythonhosted.org/packages/c7/a4/7873d15c088ad3bff36910b29ceb0f178e4b3232c2adbe9198de68a41e63/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85608eb70a659bf4c1142b2781083d4b7c0c4e2c90eff11856a9754e965b2540", size = 411499, upload-time = "2025-05-21T12:45:13.95Z" },
{ url = "https://files.pythonhosted.org/packages/90/f3/0ce1437befe1410766d11d08239333ac1b2d940f8a64234ce48a7714669c/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4feb9211d15d9160bc85fa72fed46432cdc143eb9cf6d5ca377335a921ac37b", size = 387918, upload-time = "2025-05-21T12:45:15.649Z" },
{ url = "https://files.pythonhosted.org/packages/94/d4/5551247988b2a3566afb8a9dba3f1d4a3eea47793fd83000276c1a6c726e/rpds_py-0.25.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ccfa689b9246c48947d31dd9d8b16d89a0ecc8e0e26ea5253068efb6c542b76e", size = 421705, upload-time = "2025-05-21T12:45:17.788Z" },
{ url = "https://files.pythonhosted.org/packages/b0/25/5960f28f847bf736cc7ee3c545a7e1d2f3b5edaf82c96fb616c2f5ed52d0/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:3c5b317ecbd8226887994852e85de562f7177add602514d4ac40f87de3ae45a8", size = 564489, upload-time = "2025-05-21T12:45:19.466Z" },
{ url = "https://files.pythonhosted.org/packages/02/66/1c99884a0d44e8c2904d3c4ec302f995292d5dde892c3bf7685ac1930146/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:454601988aab2c6e8fd49e7634c65476b2b919647626208e376afcd22019eeb8", size = 592557, upload-time = "2025-05-21T12:45:21.362Z" },
{ url = "https://files.pythonhosted.org/packages/55/ae/4aeac84ebeffeac14abb05b3bb1d2f728d00adb55d3fb7b51c9fa772e760/rpds_py-0.25.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:1c0c434a53714358532d13539272db75a5ed9df75a4a090a753ac7173ec14e11", size = 558691, upload-time = "2025-05-21T12:45:23.084Z" },
{ url = "https://files.pythonhosted.org/packages/41/b3/728a08ff6f5e06fe3bb9af2e770e9d5fd20141af45cff8dfc62da4b2d0b3/rpds_py-0.25.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f73ce1512e04fbe2bc97836e89830d6b4314c171587a99688082d090f934d20a", size = 231651, upload-time = "2025-05-21T12:45:24.72Z" },
{ url = "https://files.pythonhosted.org/packages/49/74/48f3df0715a585cbf5d34919c9c757a4c92c1a9eba059f2d334e72471f70/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ee86d81551ec68a5c25373c5643d343150cc54672b5e9a0cafc93c1870a53954", size = 374208, upload-time = "2025-05-21T12:45:26.306Z" },
{ url = "https://files.pythonhosted.org/packages/55/b0/9b01bb11ce01ec03d05e627249cc2c06039d6aa24ea5a22a39c312167c10/rpds_py-0.25.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:89c24300cd4a8e4a51e55c31a8ff3918e6651b241ee8876a42cc2b2a078533ba", size = 359262, upload-time = "2025-05-21T12:45:28.322Z" },
{ url = "https://files.pythonhosted.org/packages/a9/eb/5395621618f723ebd5116c53282052943a726dba111b49cd2071f785b665/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:771c16060ff4e79584dc48902a91ba79fd93eade3aa3a12d6d2a4aadaf7d542b", size = 387366, upload-time = "2025-05-21T12:45:30.42Z" },
{ url = "https://files.pythonhosted.org/packages/68/73/3d51442bdb246db619d75039a50ea1cf8b5b4ee250c3e5cd5c3af5981cd4/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:785ffacd0ee61c3e60bdfde93baa6d7c10d86f15655bd706c89da08068dc5038", size = 400759, upload-time = "2025-05-21T12:45:32.516Z" },
{ url = "https://files.pythonhosted.org/packages/b7/4c/3a32d5955d7e6cb117314597bc0f2224efc798428318b13073efe306512a/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a40046a529cc15cef88ac5ab589f83f739e2d332cb4d7399072242400ed68c9", size = 523128, upload-time = "2025-05-21T12:45:34.396Z" },
{ url = "https://files.pythonhosted.org/packages/be/95/1ffccd3b0bb901ae60b1dd4b1be2ab98bb4eb834cd9b15199888f5702f7b/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:85fc223d9c76cabe5d0bff82214459189720dc135db45f9f66aa7cffbf9ff6c1", size = 411597, upload-time = "2025-05-21T12:45:36.164Z" },
{ url = "https://files.pythonhosted.org/packages/ef/6d/6e6cd310180689db8b0d2de7f7d1eabf3fb013f239e156ae0d5a1a85c27f/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0be9965f93c222fb9b4cc254235b3b2b215796c03ef5ee64f995b1b69af0762", size = 388053, upload-time = "2025-05-21T12:45:38.45Z" },
{ url = "https://files.pythonhosted.org/packages/4a/87/ec4186b1fe6365ced6fa470960e68fc7804bafbe7c0cf5a36237aa240efa/rpds_py-0.25.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8378fa4a940f3fb509c081e06cb7f7f2adae8cf46ef258b0e0ed7519facd573e", size = 421821, upload-time = "2025-05-21T12:45:40.732Z" },
{ url = "https://files.pythonhosted.org/packages/7a/60/84f821f6bf4e0e710acc5039d91f8f594fae0d93fc368704920d8971680d/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:33358883a4490287e67a2c391dfaea4d9359860281db3292b6886bf0be3d8692", size = 564534, upload-time = "2025-05-21T12:45:42.672Z" },
{ url = "https://files.pythonhosted.org/packages/41/3a/bc654eb15d3b38f9330fe0f545016ba154d89cdabc6177b0295910cd0ebe/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1d1fadd539298e70cac2f2cb36f5b8a65f742b9b9f1014dd4ea1f7785e2470bf", size = 592674, upload-time = "2025-05-21T12:45:44.533Z" },
{ url = "https://files.pythonhosted.org/packages/2e/ba/31239736f29e4dfc7a58a45955c5db852864c306131fd6320aea214d5437/rpds_py-0.25.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9a46c2fb2545e21181445515960006e85d22025bd2fe6db23e76daec6eb689fe", size = 558781, upload-time = "2025-05-21T12:45:46.281Z" },
{ url = "https://files.pythonhosted.org/packages/78/b2/198266f070c6760e0e8cd00f9f2b9c86133ceebbe7c6d114bdcfea200180/rpds_py-0.25.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:50f2c501a89c9a5f4e454b126193c5495b9fb441a75b298c60591d8a2eb92e1b", size = 373973, upload-time = "2025-05-21T12:45:48.081Z" },
{ url = "https://files.pythonhosted.org/packages/13/79/1265eae618f88aa5d5e7122bd32dd41700bafe5a8bcea404e998848cd844/rpds_py-0.25.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d779b325cc8238227c47fbc53964c8cc9a941d5dbae87aa007a1f08f2f77b23", size = 359326, upload-time = "2025-05-21T12:45:49.825Z" },
{ url = "https://files.pythonhosted.org/packages/30/ab/6913b96f3ac072e87e76e45fe938263b0ab0d78b6b2cef3f2e56067befc0/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:036ded36bedb727beeabc16dc1dad7cb154b3fa444e936a03b67a86dc6a5066e", size = 387544, upload-time = "2025-05-21T12:45:51.764Z" },
{ url = "https://files.pythonhosted.org/packages/b0/23/129ed12d25229acc6deb8cbe90baadd8762e563c267c9594eb2fcc15be0c/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:245550f5a1ac98504147cba96ffec8fabc22b610742e9150138e5d60774686d7", size = 400240, upload-time = "2025-05-21T12:45:54.061Z" },
{ url = "https://files.pythonhosted.org/packages/b5/e0/6811a38a5efa46b7ee6ed2103c95cb9abb16991544c3b69007aa679b6944/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff7c23ba0a88cb7b104281a99476cccadf29de2a0ef5ce864959a52675b1ca83", size = 525599, upload-time = "2025-05-21T12:45:56.457Z" },
{ url = "https://files.pythonhosted.org/packages/6c/10/2dc88bcaa0d86bdb59e017a330b1972ffeeb7f5061bb5a180c9a2bb73bbf/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e37caa8cdb3b7cf24786451a0bdb853f6347b8b92005eeb64225ae1db54d1c2b", size = 411154, upload-time = "2025-05-21T12:45:58.525Z" },
{ url = "https://files.pythonhosted.org/packages/cf/d1/a72d522eb7d934fb33e9c501e6ecae00e2035af924d4ff37d964e9a3959b/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2f48ab00181600ee266a095fe815134eb456163f7d6699f525dee471f312cf", size = 388297, upload-time = "2025-05-21T12:46:00.264Z" },
{ url = "https://files.pythonhosted.org/packages/55/90/0dd7169ec74f042405b6b73512200d637a3088c156f64e1c07c18aa2fe59/rpds_py-0.25.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e5fc7484fa7dce57e25063b0ec9638ff02a908304f861d81ea49273e43838c1", size = 421894, upload-time = "2025-05-21T12:46:02.065Z" },
{ url = "https://files.pythonhosted.org/packages/37/e9/45170894add451783ed839c5c4a495e050aa8baa06d720364d9dff394dac/rpds_py-0.25.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:d3c10228d6cf6fe2b63d2e7985e94f6916fa46940df46b70449e9ff9297bd3d1", size = 564409, upload-time = "2025-05-21T12:46:03.891Z" },
{ url = "https://files.pythonhosted.org/packages/59/d0/31cece9090e76fbdb50c758c165d40da604b03b37c3ba53f010bbfeb130a/rpds_py-0.25.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:5d9e40f32745db28c1ef7aad23f6fc458dc1e29945bd6781060f0d15628b8ddf", size = 592681, upload-time = "2025-05-21T12:46:06.009Z" },
{ url = "https://files.pythonhosted.org/packages/f1/4c/22ef535efb2beec614ba7be83e62b439eb83b0b0d7b1775e22d35af3f9b5/rpds_py-0.25.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:35a8d1a24b5936b35c5003313bc177403d8bdef0f8b24f28b1c4a255f94ea992", size = 558744, upload-time = "2025-05-21T12:46:07.78Z" },
{ url = "https://files.pythonhosted.org/packages/79/ff/f2150efc8daf0581d4dfaf0a2a30b08088b6df900230ee5ae4f7c8cd5163/rpds_py-0.25.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:6099263f526efff9cf3883dfef505518730f7a7a93049b1d90d42e50a22b4793", size = 231305, upload-time = "2025-05-21T12:46:10.52Z" },
]
[[package]]
name = "six"
version = "1.17.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
]
[[package]]
name = "types-python-dateutil"
version = "2.9.0.20250516"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/ef/88/d65ed807393285204ab6e2801e5d11fbbea811adcaa979a2ed3b67a5ef41/types_python_dateutil-2.9.0.20250516.tar.gz", hash = "sha256:13e80d6c9c47df23ad773d54b2826bd52dbbb41be87c3f339381c1700ad21ee5", size = 13943, upload-time = "2025-05-16T03:06:58.385Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c5/3f/b0e8db149896005adc938a1e7f371d6d7e9eca4053a29b108978ed15e0c2/types_python_dateutil-2.9.0.20250516-py3-none-any.whl", hash = "sha256:2b2b3f57f9c6a61fba26a9c0ffb9ea5681c9b83e69cd897c6b5f668d9c0cab93", size = 14356, upload-time = "2025-05-16T03:06:57.249Z" },
]
[[package]]
name = "typing-extensions"
version = "4.13.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" },
]
[[package]]
name = "uri-template"
version = "1.3.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" },
]
[[package]]
name = "webcolors"
version = "24.11.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" },
]
+45
-34

@@ -10,4 +10,2 @@ name: CI

pull_request:
release:
types: [published]
schedule:

@@ -18,16 +16,5 @@ # Daily at 3:21

env:
PIP_DISABLE_PIP_VERSION_CHECK: "1"
PIP_NO_PYTHON_VERSION_WARNING: "1"
permissions: {}
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- uses: pre-commit/action@v3.0.1
list:

@@ -39,8 +26,12 @@ runs-on: ubuntu-latest

- uses: actions/checkout@v4
- name: Set up nox
uses: wntrblm/nox@2024.04.15
with:
persist-credentials: false
- name: Set up uv
uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb
with:
enable-cache: ${{ github.ref_type != 'tag' }} # zizmor: ignore[cache-poisoning]
- id: noxenvs-matrix
run: |
echo >>$GITHUB_OUTPUT noxenvs=$(
nox --list-sessions --json | jq '[.[].session]'
uvx nox --list-sessions --json | jq '[.[].session]'
)

@@ -51,2 +42,3 @@

runs-on: ${{ matrix.os }}
strategy:

@@ -60,8 +52,20 @@ fail-fast: false

- os: ubuntu-latest
noxenv: "tests-3.11(format)"
noxenv: "tests-3.13(format)"
posargs: coverage github
- os: ubuntu-latest
noxenv: "tests-3.11(no-extras)"
noxenv: "tests-3.13(no-extras)"
posargs: coverage github
exclude:
- os: macos-latest
noxenv: "docs(dirhtml)"
- os: macos-latest
noxenv: "docs(doctest)"
- os: macos-latest
noxenv: "docs(linkcheck)"
- os: macos-latest
noxenv: "docs(man)"
- os: macos-latest
noxenv: "docs(spelling)"
- os: macos-latest
noxenv: "docs(style)"
- os: windows-latest

@@ -80,2 +84,4 @@ noxenv: "docs(dirhtml)"

- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Install dependencies

@@ -91,3 +97,2 @@ run: sudo apt-get update && sudo apt-get install -y libenchant-2-dev

python-version: |
3.8
3.9

@@ -98,11 +103,15 @@ 3.10

3.13
pypy3.10
pypy3.11
allow-prereleases: true
- name: Set up nox
uses: wntrblm/nox@2024.04.15
- name: Enable UTF-8 on Windows
run: echo "PYTHONUTF8=1" >> $env:GITHUB_ENV
if: runner.os == 'Windows' && startsWith(matrix.noxenv, 'tests')
- name: Set up uv
uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb
with:
enable-cache: true
- name: Run nox
run: nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }}
run: uvx nox -s "${{ matrix.noxenv }}" -- ${{ matrix.posargs }} # zizmor: ignore[template-injection]

@@ -115,2 +124,3 @@ packaging:

url: https://pypi.org/p/jsonschema
permissions:

@@ -124,16 +134,17 @@ contents: write

fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
persist-credentials: false
- name: Set up uv
uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb
with:
python-version: "3.x"
- name: Install dependencies
run: python -m pip install build
- name: Create packages
run: python -m build .
enable-cache: true
- name: Build our distributions
run: uv run --with 'build[uv]' -m build --installer=uv
- name: Publish to PyPI
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
- name: Create a Release
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc
- name: Create a GitHub Release
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631
with:

@@ -140,0 +151,0 @@ files: |

name: Read the Docs Pull Request Preview
on:
pull_request_target:
pull_request_target: # zizmor: ignore[dangerous-triggers]
types:

@@ -14,4 +14,4 @@ - opened

steps:
- uses: readthedocs/actions/preview@v1
- uses: readthedocs/actions/preview@b8bba1484329bda1a3abe986df7ebc80a8950333
with:
project-slug: "python-jsonschema"

@@ -5,3 +5,3 @@ exclude: json/

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:

@@ -20,14 +20,5 @@ - id: check-ast

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.5.0"
rev: "v0.11.11"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v4.0.0-alpha.8"
hooks:
- id: prettier
exclude: "^jsonschema/benchmarks/issue232/issue.json$"

@@ -0,1 +1,7 @@

v4.24.0
=======
* Fix improper handling of ``unevaluatedProperties`` in the presence of ``additionalProperties`` (#1351).
* Support for Python 3.8 has been dropped, as it is end-of-life.
v4.23.0

@@ -2,0 +8,0 @@ =======

@@ -223,2 +223,3 @@ =========================

If you stick to the subset of YAML for which this is the case then you shouldn't have issue, but if you pass schemas (or instances) around whose structure could never have possibly existed as JSON (e.g. a mapping whose keys are not strings), all bets are off.
For an example on how to handle that, have a look at the `parsers/yaml.py <https://github.com/python-jsonschema/check-jsonschema/blob/main/src/check_jsonschema/parsers/yaml.py>`_ file in the check-jsonschema repository.

@@ -225,0 +226,0 @@ One could similarly imagine a retrieval function which switches on whether to call ``yaml.safe_load`` or ``json.loads`` by file extension (or some more reliable mechanism) and thereby support retrieving references of various different file formats.

@@ -1,2 +0,2 @@

file:.#egg=jsonschema
file:.
furo

@@ -11,4 +11,1 @@ lxml

sphinxext-opengraph
# Until pyenchant/pyenchant#302 is released...
pyenchant>=3.3.0rc1

@@ -1,58 +0,52 @@

#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --strip-extras docs/requirements.in
#
alabaster==0.7.16
# This file was autogenerated by uv via the following command:
# uv pip compile --output-file /Users/julian/Development/jsonschema/docs/requirements.txt docs/requirements.in
alabaster==1.0.0
# via sphinx
astroid==3.2.2
astroid==3.3.9
# via sphinx-autoapi
attrs==23.2.0
attrs==25.3.0
# via
# jsonschema
# referencing
babel==2.15.0
babel==2.17.0
# via sphinx
beautifulsoup4==4.12.3
beautifulsoup4==4.13.3
# via furo
certifi==2024.6.2
certifi==2025.1.31
# via requests
charset-normalizer==3.3.2
charset-normalizer==3.4.1
# via requests
docutils==0.21.2
# via sphinx
furo==2024.5.6
furo==2024.8.6
# via -r docs/requirements.in
idna==3.7
idna==3.10
# via requests
imagesize==1.4.1
# via sphinx
jinja2==3.1.4
jinja2==3.1.6
# via
# sphinx
# sphinx-autoapi
file:.#egg=jsonschema
jsonschema @ file:.
# via -r docs/requirements.in
jsonschema-specifications==2023.12.1
jsonschema-specifications==2024.10.1
# via jsonschema
lxml==5.2.2
lxml==5.3.1
# via
# -r docs/requirements.in
# sphinx-json-schema-spec
markupsafe==2.1.5
markupsafe==3.0.2
# via jinja2
packaging==24.1
packaging==24.2
# via sphinx
pyenchant==3.3.0rc1
pyenchant==3.2.2
# via sphinxcontrib-spelling
pygments==2.19.1
# via
# -r docs/requirements.in
# sphinxcontrib-spelling
pygments==2.18.0
# via
# furo
# sphinx
pyyaml==6.0.1
pyyaml==6.0.2
# via sphinx-autoapi
referencing==0.35.1
referencing==0.36.2
# via

@@ -62,4 +56,8 @@ # jsonschema

requests==2.32.3
# via
# sphinx
# sphinxcontrib-spelling
roman-numerals-py==3.1.0
# via sphinx
rpds-py==0.18.1
rpds-py==0.24.0
# via

@@ -70,5 +68,5 @@ # jsonschema

# via sphinx
soupsieve==2.5
soupsieve==2.6
# via beautifulsoup4
sphinx==7.3.7
sphinx==8.2.3
# via

@@ -84,5 +82,5 @@ # -r docs/requirements.in

# sphinxext-opengraph
sphinx-autoapi==3.1.1
sphinx-autoapi==3.6.0
# via -r docs/requirements.in
sphinx-autodoc-typehints==2.1.1
sphinx-autodoc-typehints==3.1.0
# via -r docs/requirements.in

@@ -93,21 +91,23 @@ sphinx-basic-ng==1.0.0b2

# via -r docs/requirements.in
sphinx-json-schema-spec==2024.1.1
sphinx-json-schema-spec==2025.1.1
# via -r docs/requirements.in
sphinxcontrib-applehelp==1.0.8
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==1.0.6
sphinxcontrib-devhelp==2.0.0
# via sphinx
sphinxcontrib-htmlhelp==2.0.5
sphinxcontrib-htmlhelp==2.1.0
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.7
sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==1.1.10
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
sphinxcontrib-spelling==8.0.0
sphinxcontrib-spelling==8.0.1
# via -r docs/requirements.in
sphinxext-opengraph==0.9.1
# via -r docs/requirements.in
urllib3==2.2.2
typing-extensions==4.13.0
# via beautifulsoup4
urllib3==2.3.0
# via requests

@@ -230,2 +230,3 @@ # JSON Schema Test Suite

* [Blaze](https://github.com/sourcemeta/blaze)
* [Modern C++ JSON schema validator](https://github.com/pboettch/json-schema-validator)

@@ -297,3 +298,3 @@ * [Valijson](https://github.com/tristanpenman/valijson)

* [JsonSchema.Net](https://github.com/gregsdennis/json-everything)
* [JsonSchema.Net](https://github.com/json-everything/json-everything)
* [Newtonsoft.Json.Schema](https://github.com/JamesNK/Newtonsoft.Json.Schema)

@@ -344,2 +345,3 @@

* [JSONSchema](https://github.com/kylef/JSONSchema.swift)
* [swift-json-schema](https://github.com/ajevans99/swift-json-schema)

@@ -346,0 +348,0 @@ If you use it as well, please fork and send a pull request adding yourself to

@@ -409,16 +409,2 @@ [

{
"description": "\\a is not an ECMA 262 control escape",
"schema": {
"$schema": "https://json-schema.org/draft/next/schema",
"$ref": "https://json-schema.org/draft/next/schema"
},
"tests": [
{
"description": "when used as a pattern",
"data": { "pattern": "\\a" },
"valid": false
}
]
},
{
"description": "pattern with non-ASCII digits",

@@ -425,0 +411,0 @@ "schema": {

@@ -50,2 +50,7 @@ [

{
"description": "must start with P",
"data": "4DT12H30M5S",
"valid": false
},
{
"description": "no elements present",

@@ -52,0 +57,0 @@ "data": "P",

@@ -123,2 +123,12 @@ [

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
},
{
"description": "single dot",
"data": ".",
"valid": false
}

@@ -125,0 +135,0 @@ ]

@@ -260,3 +260,3 @@ [

"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
"data": "\u0660\u06f0",
"data": "\u0628\u0660\u06f0",
"valid": false

@@ -330,5 +330,62 @@ },

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
}
]
},
{
"description": "validation of separators in internationalized host names",
"specification": [
{"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"}
],
"schema": {
"$schema": "https://json-schema.org/draft/next/schema",
"format": "idn-hostname"
},
"tests": [
{
"description": "single dot",
"data": ".",
"valid": false
},
{
"description": "single ideographic full stop",
"data": "\u3002",
"valid": false
},
{
"description": "single fullwidth full stop",
"data": "\uff0e",
"valid": false
},
{
"description": "single halfwidth ideographic full stop",
"data": "\uff61",
"valid": false
},
{
"description": "dot as label separator",
"data": "a.b",
"valid": true
},
{
"description": "ideographic full stop as label separator",
"data": "a\u3002b",
"valid": true
},
{
"description": "fullwidth full stop as label separator",
"data": "a\uff0eb",
"valid": true
},
{
"description": "halfwidth ideographic full stop as label separator",
"data": "a\uff61b",
"valid": true
}
]
}
]

@@ -50,2 +50,7 @@ [

{
"description": "must start with P",
"data": "4DT12H30M5S",
"valid": false
},
{
"description": "no elements present",

@@ -52,0 +57,0 @@ "data": "P",

@@ -123,2 +123,12 @@ [

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
},
{
"description": "single dot",
"data": ".",
"valid": false
}

@@ -125,0 +135,0 @@ ]

@@ -260,3 +260,3 @@ [

"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
"data": "\u0660\u06f0",
"data": "\u0628\u0660\u06f0",
"valid": false

@@ -330,5 +330,62 @@ },

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
}
]
},
{
"description": "validation of separators in internationalized host names",
"specification": [
{"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"}
],
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"format": "idn-hostname"
},
"tests": [
{
"description": "single dot",
"data": ".",
"valid": false
},
{
"description": "single ideographic full stop",
"data": "\u3002",
"valid": false
},
{
"description": "single fullwidth full stop",
"data": "\uff0e",
"valid": false
},
{
"description": "single halfwidth ideographic full stop",
"data": "\uff61",
"valid": false
},
{
"description": "dot as label separator",
"data": "a.b",
"valid": true
},
{
"description": "ideographic full stop as label separator",
"data": "a\u3002b",
"valid": true
},
{
"description": "fullwidth full stop as label separator",
"data": "a\uff0eb",
"valid": true
},
{
"description": "halfwidth ideographic full stop as label separator",
"data": "a\uff61b",
"valid": true
}
]
}
]

@@ -114,3 +114,56 @@ [

]
},
{
"description": "propertyNames with const",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"propertyNames": {"const": "foo"}
},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"bar": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
},
{
"description": "propertyNames with enum",
"schema": {
"$schema": "https://json-schema.org/draft/2019-09/schema",
"propertyNames": {"enum": ["foo", "bar"]}
},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with property foo and bar is valid",
"data": {"foo": 1, "bar": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"baz": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
}
]

@@ -409,16 +409,2 @@ [

{
"description": "\\a is not an ECMA 262 control escape",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$ref": "https://json-schema.org/draft/2020-12/schema"
},
"tests": [
{
"description": "when used as a pattern",
"data": { "pattern": "\\a" },
"valid": false
}
]
},
{
"description": "pattern with non-ASCII digits",

@@ -425,0 +411,0 @@ "schema": {

@@ -50,2 +50,7 @@ [

{
"description": "must start with P",
"data": "4DT12H30M5S",
"valid": false
},
{
"description": "no elements present",

@@ -52,0 +57,0 @@ "data": "P",

@@ -123,2 +123,12 @@ [

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
},
{
"description": "single dot",
"data": ".",
"valid": false
}

@@ -125,0 +135,0 @@ ]

@@ -260,3 +260,3 @@ [

"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
"data": "\u0660\u06f0",
"data": "\u0628\u0660\u06f0",
"valid": false

@@ -330,5 +330,62 @@ },

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
}
]
},
{
"description": "validation of separators in internationalized host names",
"specification": [
{"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"}
],
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"format": "idn-hostname"
},
"tests": [
{
"description": "single dot",
"data": ".",
"valid": false
},
{
"description": "single ideographic full stop",
"data": "\u3002",
"valid": false
},
{
"description": "single fullwidth full stop",
"data": "\uff0e",
"valid": false
},
{
"description": "single halfwidth ideographic full stop",
"data": "\uff61",
"valid": false
},
{
"description": "dot as label separator",
"data": "a.b",
"valid": true
},
{
"description": "ideographic full stop as label separator",
"data": "a\u3002b",
"valid": true
},
{
"description": "fullwidth full stop as label separator",
"data": "a\uff0eb",
"valid": true
},
{
"description": "halfwidth ideographic full stop as label separator",
"data": "a\uff61b",
"valid": true
}
]
}
]

@@ -48,2 +48,32 @@ [

{
"description": "propertyNames validation with pattern",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"propertyNames": { "pattern": "^a+$" }
},
"tests": [
{
"description": "matching property names valid",
"data": {
"a": {},
"aa": {},
"aaa": {}
},
"valid": true
},
{
"description": "non-matching property name is invalid",
"data": {
"aaA": {}
},
"valid": false
},
{
"description": "object without properties is valid",
"data": {},
"valid": true
}
]
},
{
"description": "propertyNames with boolean schema true",

@@ -85,3 +115,56 @@ "schema": {

]
},
{
"description": "propertyNames with const",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"propertyNames": {"const": "foo"}
},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"bar": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
},
{
"description": "propertyNames with enum",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"propertyNames": {"enum": ["foo", "bar"]}
},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with property foo and bar is valid",
"data": {"foo": 1, "bar": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"baz": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
}
]

@@ -6,3 +6,2 @@ [

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"unevaluatedProperties": true

@@ -29,3 +28,2 @@ },

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"unevaluatedProperties": {

@@ -62,3 +60,2 @@ "type": "string",

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"unevaluatedProperties": false

@@ -85,3 +82,2 @@ },

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -114,3 +110,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"patternProperties": {

@@ -140,9 +135,5 @@ "^foo": { "type": "string" }

{
"description": "unevaluatedProperties with adjacent additionalProperties",
"description": "unevaluatedProperties with adjacent bool additionalProperties",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"foo": { "type": "string" }
},
"additionalProperties": true,

@@ -170,6 +161,30 @@ "unevaluatedProperties": false

{
"description": "unevaluatedProperties with adjacent non-bool additionalProperties",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": { "type": "string" },
"unevaluatedProperties": false
},
"tests": [
{
"description": "with only valid additional properties",
"data": {
"foo": "foo"
},
"valid": true
},
{
"description": "with invalid additional properties",
"data": {
"foo": "foo",
"bar": 1
},
"valid": false
}
]
},
{
"description": "unevaluatedProperties with nested properties",
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -211,3 +226,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -249,3 +263,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -283,3 +296,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -320,3 +332,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -390,3 +401,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -435,3 +445,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -465,3 +474,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"if": {

@@ -526,3 +534,2 @@ "properties": {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"if": {

@@ -581,3 +588,2 @@ "properties": {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"if": {

@@ -636,3 +642,2 @@ "properties": {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -673,3 +678,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -702,3 +706,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"$ref": "#/$defs/bar",

@@ -741,3 +744,2 @@ "properties": {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"unevaluatedProperties": false,

@@ -796,3 +798,2 @@ "properties": {

"unevaluatedProperties": false,
"type": "object",
"properties": {

@@ -886,3 +887,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -920,3 +920,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"allOf": [

@@ -954,3 +953,2 @@ {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -988,3 +986,2 @@ "foo": { "type": "string" }

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"allOf": [

@@ -1022,3 +1019,2 @@ {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"allOf": [

@@ -1058,3 +1054,2 @@ {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"allOf": [

@@ -1095,6 +1090,4 @@ {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"foo": {
"type": "object",
"properties": {

@@ -1148,3 +1141,2 @@ "bar": {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"allOf": [

@@ -1195,3 +1187,2 @@ {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"allOf": [

@@ -1242,3 +1233,2 @@ {

"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {

@@ -1245,0 +1235,0 @@ "x": { "$ref": "#" }

@@ -60,2 +60,7 @@ [

"valid": false
},
{
"description": "empty string",
"data": "",
"valid": false
}

@@ -62,0 +67,0 @@ ]

@@ -20,3 +20,3 @@ [

"description": "fragment within remote ref",
"schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"},
"schema": {"$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/integer"},
"tests": [

@@ -38,3 +38,3 @@ {

"schema": {
"$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger"
"$ref": "http://localhost:1234/draft3/subSchemas.json#/definitions/refToInteger"
},

@@ -41,0 +41,0 @@ "tests": [

@@ -115,2 +115,12 @@ [

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
},
{
"description": "single dot",
"data": ".",
"valid": false
}

@@ -117,0 +127,0 @@ ]

@@ -20,3 +20,3 @@ [

"description": "fragment within remote ref",
"schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"},
"schema": {"$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/integer"},
"tests": [

@@ -38,3 +38,3 @@ {

"schema": {
"$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger"
"$ref": "http://localhost:1234/draft4/subSchemas.json#/definitions/refToInteger"
},

@@ -144,3 +144,3 @@ "tests": [

"properties": {
"name": {"$ref": "name.json#/definitions/orNull"}
"name": {"$ref": "draft4/name.json#/definitions/orNull"}
}

@@ -177,3 +177,3 @@ },

"schema": {
"$ref": "http://localhost:1234/locationIndependentIdentifierDraft4.json#/definitions/refToInteger"
"$ref": "http://localhost:1234/draft4/locationIndependentIdentifier.json#/definitions/refToInteger"
},

@@ -180,0 +180,0 @@ "tests": [

@@ -115,2 +115,12 @@ [

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
},
{
"description": "single dot",
"data": ".",
"valid": false
}

@@ -117,0 +127,0 @@ ]

@@ -106,3 +106,50 @@ [

]
},
{
"description": "propertyNames with const",
"schema": {"propertyNames": {"const": "foo"}},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"bar": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
},
{
"description": "propertyNames with enum",
"schema": {"propertyNames": {"enum": ["foo", "bar"]}},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with property foo and bar is valid",
"data": {"foo": 1, "bar": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"baz": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
}
]

@@ -20,3 +20,3 @@ [

"description": "fragment within remote ref",
"schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"},
"schema": {"$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/integer"},
"tests": [

@@ -38,3 +38,3 @@ {

"schema": {
"$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger"
"$ref": "http://localhost:1234/draft6/subSchemas.json#/definitions/refToInteger"
},

@@ -144,3 +144,3 @@ "tests": [

"properties": {
"name": {"$ref": "name.json#/definitions/orNull"}
"name": {"$ref": "draft6/name.json#/definitions/orNull"}
}

@@ -179,3 +179,3 @@ },

"allOf": [
{ "$ref": "ref-and-definitions.json" }
{ "$ref": "draft6/ref-and-definitions.json" }
]

@@ -203,3 +203,3 @@ },

"schema": {
"$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger"
"$ref": "http://localhost:1234/draft6/locationIndependentIdentifier.json#/definitions/refToInteger"
},

@@ -206,0 +206,0 @@ "tests": [

@@ -115,2 +115,12 @@ [

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
},
{
"description": "single dot",
"data": ".",
"valid": false
}

@@ -117,0 +127,0 @@ ]

@@ -257,3 +257,3 @@ [

"comment": "https://tools.ietf.org/html/rfc5891#section-4.2.3.3 https://tools.ietf.org/html/rfc5892#appendix-A.8",
"data": "\u0660\u06f0",
"data": "\u0628\u0660\u06f0",
"valid": false

@@ -322,5 +322,59 @@ },

"valid": true
},
{
"description": "empty string",
"data": "",
"valid": false
}
]
},
{
"description": "validation of separators in internationalized host names",
"specification": [
{"rfc3490": "3.1", "quote": "Whenever dots are used as label separators, the following characters MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), U+FF61(halfwidth ideographic full stop)"}
],
"schema": { "format": "idn-hostname" },
"tests": [
{
"description": "single dot",
"data": ".",
"valid": false
},
{
"description": "single ideographic full stop",
"data": "\u3002",
"valid": false
},
{
"description": "single fullwidth full stop",
"data": "\uff0e",
"valid": false
},
{
"description": "single halfwidth ideographic full stop",
"data": "\uff61",
"valid": false
},
{
"description": "dot as label separator",
"data": "a.b",
"valid": true
},
{
"description": "ideographic full stop as label separator",
"data": "a\u3002b",
"valid": true
},
{
"description": "fullwidth full stop as label separator",
"data": "a\uff0eb",
"valid": true
},
{
"description": "halfwidth ideographic full stop as label separator",
"data": "a\uff61b",
"valid": true
}
]
}
]

@@ -106,3 +106,50 @@ [

]
},
{
"description": "propertyNames with const",
"schema": {"propertyNames": {"const": "foo"}},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"bar": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
},
{
"description": "propertyNames with enum",
"schema": {"propertyNames": {"enum": ["foo", "bar"]}},
"tests": [
{
"description": "object with property foo is valid",
"data": {"foo": 1},
"valid": true
},
{
"description": "object with property foo and bar is valid",
"data": {"foo": 1, "bar": 1},
"valid": true
},
{
"description": "object with any other property is invalid",
"data": {"baz": 1},
"valid": false
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
}
]

@@ -20,3 +20,3 @@ [

"description": "fragment within remote ref",
"schema": {"$ref": "http://localhost:1234/subSchemas.json#/definitions/integer"},
"schema": {"$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/integer"},
"tests": [

@@ -38,3 +38,3 @@ {

"schema": {
"$ref": "http://localhost:1234/subSchemas.json#/definitions/refToInteger"
"$ref": "http://localhost:1234/draft7/subSchemas.json#/definitions/refToInteger"
},

@@ -144,3 +144,3 @@ "tests": [

"properties": {
"name": {"$ref": "name.json#/definitions/orNull"}
"name": {"$ref": "draft7/name.json#/definitions/orNull"}
}

@@ -179,3 +179,3 @@ },

"allOf": [
{ "$ref": "ref-and-definitions.json" }
{ "$ref": "draft7/ref-and-definitions.json" }
]

@@ -203,3 +203,3 @@ },

"schema": {
"$ref": "http://localhost:1234/locationIndependentIdentifierPre2019.json#/definitions/refToInteger"
"$ref": "http://localhost:1234/draft7/locationIndependentIdentifier.json#/definitions/refToInteger"
},

@@ -206,0 +206,0 @@ "tests": [

@@ -109,4 +109,2 @@ """

__all__ = [
"Draft201909Validator",
"Draft202012Validator",
"Draft3Validator",

@@ -116,2 +114,4 @@ "Draft4Validator",

"Draft7Validator",
"Draft201909Validator",
"Draft202012Validator",
"FormatChecker",

@@ -118,0 +118,0 @@ "SchemaError",

@@ -16,5 +16,3 @@ from __future__ import annotations

_F = typing.TypeVar("_F", bound=_FormatCheckCallable)
_RaisesType = typing.Union[
typing.Type[Exception], typing.Tuple[typing.Type[Exception], ...],
]
_RaisesType = typing.Union[type[Exception], tuple[type[Exception], ...]]

@@ -278,2 +276,6 @@ _RE_DATE = re.compile(r"^\d{4}-\d{2}-\d{2}$", re.ASCII)

draft202012="hostname",
# fqdn.FQDN("") raises a ValueError due to a bug
# however, it's not clear when or if that will be fixed, so catch it
# here for now
raises=ValueError,
)

@@ -280,0 +282,0 @@ def is_host_name(instance: object) -> bool:

from __future__ import annotations
from typing import Any, Callable, Mapping
from typing import TYPE_CHECKING
import numbers

@@ -11,3 +11,7 @@

if TYPE_CHECKING:
from collections.abc import Mapping
from typing import Any, Callable
# unfortunately, the type of HashTrieMap is generic, and if used as an attrs

@@ -196,3 +200,3 @@ # converter, the generic type is presented to mypy, which then fails to match

is_integer(checker, instance)
or isinstance(instance, float) and instance.is_integer()
or (isinstance(instance, float) and instance.is_integer())
),

@@ -199,0 +203,0 @@ )

"""
Some (initially private) typing helpers for jsonschema's types.
"""
from typing import Any, Callable, Iterable, Protocol, Tuple, Union
from collections.abc import Iterable
from typing import Any, Callable, Protocol, Union

@@ -27,3 +28,3 @@ import referencing.jsonschema

[referencing.jsonschema.Schema],
Iterable[Tuple[str, Any]],
Iterable[tuple[str, Any]],
]

@@ -301,14 +301,14 @@ from collections.abc import Mapping, MutableMapping, Sequence

for keyword in [
"properties", "additionalProperties", "unevaluatedProperties",
]:
if keyword in schema:
schema_value = schema[keyword]
if validator.is_type(schema_value, "boolean") and schema_value:
evaluated_keys += instance.keys()
properties = schema.get("properties")
if validator.is_type(properties, "object"):
evaluated_keys += properties.keys() & instance.keys()
elif validator.is_type(schema_value, "object"):
for property in schema_value:
if property in instance:
evaluated_keys.append(property)
for keyword in ["additionalProperties", "unevaluatedProperties"]:
if (subschema := schema.get(keyword)) is None:
continue
evaluated_keys += (
key
for key, value in instance.items()
if is_valid(validator.descend(value, subschema))
)

@@ -330,9 +330,8 @@ if "patternProperties" in schema:

for keyword in ["allOf", "oneOf", "anyOf"]:
if keyword in schema:
for subschema in schema[keyword]:
errs = next(validator.descend(instance, subschema), None)
if errs is None:
evaluated_keys += find_evaluated_property_keys_by_schema(
validator, instance, subschema,
)
for subschema in schema.get(keyword, []):
if not is_valid(validator.descend(instance, subschema)):
continue
evaluated_keys += find_evaluated_property_keys_by_schema(
validator, instance, subschema,
)

@@ -354,1 +353,6 @@ if "if" in schema:

return evaluated_keys
def is_valid(errs_it):
"""Whether there are no errors in the given iterator."""
return next(errs_it, None) is None

@@ -11,3 +11,2 @@ """

import heapq
import itertools
import warnings

@@ -475,7 +474,5 @@

"""
errors = iter(errors)
best = next(errors, None)
best = max(errors, key=key, default=None)
if best is None:
return
best = max(itertools.chain([best], errors), key=key)

@@ -482,0 +479,0 @@ while best.context:

@@ -10,10 +10,3 @@ """

from typing import (
TYPE_CHECKING,
Any,
ClassVar,
Iterable,
Protocol,
runtime_checkable,
)
from typing import TYPE_CHECKING, Any, ClassVar, Protocol, runtime_checkable

@@ -25,3 +18,3 @@ # in order for Sphinx to resolve references accurately from type annotations,

if TYPE_CHECKING:
from collections.abc import Mapping
from collections.abc import Iterable, Mapping

@@ -28,0 +21,0 @@ import referencing.jsonschema

@@ -13,3 +13,2 @@ """

import re
import subprocess
import sys

@@ -25,2 +24,3 @@ import unittest

from referencing.jsonschema import Schema
import pyperf

@@ -31,2 +31,4 @@

MAGIC_REMOTE_URL = "http://localhost:1234"
_DELIMITERS = re.compile(r"[\W\- ]+")

@@ -57,35 +59,4 @@

_root: Path = field(factory=_find_suite)
_remotes: referencing.jsonschema.SchemaRegistry = field(init=False)
def __attrs_post_init__(self):
jsonschema_suite = self._root.joinpath("bin", "jsonschema_suite")
argv = [sys.executable, str(jsonschema_suite), "remotes"]
remotes = subprocess.check_output(argv).decode("utf-8")
resources = json.loads(remotes)
li = "http://localhost:1234/locationIndependentIdentifierPre2019.json"
li4 = "http://localhost:1234/locationIndependentIdentifierDraft4.json"
registry = Registry().with_resources(
[
(
li,
referencing.jsonschema.DRAFT7.create_resource(
contents=resources.pop(li),
),
),
(
li4,
referencing.jsonschema.DRAFT4.create_resource(
contents=resources.pop(li4),
),
),
],
).with_contents(
resources.items(),
default_specification=referencing.jsonschema.DRAFT202012,
)
object.__setattr__(self, "_remotes", registry)
def benchmark(self, runner: pyperf.Runner): # pragma: no cover

@@ -99,6 +70,14 @@ for name, Validator in _VALIDATORS.items():

def version(self, name) -> Version:
Validator = _VALIDATORS[name]
uri: str = Validator.ID_OF(Validator.META_SCHEMA) # type: ignore[assignment]
specification = referencing.jsonschema.specification_with(uri)
registry = Registry().with_contents(
remotes_in(root=self._root / "remotes", name=name, uri=uri),
default_specification=specification,
)
return Version(
name=name,
path=self._root / "tests" / name,
remotes=self._remotes,
remotes=registry,
)

@@ -195,2 +174,32 @@

def remotes_in(
root: Path,
name: str,
uri: str,
) -> Iterable[tuple[str, Schema]]:
# This messy logic is because the test suite is terrible at indicating
# what remotes are needed for what drafts, and mixes in schemas which
# have no $schema and which are invalid under earlier versions, in with
# other schemas which are needed for tests.
for each in root.rglob("*.json"):
schema = json.loads(each.read_text())
relative = str(each.relative_to(root)).replace("\\", "/")
if (
( # invalid boolean schema
name in {"draft3", "draft4"}
and each.stem == "tree"
) or
( # draft<NotThisDialect>/*.json
"$schema" not in schema
and relative.startswith("draft")
and not relative.startswith(name)
)
):
continue
yield f"{MAGIC_REMOTE_URL}/{relative}", schema
@frozen(repr=False)

@@ -197,0 +206,0 @@ class _Test:

@@ -693,3 +693,3 @@ from contextlib import redirect_stderr, redirect_stdout

def test_successful_validation_via_explicit_base_uri(self):
ref_schema_file = tempfile.NamedTemporaryFile(delete=False)
ref_schema_file = tempfile.NamedTemporaryFile(delete=False) # noqa: SIM115
ref_schema_file.close()

@@ -715,3 +715,3 @@ self.addCleanup(os.remove, ref_schema_file.name)

def test_unsuccessful_validation_via_explicit_base_uri(self):
ref_schema_file = tempfile.NamedTemporaryFile(delete=False)
ref_schema_file = tempfile.NamedTemporaryFile(delete=False) # noqa: SIM115
ref_schema_file.close()

@@ -886,7 +886,4 @@ self.addCleanup(os.remove, ref_schema_file.name)

def test_license(self):
output = subprocess.check_output(
[sys.executable, "-m", "pip", "show", "jsonschema"],
stderr=subprocess.STDOUT,
)
self.assertIn(b"License: MIT", output)
our_metadata = metadata.metadata("jsonschema")
self.assertEqual(our_metadata.get("License-Expression"), "MIT")

@@ -893,0 +890,0 @@ def test_version(self):

@@ -186,3 +186,3 @@ from contextlib import contextmanager

with self.assertWarnsRegex(DeprecationWarning, message) as w:
from jsonschema.validators import RefResolver # noqa: F401, F811
from jsonschema.validators import RefResolver # noqa: F401
self.assertEqual(w.filename, __file__)

@@ -189,0 +189,0 @@

@@ -9,3 +9,2 @@ """

import sys

@@ -31,2 +30,7 @@ from jsonschema.tests._suite import Suite

def ecmascript_regex(test):
if test.subject == "ecmascript-regex":
return "ECMA regex support will be added in #1142."
def missing_format(Validator):

@@ -71,14 +75,2 @@ def missing_format(test): # pragma: no cover

if sys.version_info < (3, 9): # pragma: no cover
message = "Rejecting leading zeros is 3.9+"
allowed_leading_zeros = skip(
message=message,
subject="ipv4",
description="invalid leading zeroes, as they are treated as octals",
)
else:
def allowed_leading_zeros(test): # pragma: no cover
return
def leap_second(test):

@@ -138,3 +130,4 @@ message = "Leap seconds are unsupported."

skip=lambda test: (
missing_format(jsonschema.Draft3Validator)(test)
ecmascript_regex(test)
or missing_format(jsonschema.Draft3Validator)(test)
or complex_email_validation(test)

@@ -156,3 +149,3 @@ ),

skip=lambda test: (
allowed_leading_zeros(test)
ecmascript_regex(test)
or leap_second(test)

@@ -175,3 +168,3 @@ or missing_format(jsonschema.Draft4Validator)(test)

skip=lambda test: (
allowed_leading_zeros(test)
ecmascript_regex(test)
or leap_second(test)

@@ -196,3 +189,3 @@ or missing_format(jsonschema.Draft6Validator)(test)

skip=lambda test: (
allowed_leading_zeros(test)
ecmascript_regex(test)
or leap_second(test)

@@ -234,3 +227,3 @@ or missing_format(jsonschema.Draft7Validator)(test)

complex_email_validation(test)
or allowed_leading_zeros(test)
or ecmascript_regex(test)
or leap_second(test)

@@ -272,3 +265,3 @@ or missing_format(jsonschema.Draft201909Validator)(test)

complex_email_validation(test)
or allowed_leading_zeros(test)
or ecmascript_regex(test)
or leap_second(test)

@@ -275,0 +268,0 @@ or missing_format(jsonschema.Draft202012Validator)(test)

@@ -860,3 +860,3 @@ """

_LATEST_VERSION = Draft202012Validator
_LATEST_VERSION: type[Validator] = Draft202012Validator

@@ -1338,3 +1338,3 @@

schema,
default: Validator | _utils.Unset = _UNSET,
default: type[Validator] | _utils.Unset = _UNSET,
) -> type[Validator]:

@@ -1401,3 +1401,3 @@ """

if schema is True or schema is False or "$schema" not in schema:
return DefaultValidator
return DefaultValidator # type: ignore[return-value]
if schema["$schema"] not in _META_SCHEMAS and default is _UNSET:

@@ -1404,0 +1404,0 @@ warn(

@@ -25,3 +25,3 @@ from pathlib import Path

REQUIREMENTS_IN = [ # this is actually ordered, as files depend on each other
path.parent / f"{path.stem}.in" for path in REQUIREMENTS.values()
(path.parent / f"{path.stem}.in", path) for path in REQUIREMENTS.values()
]

@@ -33,2 +33,3 @@

"ISC License (ISCL)",
"MIT",
"MIT License",

@@ -40,5 +41,6 @@ "Mozilla Public License 2.0 (MPL 2.0)",

SUPPORTED = ["3.8", "3.9", "3.10", "pypy3.10", "3.11", "3.12", "3.13"]
LATEST_STABLE = "3.12"
SUPPORTED = ["3.9", "3.10", "pypy3.11", "3.11", "3.12", "3.13"]
LATEST_STABLE = SUPPORTED[-1]
nox.options.default_venv_backend = "uv|virtualenv"
nox.options.sessions = []

@@ -121,5 +123,15 @@

"--ignore-packages",
# because they're not our deps
"pip-requirements-parser",
"pip_audit",
"pip-api",
# because pip-licenses doesn't yet support PEP 639 :/
"attrs",
"jsonschema",
"jsonschema-specifications",
"referencing",
"types-python-dateutil",
"--allow-only",

@@ -135,5 +147,11 @@ ";".join(NONGPL_LICENSES),

"""
session.install("build", "docutils", "twine")
session.install("build[uv]", "docutils", "twine")
with TemporaryDirectory() as tmpdir:
session.run("python", "-m", "build", ROOT, "--outdir", tmpdir)
session.run(
"pyproject-build",
"--installer=uv",
ROOT,
"--outdir",
tmpdir,
)
session.run("twine", "check", "--strict", tmpdir + "/*")

@@ -151,3 +169,3 @@ session.run(

session.install("detect-secrets")
session.run("detect-secrets", "scan", ROOT)
session.run("detect-secrets", "scan", ROOT, "--exclude-files", "json/")

@@ -248,11 +266,11 @@

"""
session.install("pip-tools")
for each in REQUIREMENTS_IN:
session.run(
"pip-compile",
"--resolver",
"backtracking",
"--strip-extras",
"-U",
each.relative_to(ROOT),
)
if session.venv_backend == "uv":
cmd = ["uv", "pip", "compile"]
else:
session.install("pip-tools")
cmd = ["pip-compile", "--resolver", "backtracking", "--strip-extras"]
for each, out in REQUIREMENTS_IN:
# otherwise output files end up with silly absolute path comments...
relative = each.relative_to(ROOT)
session.run(*cmd, "--upgrade", "--output-file", out, relative)

@@ -1,4 +0,4 @@

Metadata-Version: 2.3
Metadata-Version: 2.4
Name: jsonschema
Version: 4.23.0
Version: 4.24.0
Summary: An implementation of JSON Schema validation for Python

@@ -13,3 +13,3 @@ Project-URL: Homepage, https://github.com/python-jsonschema/jsonschema

Author-email: Julian Berman <Julian+jsonschema@GrayVines.com>
License: MIT
License-Expression: MIT
License-File: COPYING

@@ -19,6 +19,4 @@ Keywords: data validation,json,json schema,jsonschema,validation

Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9

@@ -33,3 +31,3 @@ Classifier: Programming Language :: Python :: 3.10

Classifier: Topic :: File Formats :: JSON :: JSON Schema
Requires-Python: >=3.8
Requires-Python: >=3.9
Requires-Dist: attrs>=22.2.0

@@ -165,4 +163,2 @@ Requires-Dist: importlib-resources>=1.4.0; python_version < '3.9'

You can also generally find me on Libera (nick: ``Julian``) in various channels, including ``#python``.
If you feel overwhelmingly grateful, you can also `sponsor me <https://github.com/sponsors/Julian/>`_.

@@ -176,6 +172,6 @@

v4.23.0
v4.24.0
=======
* Do not reorder dictionaries (schemas, instances) that are printed as part of validation errors.
* Declare support for Py3.13
* Fix improper handling of ``unevaluatedProperties`` in the presence of ``additionalProperties`` (#1351).
* Support for Python 3.8 has been dropped, as it is end-of-life.

@@ -11,4 +11,5 @@ [build-system]

description = "An implementation of JSON Schema validation for Python"
requires-python = ">=3.8"
license = {text = "MIT"}
requires-python = ">=3.9"
license = "MIT"
license-files = ["COPYING"]
keywords = [

@@ -27,6 +28,4 @@ "validation",

"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",

@@ -135,13 +134,6 @@ "Programming Language :: Python :: 3.10",

ignore = [
"D000", # see PyCQA/doc8#125
"D001", # one sentence per line, so max length doesn't make sense
"D000", # see PyCQA/doc8#125
"D001", # one sentence per line, so max length doesn't make sense
]
[tool.isort]
combine_as_imports = true
ensure_newline_before_comments = true
from_first = true
include_trailing_comma = true
multi_line_output = 3
[tool.mypy]

@@ -162,2 +154,3 @@ ignore_missing_imports = true

"A003",
"A005",
"ARG", # This is all wrong whenever an interface is involved

@@ -192,2 +185,3 @@ "ANN", # Just let the type checker do this

"PLR1714", # This makes for uglier comparisons sometimes
"PLW0642", # Shadowing self also isn't a big deal.
"PLW2901", # Shadowing for loop variables is occasionally fine.

@@ -205,3 +199,3 @@ "PT", # We use unittest

"TRY003", # Some exception classes are essentially intended for free-form
"UP007", # We support 3.8 + 3.9
"UP007", # We support 3.9
]

@@ -208,0 +202,0 @@

@@ -137,6 +137,4 @@ ==========

You can also generally find me on Libera (nick: ``Julian``) in various channels, including ``#python``.
If you feel overwhelmingly grateful, you can also `sponsor me <https://github.com/sponsors/Julian/>`_.
And for companies who appreciate ``jsonschema`` and its continued support and growth, ``jsonschema`` is also now supportable via `TideLift <https://tidelift.com/subscription/pkg/pypi-jsonschema?utm_source=pypi-jsonschema&utm_medium=referral&utm_campaign=readme>`_.
name: CIFuzz
on:
pull_request:
branches:
- main
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: "jsonschema"
language: python
continue-on-error: true
- name: Run Fuzzers
if: steps.build.outcome == 'success'
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: "jsonschema"
fuzz-seconds: 30
- name: Upload Crash
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts
{
"definitions": {
"refToInteger": {
"$ref": "#foo"
},
"A": {
"id": "#foo",
"type": "integer"
}
}
}
{
"definitions": {
"refToInteger": {
"$ref": "#foo"
},
"A": {
"$id": "#foo",
"type": "integer"
}
}
}
{
"definitions": {
"orNull": {
"anyOf": [
{
"type": "null"
},
{
"$ref": "#"
}
]
}
},
"type": "string"
}
{
"$id": "http://localhost:1234/ref-and-definitions.json",
"definitions": {
"inner": {
"properties": {
"bar": { "type": "string" }
}
}
},
"allOf": [ { "$ref": "#/definitions/inner" } ]
}
{
"definitions": {
"integer": {
"type": "integer"
},
"refToInteger": {
"$ref": "#/definitions/integer"
}
}
}
[
{
"description": "ECMA 262 regex dialect recognition",
"schema": { "format": "regex" },
"tests": [
{
"description": "[^] is a valid regex",
"data": "[^]",
"valid": true
},
{
"description": "ECMA 262 has no support for lookbehind",
"data": "(?<=foo)bar",
"valid": false
}
]
}
]