diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 50df175..6fedd8f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -54,6 +54,27 @@ jobs: - name: Check distributions run: twine check --strict dist/* + typing: + name: "Check type stubs" + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.13 + uses: actions/setup-python@v5 + with: + python-version: "3.13" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mypy . + - name: Run stubtest + # run outside the checkout so the installed module and stubs are used + working-directory: ${{ runner.temp }} + run: python -m mypy.stubtest jsonpointer + docs: name: "Build documentation" runs-on: ubuntu-latest diff --git a/MANIFEST.in b/MANIFEST.in index 0f9b9f6..0906a30 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,3 +2,4 @@ include AUTHORS include LICENSE.txt include README.md include tests.py +recursive-include jsonpointer-stubs *.pyi diff --git a/jsonpointer-stubs/__init__.pyi b/jsonpointer-stubs/__init__.pyi new file mode 100644 index 0000000..a011a88 --- /dev/null +++ b/jsonpointer-stubs/__init__.pyi @@ -0,0 +1,63 @@ +from collections.abc import Iterable, Iterator +from re import Pattern +from typing import Any, Final, TypeVar + +from typing_extensions import Self + +_T = TypeVar("_T") + +__author__: Final[str] +__version__: Final[str] +__website__: Final[str] +__license__: Final[str] + +VERBOSE_EXCEPTIONS: bool + +def set_pointer( + doc: Any, + pointer: str, + value: Any, + inplace: bool = True, + create: bool = False, +) -> Any: ... +def resolve_pointer(doc: Any, pointer: str, default: Any = ...) -> Any: ... +def pairwise(iterable: Iterable[_T]) -> Iterator[tuple[_T, _T]]: ... + +class JsonPointerException(Exception): ... + +class EndOfList: + list_: Any + def __init__(self, list_: Any) -> None: ... + +class JsonPointer: + _RE_ARRAY_INDEX: Pattern[str] + _RE_INVALID_ESCAPE: Pattern[str] + parts: list[str] + def __init__(self, pointer: str) -> None: ... + def to_last(self, doc: Any) -> tuple[Any, str | int | None]: ... + def resolve(self, doc: Any, default: Any = ...) -> Any: ... + def get(self, doc: Any, default: Any = ...) -> Any: ... + def set( + self, + doc: Any, + value: Any, + inplace: bool = True, + create: bool = False, + ) -> Any: ... + @classmethod + def get_part(cls, doc: Any, part: str | int) -> str | int: ... + def get_parts(self) -> list[str]: ... + def walk(self, doc: Any, part: str | int) -> Any: ... + def contains(self, ptr: JsonPointer) -> bool: ... + def __contains__(self, item: JsonPointer) -> bool: ... + def join(self, suffix: JsonPointer | str | Iterable[object]) -> Self: ... + def __truediv__(self, suffix: JsonPointer | str | Iterable[object]) -> Self: ... + @property + def path(self) -> str: ... + def __eq__(self, other: object) -> bool: ... + def __hash__(self) -> int: ... + @classmethod + def from_parts(cls, parts: Iterable[object]) -> Self: ... + +def escape(s: str) -> str: ... +def unescape(s: str) -> str: ... diff --git a/setup.py b/setup.py index 26f34ee..785d397 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,7 @@ 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries', 'Topic :: Utilities', + 'Typing :: Typed', ] setup( @@ -60,6 +61,9 @@ license=LICENSE, url=WEBSITE, py_modules=MODULES, + # PEP 561 stub-only package, shipped in the same distribution + packages=['jsonpointer-stubs'], + package_data={'jsonpointer-stubs': ['__init__.pyi']}, scripts=['bin/jsonpointer'], classifiers=CLASSIFIERS, python_requires='>=3.10',