You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Ship type stubs as a jsonpatch-stubs package - #249
mypy reports module is installed, but missing library stubs or py.typed marker for jsonpatch. PEP 561 has no py.typed marker for single-file modules, so this ships the types as a stub-only package, jsonpatch-stubs, inside the jsonpatch distribution. Type checkers pick it up automatically, and jsonpatch.py stays a single module without changes.
Changes
jsonpatch-stubs/__init__.pyi: stubs for the public API.
JSON documents are Any, since they can be any JSON value and the module accepts arbitrary Mapping / Sequence types, which a recursive JSON type would reject.
Patches are str | bytes | Iterable[Mapping[str, Any]].
from_string / from_diff return Self, so subclasses get instances of themselves.
DiffBuilder is typed loosely, as it is mostly an implementation detail.
setup.py: includes the stub package in the distribution and adds the Typing :: Typed classifier. MANIFEST.in adds the new type test to the sdist.
requirements.txt: requires jsonpointer>=3.8, the first jsonpointer release with type stubs, so JsonPointer and pointer_cls have real types.
pyproject.toml: mypy configuration (strict).
New CI job typing:
mypy.stubtest checks that the stubs agree with jsonpatch.py. It fails on missing names, mismatched parameters, or changed defaults.
mypy --strict type-checks typical usage (typetests/usage.py) against the installed distribution, including a custom JsonPointer subclass as pointer_cls. It also includes calls that must be rejected, marked with # type: ignore[...]; strict mode fails if they stop producing that error.
README.md: a short "Type hints" section, including a reminder to update the stubs when the API changes.
Testing
The built wheel and sdist contain jsonpatch-stubs/__init__.pyi, and twine check --strict passes.
mypy resolves import jsonpatch to the installed stubs, also with --python-version 3.10.
stubtest and the usage check pass with jsonpointer 3.8. With jsonpointer 3.7 (untyped), the usage check fails as expected.
tests.py (256 tests) and property_tests.py pass. flake8 passes.
Release notes
The third-party types-jsonpatch package on PyPI (2022 alpha releases) installs into the same jsonpatch-stubs/ directory and pins jsonpatch==1.32. Installing it downgrades jsonpatch, and uninstalling it deletes jsonpatch's own stubs. The release notes should tell users to uninstall it before upgrading.
mypy reported "module is installed, but missing library stubs or py.typed
marker" for jsonpatch. PEP 561 has no py.typed marker for single-file
modules, so the types are shipped as a stub-only package, jsonpatch-stubs,
in the same distribution, which type checkers pick up automatically. This
keeps jsonpatch.py a single module without annotations.
JSON documents are typed as Any, as they can be any JSON value and the
module accepts arbitrary Mapping / Sequence types. Patches are typed as
str | bytes | Iterable[Mapping[str, Any]].
A new CI job runs mypy's stubtest to check that the stubs agree with
jsonpatch.py, and type-checks typical usage (typetests/usage.py) against
the installed distribution with mypy --strict, including usage that must
be rejected.
Released jsonpointer versions are untyped, so pyproject.toml tells mypy to
ignore that; the stubs also pass against the typed jsonpointer from
stefankoegl/python-json-pointer#106.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pewzpj8LrcYUx1DeTxFCMg
jsonpointer 3.8 includes its own type stubs, so mypy no longer needs to
ignore it, and JsonPointer / pointer_cls in the jsonpatch stubs now have
real types instead of Any. The usage type test now also covers a custom
JsonPointer subclass as pointer_cls, and rejects a pointer_cls that is not
one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pewzpj8LrcYUx1DeTxFCMg
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The stub fails to explicitly re-export JsonPointer and omits JsonPointerException, causing type-checking errors for existing usage supported by the runtime module.
jsonpatch.py imports both from jsonpointer, so jsonpatch.JsonPointer and
jsonpatch.JsonPointerException work at runtime (ext_tests.py catches the
latter). In a .pyi file, imports are private unless re-exported with a
same-name alias, so type checkers rejected these uses. stubtest doesn't
notice, as it skips names defined in other modules, so the usage type
test now covers them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pewzpj8LrcYUx1DeTxFCMg
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The JsonPatch.from_string annotation omits bytearray, rejecting an input supported at runtime, and should include it in the parameter union.
No open issues 🎉
1 previously missed issue
In code that hasn't changed since last review
Include bytearray in the from_string input type
jsonpatch-stubs/__init__.pyi:106
The default JSON loader accepts bytearray, and from_string forwards its input unchanged, so JsonPatch.from_string(bytearray(b'[]')) works at runtime but is rejected by this annotation. Include bytearray in this parameter's union to preserve that supported input. apply_patch can retain its narrower union because it dispatches strings and bytes separately.
The default loader (json.loads) accepts bytearray, and from_string passes
its input on unchanged, so JsonPatch.from_string(bytearray(...)) works at
runtime. apply_patch keeps str | bytes: it treats a bytearray as a
sequence of operations and fails, so the usage test checks that type
checkers reject that.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pewzpj8LrcYUx1DeTxFCMg
Addressed the bytearray point from the latest review in ac82662: JsonPatch.from_string now accepts str | bytes | bytearray. apply_patch keeps str | bytes, since at runtime it treats a bytearray as a sequence of operations and raises InvalidJsonPatch; typetests/usage.py checks both.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #158.
mypy reports
module is installed, but missing library stubs or py.typed markerfor jsonpatch. PEP 561 has nopy.typedmarker for single-file modules, so this ships the types as a stub-only package,jsonpatch-stubs, inside the jsonpatch distribution. Type checkers pick it up automatically, andjsonpatch.pystays a single module without changes.Changes
jsonpatch-stubs/__init__.pyi: stubs for the public API.Any, since they can be any JSON value and the module accepts arbitraryMapping/Sequencetypes, which a recursive JSON type would reject.str | bytes | Iterable[Mapping[str, Any]].from_string/from_diffreturnSelf, so subclasses get instances of themselves.DiffBuilderis typed loosely, as it is mostly an implementation detail.setup.py: includes the stub package in the distribution and adds theTyping :: Typedclassifier.MANIFEST.inadds the new type test to the sdist.requirements.txt: requiresjsonpointer>=3.8, the first jsonpointer release with type stubs, soJsonPointerandpointer_clshave real types.pyproject.toml: mypy configuration (strict).typing:mypy.stubtestchecks that the stubs agree withjsonpatch.py. It fails on missing names, mismatched parameters, or changed defaults.mypy --stricttype-checks typical usage (typetests/usage.py) against the installed distribution, including a customJsonPointersubclass aspointer_cls. It also includes calls that must be rejected, marked with# type: ignore[...]; strict mode fails if they stop producing that error.README.md: a short "Type hints" section, including a reminder to update the stubs when the API changes.Testing
jsonpatch-stubs/__init__.pyi, andtwine check --strictpasses.import jsonpatchto the installed stubs, also with--python-version 3.10.tests.py(256 tests) andproperty_tests.pypass. flake8 passes.Release notes
The third-party
types-jsonpatchpackage on PyPI (2022 alpha releases) installs into the samejsonpatch-stubs/directory and pinsjsonpatch==1.32. Installing it downgrades jsonpatch, and uninstalling it deletes jsonpatch's own stubs. The release notes should tell users to uninstall it before upgrading.🤖 Generated with Claude Code
https://claude.ai/code/session_01Pewzpj8LrcYUx1DeTxFCMg