jsonvet
jsonvet checks JSON, I-JSON, JSONC, HuJSON (JWCC), JSON5 and JSON Lines files for syntax errors, duplicate keys and the rules of each dialect. Each problem comes with its file, line, column and rule. Columns count Unicode code points from 1, and a byte order mark is column 1. A duplicate key also gets its JSONPath and the position of the first copy:
config.json:4:5: error[duplicate-key] duplicate key $.server.port (first at 2:5)
package.json:3:3: error[syntax] expected `,` or `}`, found `"`
events.jsonl:12:1: error[syntax] blank line; JSON Lines needs a value on every line
A file jsonvet cannot read gets a line with no position and no rule, such as
gone.json: error: no such file; in SARIF it is a result under the rule unreadable.
It runs as a pre-commit or prek hook, a GitHub Action, a command and a Rust library. Up to 1.4 it was check-json5, a Python hook. 2.0 rewrote it in Rust with the same verdicts (see Coming from check-json5).
Use it as a hook
In .pre-commit-config.yaml (pre-commit or prek):
- repo: https://github.com/simonvanlierde/jsonvet
rev: v3.0.0
hooks:
- id: jsonvet
Options go in args. This holds package.json to strict JSON and checks .vscode files as
JSONC:
- id: jsonvet
args: [--strict, package.json, --dialect, "jsonc:.vscode/*.json"]
It checks files by name: .json, .jsonc, .json5, .jsonl, .ndjson, .geojson, .jsonld,
.hujson, .jwcc, .code-workspace, .code-snippets, .webmanifest and .babelrc.
The hook and the Action install a prebuilt binary from PyPI, so they need no Rust. In GitHub Actions each problem also becomes an annotation on the pull request.
Use it as a GitHub Action
- uses: simonvanlierde/jsonvet@v3
The step fails when a file has an error. It runs on Linux, macOS and Windows runners with no other setup. All inputs are optional:
| Input | What it does |
|---|---|
files |
paths or globs to check, separated by spaces; by default every tracked file the hook checks |
args |
extra options, separated by spaces, such as --strict package.json |
sarif |
also write a SARIF file to this path (see GitHub code scanning) |
version |
the jsonvet version to install: X.Y.Z (also with a suffix such as rc1 or .post1), X.*, X.Y.* or latest |
In files, ** matches folders at any depth on every runner. The Action skips symlinks, and by
default also submodules. Any other version value stops the step.
By default the Action installs the release that matches its own tag: @v3 gets the newest 3.x,
@v3.0.0 gets 3.0.0. Pinned to a commit SHA or a branch, it installs the release named in that
commit's Cargo.toml. Between releases that is the last release, not the code in the commit.
The step log names the version it installed. Pinning the Action does not pin the wheel's bytes:
pip installs jsonvet==X.Y.Z from PyPI without a hash check.
Use it from the command line
uvx jsonvet config/*.json # from PyPI, without installing
pip install jsonvet # as a Python package
cargo install jsonvet-cli # from source
The Rust library is the jsonvet crate:
use jsonvet::{check, Config, Dialect};
let report = check("{\"a\": 1, \"a\": 2}", &Config::new(Dialect::Json));
for problem in report.problems() {
let at = report.location(problem.offset());
println!("{}:{}: {}[{}] {problem}", at.line, at.column, problem.severity(), problem.rule());
}
Options
--dialect DIALECT[:GLOB] check files matching GLOB (every file, without one) as DIALECT,
or as `auto`, the extension's default; the last match wins
--strict GLOB the same as --dialect json:GLOB, kept from check-json5
--error RULE, --warn RULE, --ignore RULE
--max-warnings N
--format text|sarif text lines (the default), or one SARIF 2.1.0 document on stdout
--schema FILE also check every file against the JSON Schema in FILE
--config FILE, --no-config
A glob without / matches the file name at any depth. A glob with / matches the whole path,
and * also matches /. A glob compares exact code points, with no Unicode normalization, and
a \ in a path is read as /. A glob on the command line matches the path as you typed it, so
it is relative to the working directory. pre-commit runs from the repository root.
pre-commit passes file names with no -- before them. So an unknown -x or --name, or a known
option with a value such as --dialect=json, is a file name when a file of exactly that name
exists. Otherwise an unknown one is a usage error (unknown option). Put -- before the file
names to be sure: jsonvet -- --x.json.
Exit status: 0 when no file has an error, 1 when one does, 2 for a usage error. With no files,
jsonvet exits 0. A file that does not exist or cannot be read prints name: error: <reason>, with
no line or column, and makes the run exit 1. jsonvet reads regular files only, and follows a
symlink to one. A directory, device, FIFO or socket prints error: not a regular file. The hook
(types: [text]) skips tracked symlinks and submodules. When the output pipe closes early, as in
jsonvet … | head -1, jsonvet stops quietly and exits with the verdict for the files it has
checked.
Configuration
Settings can also live in jsonvet.toml, or in a [tool.jsonvet] table in pyproject.toml.
jsonvet looks in the working directory and its parents up to the repository root. The command
line wins.
rules = { byte-order-mark = "ignore", missing-final-newline = "error" }
# Checked in order; the last matching entry wins.
dialects = [
{ files = ".vscode/*.json", dialect = "jsonc" },
{ files = "package.json", dialect = "json" },
]
A glob in a config file is relative to the directory that holds the file. So data/*.json in the
root's jsonvet.toml matches data/x.json when jsonvet runs in the root, in data/, or with an
absolute path. A file outside that directory matches none of its globs.
A severity is error, warning (or warn), or ignore (or off). Any key other than rules
and dialects, at the top or in a dialects entry, is a usage error, so a typo never goes
unnoticed.
Dialects
Each file is checked in the dialect its extension implies. --dialect or the config file can pick
another. JSONC, JWCC and JSON5 each add syntax to the one before. The exception is where a //
comment ends: JWCC ends it at LF only, JSONC also at a lone CR, and JSON5 also at U+2028 and
U+2029.
| Dialect | Adds to JSON | Default for |
|---|---|---|
json |
nothing (RFC 8259) | none; choose it with --dialect or --strict |
i-json |
stricter content (RFC 7493): lone surrogates, noncharacters and numbers a double cannot hold are errors | none |
jsonc |
// and /* */ comments |
.jsonc, .code-workspace, .code-snippets |
jwcc |
comments and trailing commas (HuJSON) | .hujson, .jwcc |
json5 |
the JSON5 1.0.0 grammar | .json, .json5, .geojson, .jsonld, .webmanifest, .babelrc |
jsonl |
one JSON value per line (JSON Lines) | .jsonl, .ndjson |
Any other extension is checked as JSON5. Extensions match in lower case only, so DATA.JSONL
is checked as JSON5, not JSON Lines.
.json defaults to JSON5 because most .json files that fail as JSON are config files with
comments. Hold the files a strict parser reads to JSON: --dialect json:package.json.
Rules
| Rule | Reports | Default |
|---|---|---|
syntax |
the first syntax error; checking stops there | error |
duplicate-key |
a key repeated in one object, with both positions and its path | error |
invalid-number |
a number a double cannot hold, or an integer past ±(2⁵³ − 1) | error in i-json, off elsewhere |
invalid-code-point |
a lone surrogate or a noncharacter in a string | error in i-json, off elsewhere |
byte-order-mark |
a byte order mark at the start of the file | warning in json and i-json, error in jsonl |
missing-final-newline |
a JSON Lines file that does not end with a newline | warning in jsonl |
Warnings fail a run only when there are more than --max-warnings N. A file jsonvet cannot read
is reported under unreadable. That is not a rule you can set: it always fails the run.
jsonvet escapes control, bidirectional and invisible characters in file names and messages, so no output line can drive a terminal or pass for a GitHub workflow command. The exact forms are in docs/design.md.
JSON Schema
--schema FILE checks each file's values against one JSON Schema. Each error is reported at the
line and column of its value, in every dialect, with comments and JSON5 syntax:
$ jsonvet --schema server.schema.json server.json5
server.json5:3:9: error[schema] "80" is not of type "integer" (at $.port)
server.json5:6:3: error[schema] Additional properties are not allowed ('debug' was unexpected) (at $.debug)
In the hook, give each schema its own entry, with files naming the files it covers:
- id: jsonvet
name: jsonvet (server schema)
files: ^config/server\.json5$
args: [--schema, schemas/server.schema.json]
Each message ends with the JSONPath of the value, written as duplicate-key paths are: $ is the
root, $.tags[1] an array element, $[""] the empty key. The rule id schema and the position
are stable. The message wording comes from the jsonschema crate and may change between releases.
Schema errors are always errors, in text, annotations and SARIF. --error, --warn, --ignore
and the config file do not take schema, and exit 2 if given it. The limits:
- Errors. A document lists at most 100 schema errors: the first 100 jsonschema finds, which
takes an object's keys in sorted order, not file order. They print in file order. Then one more
line,
... and N more schema errors in this document, sits at the document's start. SARIF leaves that line out.additionalPropertiesgives one error per key it does not allow, at that key, and each counts toward the 100. - Messages. A message quotes the value unless that makes it long; then it says
value. A message, with its path, is cut at 200 bytes and ends in.... - Depth. With
--schema, a file nested deeper than 512 levels is a syntax error. A file with a syntax error gets no schema errors. - Values. Each line of a JSON Lines file is checked on its own.
NaN,Infinityand numbers past a double's range have no JSON Schema value, so a document holding one is reported once and not checked. So is a document with two keys in one object that differ only in lone surrogates such as"\ud800", since both become U+FFFD. In the schema file, either is a usage error. - Memory. jsonvet holds each file's values in memory: 14 to 27 times the file's size, the
most for many small records such as JSON Lines. Without
--schema, memory stays near the file's size. - Regexes. A pattern with a back-reference or lookaround may backtrack 5,000 times per string.
A key or string that needs more is an error at that key or string: the pattern could not be
checked. jsonvet tries each
patternPropertiespattern on every key, and eachpatternon every string, so this error can name a string the pattern does not apply to. - The schema file. It may be in any dialect. Its
$schemapicks the draft, from draft 4 to 2020-12. A$refmust point inside the file: jsonvet fetches nothing, from the network or from disk. A schema jsonvet cannot read or use is a usage error (exit 2). That covers a$refto another file, and nesting deeper than 128 levels, where each$reffollowed counts as a level. It also covers a schema of more than 5,000,000 objects and arrays once each$refis replaced by what it points at, every time it is followed. SchemaStore's 1.6 MBazure-pipelines.jsoncomes to about 2,560,000. A$refback to a schema it is inside, as in{"items": {"$ref": "#"}}, is recursion and is fine: it is not followed again.
Why each limit exists: docs/design.md.
GitHub code scanning
--format sarif prints one SARIF 2.1.0
document instead of text lines, for GitHub code scanning and other tools. Each problem is a result
with its rule, severity, message and position, and a duplicate key also points at the first copy.
A file jsonvet cannot read is a result under the rule unreadable. The exit status and
--max-warnings work as with text, and no annotations are printed. GitHub keeps only 5,000
results of a run with more than 25,000, so jsonvet writes the first 25,000 and counts the rest in
a tool notification and on stderr.
jsonvet --format sarif $(git ls-files '*.json') > jsonvet.sarif
The Action's sarif input writes that file as well as the usual log and annotations. Upload it
with github/codeql-action/upload-sarif, which needs security-events: write:
jobs:
jsonvet:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: simonvanlierde/jsonvet@v3
with:
sarif: jsonvet.sarif
# Upload when jsonvet found problems too: that is when the step fails.
- uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
if: success() || failure()
with:
sarif_file: jsonvet.sarif
Coming from check-json5
Bump rev to the newest tag. The check-json5 hook id, the check-json5 command and --strict
keep working through 3.x, and the check-json5 package on PyPI now installs jsonvet.
For .json, .json5, .geojson, .jsonld, .webmanifest and .babelrc files, and in strict
mode, jsonvet gives the same pass or fail as 1.4.1, the same exit codes and the same duplicate-key
paths. The evidence, a comparison on 20,184 files, and the speed figures are in
docs/design.md.
One change can fail a file that passed: .jsonc, .code-workspace and .code-snippets files
are now checked as JSONC, and .hujson and .jwcc files as JWCC. 1.4.1 read every file as
JSON5, so JSON5-only syntax such as {'a': 1, b: 2} passed there. To keep the old verdict, pass
--dialect json5:GLOB or add a dialects entry to the config file. The output line, the
syntax-error wording, positions after a lone CR (or after U+2028 in JSON5), the new .jsonl and
.ndjson files and the removed Python module are in the
CHANGELOG under 2.0.0 and
3.0.0.
How it is tested
jsonvet runs the json5-tests suite, a snapshot of edge cases in every dialect, property tests, fuzzing, mutation testing and the comparison with check-json5 1.4.1, on Linux, macOS and Windows. A conformance matrix runs the same files against 17 other parsers in four languages. Details: docs/design.md.
| dialect | files | share of files where each parser gives the expected verdict |
|---|---|---|
| JSON5 | 166 | js-json5 100%, jsonvet-json5 100%, rs-json5 100%, py-json5 99%, py-pyjson5 99%, rs-serde-json5 94%, go-json5 91% |
| JSONC | 9 | js-jsonc-parser 100%, jsonvet-jsonc 100%, go-tidwall-jsonc 89%, js-strip-json-comments 89%, rs-jsonc-parser 78% |
| JWCC (HuJSON) | 10 | jsonvet-jwcc 100%, go-hujson 90% |
| JSON Lines | 11 | jsonvet-jsonl 100%, py-jsonlines 82%, go-json-stream 64%, rs-serde-json-stream 64% |
| Strict JSON (baseline) | 129 | js-json-parse 100%, jsonvet-json 100%, rs-serde-json 98%, py-json 96% |
Run on 2026-10-14. The full grid, and where each expected verdict comes from: docs/conformance.md.
Development
Clone with --recurse-submodules, run just setup once, and run just check before a pull
request. Setup, the checks, snapshots, fuzzing and releases are in
CONTRIBUTING.md.
Credits
I (Simon van Lierde) started this as a fork of check-json5 by Ben Mares, which is based on the pre-commit-hooks repository by Anthony Sottile and contributors.
License
MIT, like the projects it started from (Ben Mares, pre-commit-hooks).
Metadata
Release files for jsonvet 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jsonvet-3.0.0.tar.gz | 116.4 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| jsonvet-3.0.0-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| jsonvet-3.0.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| jsonvet-3.0.0-py3-none-musllinux_1_2_x86_64.whl | Python 3 | none | Linux musl 1.2+ x86-64 | Details |
| jsonvet-3.0.0-py3-none-musllinux_1_2_aarch64.whl | Python 3 | none | Linux musl 1.2+ ARM64 | Details |
| jsonvet-3.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| jsonvet-3.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| jsonvet-3.0.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| jsonvet-3.0.0-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
Total release size: 32.0 MB
Release files / jsonvet-3.0.0.tar.gz
| Download URL | jsonvet-3.0.0.tar.gz |
|---|---|
| Size | 116.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e44f1708b2cdd54b0f813db24dded0a1a7bbe0d17ba8dd6a67cd988bae6310e2
|
|
BLAKE2b-256 checksum How to use checksums |
744a688db7cecf5262e15eb44f076776cfe4d29f198ad233253b392e262b629c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-win_arm64.whl
| Download URL | jsonvet-3.0.0-py3-none-win_arm64.whl |
|---|---|
| Size | 3.5 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
6e0eb224d1790f5232bfb75f38c7d23ce602241c3d827e89cec5136c38a4460d
|
|
BLAKE2b-256 checksum How to use checksums |
76d8aad902d5786cb05c76896cf7a0332c4f0646527e4a6cb6d7d206764b796b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-win_amd64.whl
| Download URL | jsonvet-3.0.0-py3-none-win_amd64.whl |
|---|---|
| Size | 3.9 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
94b3c4cb10df05151a0041542c8c225c15730731f5f19eefa9927e4ee2c3462d
|
|
BLAKE2b-256 checksum How to use checksums |
ed16ba60b59ece3504398d61ae6b90513d59a63c027b1f3ab1a5dc84d3b9c264
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-musllinux_1_2_x86_64.whl
| Download URL | jsonvet-3.0.0-py3-none-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 4.5 MB |
| Tags | Linux musl 1.2+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
3c014ff2324198c4f0a95ad784e8ea206977ca14121ca19662da8adb1772379b
|
|
BLAKE2b-256 checksum How to use checksums |
5614faaa8addd8ba96838ce7cbb071c83884243b8a33224032f3629c6a064258
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-musllinux_1_2_aarch64.whl
| Download URL | jsonvet-3.0.0-py3-none-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 4.0 MB |
| Tags | Linux musl 1.2+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
8a458a8540b5314a470231217557aa01810026346bd3a29eeda32989afc0e122
|
|
BLAKE2b-256 checksum How to use checksums |
b01167f5af880c6029bddaeb33aaf391391649379ce71da72e690df64b5172f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | jsonvet-3.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
a2bc475e1e463ee4038c96f0415d585e1abe6a3f808094042e3e4cea7cf341f8
|
|
BLAKE2b-256 checksum How to use checksums |
475b8076db0e3aec3468aa5a852d1c96d754bb3808b67e6752e210acfc471a0c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | jsonvet-3.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 4.0 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
4698fbd6048e973ff0937554761bd883a1bf5a6ce30261c10e1d5379841bc572
|
|
BLAKE2b-256 checksum How to use checksums |
db2e947305d36e8781ad723c76286421328b19fa54d5f25a631a219e2047703a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-macosx_11_0_arm64.whl
| Download URL | jsonvet-3.0.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 3.6 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
0ba85d5a84cc5ccb1cb8d26bde569d23b4318c9cfd60f4342a929e33901b07e4
|
|
BLAKE2b-256 checksum How to use checksums |
50a5574abbd93379faf436ecdbdea14b59eea175141b7e571ec2700c0eafa7d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / jsonvet-3.0.0-py3-none-macosx_10_12_x86_64.whl
| Download URL | jsonvet-3.0.0-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
8d6634559f3627d07d9b733c93aedfc2dbcc476b06cf788a0efcdb857fa072be
|
|
BLAKE2b-256 checksum How to use checksums |
3348f4517107ec2a32845cb4871d1464810f97fc4083ab3737dad71f28a7c485
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency log