From 931af6d890c4e494827af1a136997473bbc4d34c Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Wed, 25 May 2022 16:00:24 +0000 Subject: [PATCH 1/2] Flesh out more of jsonschema stubs Apply more detailed annotations to the format module and most of the exceptions module. --- stubs/jsonschema/jsonschema/_format.pyi | 60 ++++++++++++---------- stubs/jsonschema/jsonschema/exceptions.pyi | 58 ++++++++++++--------- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/stubs/jsonschema/jsonschema/_format.pyi b/stubs/jsonschema/jsonschema/_format.pyi index 7a42455fbc4d..5a0ce6b745ad 100644 --- a/stubs/jsonschema/jsonschema/_format.pyi +++ b/stubs/jsonschema/jsonschema/_format.pyi @@ -1,13 +1,17 @@ -from collections.abc import Iterable -from typing import Any +from collections.abc import Callable, Iterable +from typing import Any, TypeVar + +_F = TypeVar("_F", bound=Callable[..., Any]) class FormatChecker: - checkers: Any + checkers: dict[str, tuple[Callable[[Any], bool], Exception | tuple[Exception, ...]]] + def __init__(self, formats: Iterable[str] | None = ...) -> None: ... - def checks(self, format, raises=...): ... - cls_checks: Any - def check(self, instance, format) -> None: ... - def conforms(self, instance, format) -> bool: ... + def checks(self, format: str, raises: Exception | tuple[Exception, ...] = ...) -> Callable[[_F], _F]: ... + @classmethod + def cls_checks(cls, format: str, raises: Exception | tuple[Exception, ...] = ...) -> Callable[[_F], _F]: ... + def check(self, instance: Any, format: str) -> None: ... + def conforms(self, instance: Any, format: str) -> bool: ... draft3_format_checker: FormatChecker draft4_format_checker: FormatChecker @@ -16,28 +20,28 @@ draft7_format_checker: FormatChecker draft201909_format_checker: FormatChecker draft202012_format_checker: FormatChecker -def is_email(instance) -> bool: ... -def is_ipv4(instance) -> bool: ... -def is_ipv6(instance) -> bool: ... +def is_email(instance: Any) -> bool: ... +def is_ipv4(instance: Any) -> bool: ... +def is_ipv6(instance: Any) -> bool: ... # is_host_name is only defined if fqdn is installed. -def is_host_name(instance) -> bool: ... -def is_idn_host_name(instance) -> bool: ... -def is_uri(instance) -> bool: ... -def is_uri_reference(instance) -> bool: ... -def is_iri(instance) -> bool: ... -def is_iri_reference(instance) -> bool: ... -def is_datetime(instance) -> bool: ... -def is_time(instance) -> bool: ... -def is_regex(instance) -> bool: ... -def is_date(instance) -> bool: ... -def is_draft3_time(instance) -> bool: ... -def is_css_color_code(instance) -> bool: ... -def is_css21_color(instance) -> bool: ... -def is_json_pointer(instance) -> bool: ... -def is_relative_json_pointer(instance) -> bool: ... -def is_uri_template(instance) -> bool: ... +def is_host_name(instance: Any) -> bool: ... +def is_idn_host_name(instance: Any) -> bool: ... +def is_uri(instance: Any) -> bool: ... +def is_uri_reference(instance: Any) -> bool: ... +def is_iri(instance: Any) -> bool: ... +def is_iri_reference(instance: Any) -> bool: ... +def is_datetime(instance: Any) -> bool: ... +def is_time(instance: Any) -> bool: ... +def is_regex(instance: Any) -> bool: ... +def is_date(instance: Any) -> bool: ... +def is_draft3_time(instance: Any) -> bool: ... +def is_css_color_code(instance: Any) -> bool: ... +def is_css21_color(instance: Any) -> bool: ... +def is_json_pointer(instance: Any) -> bool: ... +def is_relative_json_pointer(instance: Any) -> bool: ... +def is_uri_template(instance: Any) -> bool: ... # is_duration is only defined if isoduration is installed. -def is_duration(instance) -> bool: ... -def is_uuid(instance) -> bool: ... +def is_duration(instance: Any) -> bool: ... +def is_uuid(instance: Any) -> bool: ... diff --git a/stubs/jsonschema/jsonschema/exceptions.pyi b/stubs/jsonschema/jsonschema/exceptions.pyi index 466264dbbf0c..d1b1f87704ac 100644 --- a/stubs/jsonschema/jsonschema/exceptions.pyi +++ b/stubs/jsonschema/jsonschema/exceptions.pyi @@ -1,40 +1,50 @@ +from _typeshed import Self +from collections import deque +from collections.abc import Callable, Container, Iterable, Sequence from typing import Any -WEAK_MATCHES: Any -STRONG_MATCHES: Any +from jsonschema import _utils, protocols + +_RelevanceFuncType = Callable[[ValidationError], Any] + +WEAK_MATCHES: frozenset[str] +STRONG_MATCHES: frozenset[str] class _Error(Exception): - message: Any - path: Any - schema_path: Any - context: Any - cause: Any - validator: Any + message: str + path: deque[str] + relative_path: deque[str] + schema_path: deque[str] + relative_schema_path: deque[str] + context: list[ValidationError] | None + cause: Exception | None + validator: protocols.Validator | None validator_value: Any instance: Any schema: Any - parent: Any + parent: _Error | None def __init__( self, - message, - validator=..., - path=..., + message: str, + validator: _utils.Unset | None | protocols.Validator = ..., + path: Sequence[str] = ..., cause: Any | None = ..., - context=..., + context: Sequence[ValidationError] = ..., validator_value=..., - instance=..., - schema=..., - schema_path=..., - parent: Any | None = ..., + instance: Any = ..., + schema: Any = ..., + schema_path: Sequence[str] = ..., + parent: _Error | None = ..., ) -> None: ... @classmethod - def create_from(cls, other): ... + def create_from(cls: type[Self], other: _Error) -> Self: ... @property - def absolute_path(self): ... + def absolute_path(self) -> Sequence[str]: ... @property - def absolute_schema_path(self): ... + def absolute_schema_path(self) -> Sequence[str]: ... @property - def json_path(self): ... + def json_path(self) -> str: ... + def _contents(self) -> dict[str, Any]: ... class ValidationError(_Error): ... class SchemaError(_Error): ... @@ -68,8 +78,8 @@ class ErrorTree: @property def total_errors(self): ... -def by_relevance(weak=..., strong=...): ... +def by_relevance(weak: Container[str] = ..., strong: Container[str] = ...) -> _RelevanceFuncType: ... -relevance: Any +relevance: _RelevanceFuncType -def best_match(errors, key=...): ... +def best_match(errors: Iterable[ValidationError], key: _RelevanceFuncType = ...): ... From 8ddc5934d3e9d06ef24bb9ce0f0d27a783f09237 Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Fri, 27 May 2022 16:10:13 +0000 Subject: [PATCH 2/2] Adjustments to jsonschema types per review - is_X funcs are now `object -> bool`, not `Any -> bool` - _Error.contents has a TODO comment to use TypedDict - _RelevanceFuncType uses _typeshed.SupportsRichComparison --- stubs/jsonschema/jsonschema/_format.pyi | 42 +++++++++++----------- stubs/jsonschema/jsonschema/exceptions.pyi | 6 ++-- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/stubs/jsonschema/jsonschema/_format.pyi b/stubs/jsonschema/jsonschema/_format.pyi index 5a0ce6b745ad..36fa5dcf7e54 100644 --- a/stubs/jsonschema/jsonschema/_format.pyi +++ b/stubs/jsonschema/jsonschema/_format.pyi @@ -20,28 +20,28 @@ draft7_format_checker: FormatChecker draft201909_format_checker: FormatChecker draft202012_format_checker: FormatChecker -def is_email(instance: Any) -> bool: ... -def is_ipv4(instance: Any) -> bool: ... -def is_ipv6(instance: Any) -> bool: ... +def is_email(instance: object) -> bool: ... +def is_ipv4(instance: object) -> bool: ... +def is_ipv6(instance: object) -> bool: ... # is_host_name is only defined if fqdn is installed. -def is_host_name(instance: Any) -> bool: ... -def is_idn_host_name(instance: Any) -> bool: ... -def is_uri(instance: Any) -> bool: ... -def is_uri_reference(instance: Any) -> bool: ... -def is_iri(instance: Any) -> bool: ... -def is_iri_reference(instance: Any) -> bool: ... -def is_datetime(instance: Any) -> bool: ... -def is_time(instance: Any) -> bool: ... -def is_regex(instance: Any) -> bool: ... -def is_date(instance: Any) -> bool: ... -def is_draft3_time(instance: Any) -> bool: ... -def is_css_color_code(instance: Any) -> bool: ... -def is_css21_color(instance: Any) -> bool: ... -def is_json_pointer(instance: Any) -> bool: ... -def is_relative_json_pointer(instance: Any) -> bool: ... -def is_uri_template(instance: Any) -> bool: ... +def is_host_name(instance: object) -> bool: ... +def is_idn_host_name(instance: object) -> bool: ... +def is_uri(instance: object) -> bool: ... +def is_uri_reference(instance: object) -> bool: ... +def is_iri(instance: object) -> bool: ... +def is_iri_reference(instance: object) -> bool: ... +def is_datetime(instance: object) -> bool: ... +def is_time(instance: object) -> bool: ... +def is_regex(instance: object) -> bool: ... +def is_date(instance: object) -> bool: ... +def is_draft3_time(instance: object) -> bool: ... +def is_css_color_code(instance: object) -> bool: ... +def is_css21_color(instance: object) -> bool: ... +def is_json_pointer(instance: object) -> bool: ... +def is_relative_json_pointer(instance: object) -> bool: ... +def is_uri_template(instance: object) -> bool: ... # is_duration is only defined if isoduration is installed. -def is_duration(instance: Any) -> bool: ... -def is_uuid(instance: Any) -> bool: ... +def is_duration(instance: object) -> bool: ... +def is_uuid(instance: object) -> bool: ... diff --git a/stubs/jsonschema/jsonschema/exceptions.pyi b/stubs/jsonschema/jsonschema/exceptions.pyi index d1b1f87704ac..0c6fc5290a4b 100644 --- a/stubs/jsonschema/jsonschema/exceptions.pyi +++ b/stubs/jsonschema/jsonschema/exceptions.pyi @@ -1,11 +1,11 @@ -from _typeshed import Self +from _typeshed import Self, SupportsRichComparison from collections import deque from collections.abc import Callable, Container, Iterable, Sequence from typing import Any from jsonschema import _utils, protocols -_RelevanceFuncType = Callable[[ValidationError], Any] +_RelevanceFuncType = Callable[[ValidationError], SupportsRichComparison] WEAK_MATCHES: frozenset[str] STRONG_MATCHES: frozenset[str] @@ -44,6 +44,8 @@ class _Error(Exception): def absolute_schema_path(self) -> Sequence[str]: ... @property def json_path(self) -> str: ... + # TODO: this type could be made more precise using TypedDict to + # enumerate the types of the members def _contents(self) -> dict[str, Any]: ... class ValidationError(_Error): ...