Skip to content

Commit

Permalink
Improve system check registry hints (#1249)
Browse files Browse the repository at this point in the history
* Improve system check registry hints

* Review comments

* Review comments & test tweaks

* Fix pre-commit checks

* fake commit to test CI

* Fix test

* Fix type of app_configs, expand test

Co-authored-by: Adam Johnson <[email protected]>
  • Loading branch information
intgr and adamchainz authored Jan 8, 2023
1 parent 6310e89 commit 8ade002
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
31 changes: 19 additions & 12 deletions django-stubs/core/checks/registry.pyi
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from collections.abc import Callable, Sequence
from typing import Any, Protocol, TypeVar
from collections.abc import Callable, Iterable, Sequence
from typing import Any, Protocol, TypeVar, overload

from django.apps.config import AppConfig
from django.core.checks.messages import CheckMessage
from typing_extensions import TypeAlias

class Tags:
admin: str
Expand All @@ -19,7 +18,14 @@ class Tags:
translation: str
urls: str

_CheckCallable: TypeAlias = Callable[..., Sequence[CheckMessage]]
class _CheckCallable(Protocol):
def __call__(
self,
*,
app_configs: Sequence[AppConfig] | None,
databases: Sequence[str] | None,
**kwargs: Any,
) -> Iterable[CheckMessage]: ...

_C = TypeVar("_C", bound=_CheckCallable)

Expand All @@ -31,21 +37,22 @@ class CheckRegistry:
registered_checks: set[_ProcessedCheckCallable]
deployment_checks: set[_ProcessedCheckCallable]
def __init__(self) -> None: ...
def register(
self, check: _CheckCallable | str | None = ..., *tags: str, **kwargs: Any
) -> Callable[[_CheckCallable], _ProcessedCheckCallable] | _ProcessedCheckCallable: ...
@overload
def register(self, __check: _C) -> _ProcessedCheckCallable[_C]: ...
@overload
def register(self, *tags: str, **kwargs: Any) -> Callable[[_C], _ProcessedCheckCallable[_C]]: ...
def run_checks(
self,
app_configs: Sequence[AppConfig] | None = ...,
tags: Sequence[str] | None = ...,
include_deployment_checks: bool = ...,
databases: Any | None = ...,
databases: Sequence[str] | None = ...,
) -> list[CheckMessage]: ...
def tag_exists(self, tag: str, include_deployment_checks: bool = ...) -> bool: ...
def tags_available(self, deployment_checks: bool = ...) -> set[str]: ...
def get_checks(self, include_deployment_checks: bool = ...) -> list[_ProcessedCheckCallable]: ...

registry: CheckRegistry
register: Any
run_checks: Any
tag_exists: Any
registry: CheckRegistry = ...
register = registry.register
run_checks = registry.run_checks
tag_exists = registry.tag_exists
29 changes: 29 additions & 0 deletions tests/typecheck/core/test_checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
- case: test_checks_register
main: |
from typing import Any, Sequence, Optional, Union
from django.apps.config import AppConfig
from django.core.checks import register, Warning, CheckMessage
@register("foo", deploy=True)
def check_foo(app_configs: Union[Sequence[AppConfig], None], databases: Optional[Sequence[str]], **kwargs: Any) -> list[Warning]:
if databases and 'databass' in databases:
return [Warning("Naughty list")]
return []
reveal_type(check_foo) # N: Revealed type is "django.core.checks.registry._ProcessedCheckCallable[def (app_configs: Union[typing.Sequence[django.apps.config.AppConfig], None], databases: Union[typing.Sequence[builtins.str], None], **kwargs: Any) -> builtins.list[django.core.checks.messages.Warning]]"
reveal_type(check_foo.tags) # N: Revealed type is "typing.Sequence[builtins.str]"
@register
def check_bar(*, app_configs: Union[Sequence[AppConfig], None], **kwargs: Any) -> Sequence[CheckMessage]: ...
reveal_type(check_bar) # N: Revealed type is "django.core.checks.registry._ProcessedCheckCallable[def (*, app_configs: Union[typing.Sequence[django.apps.config.AppConfig], None], **kwargs: Any) -> typing.Sequence[django.core.checks.messages.CheckMessage]]"
@register
def check_baz(**kwargs: Any) -> Sequence[CheckMessage]: ...
reveal_type(check_baz) # N: Revealed type is "django.core.checks.registry._ProcessedCheckCallable[def (**kwargs: Any) -> typing.Sequence[django.core.checks.messages.CheckMessage]]"
@register() # E: Value of type variable "_C" of function cannot be "Callable[[int], Sequence[CheckMessage]]"
def wrong_args(bla: int) -> Sequence[CheckMessage]: ...

0 comments on commit 8ade002

Please sign in to comment.