Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add @type_check_only to all Protocols and known stubs-only classes #1894

Merged
merged 1 commit into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion django-stubs/conf/__init__.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Literal
from typing import Any, Literal, type_check_only

from django.utils.functional import LazyObject
from typing_extensions import Self
Expand All @@ -11,6 +11,7 @@ DEFAULT_STORAGE_ALIAS: Literal["default"]
STATICFILES_STORAGE_ALIAS: Literal["staticfiles"]

# required for plugin to be able to distinguish this specific instance of LazySettings from others
@type_check_only
class _DjangoConfLazyObject(LazyObject):
def __getattr__(self, item: Any) -> Any: ...

Expand Down
3 changes: 2 additions & 1 deletion django-stubs/conf/global_settings.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ from re import Pattern

# This is defined here as a do-nothing function because we can't import
# django.utils.translation -- that module depends on the settings.
from typing import Any, Literal, Protocol
from typing import Any, Literal, Protocol, type_check_only

from typing_extensions import TypeAlias

Expand Down Expand Up @@ -86,6 +86,7 @@ SERVER_EMAIL: str
DATABASES: dict[str, dict[str, Any]]

# Classes used to implement DB routing behavior.
@type_check_only
class Router(Protocol):
def allow_migrate(self, db: str, app_label: str, **hints: Any) -> bool | None: ...

Expand Down
4 changes: 3 additions & 1 deletion django-stubs/contrib/admin/helpers.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from typing import Any
from typing import Any, type_check_only

from django import forms
from django.contrib.admin.options import ModelAdmin
Expand All @@ -21,6 +21,7 @@ class ActionForm(forms.Form):

checkbox: Any

@type_check_only
class _PrepopulatedDict(TypedDict):
field: BoundField
dependencies: list[BoundField]
Expand Down Expand Up @@ -92,6 +93,7 @@ class AdminField:
def label_tag(self) -> SafeString: ...
def errors(self) -> SafeString: ...

@type_check_only
class _FieldDictT(TypedDict):
name: str
label: str
Expand Down
4 changes: 3 additions & 1 deletion django-stubs/contrib/admin/options.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from typing import Any, Generic, Literal, TypeVar
from typing import Any, Generic, Literal, TypeVar, type_check_only

from django import forms
from django.contrib.admin.filters import FieldListFilter, ListFilter
Expand Down Expand Up @@ -52,10 +52,12 @@ csrf_protect_m: Any

_FieldGroups: TypeAlias = Sequence[str | Sequence[str]]

@type_check_only
class _OptionalFieldOpts(TypedDict, total=False):
classes: Sequence[str]
description: _StrOrPromise

@type_check_only
class _FieldOpts(_OptionalFieldOpts, total=True):
fields: _FieldGroups

Expand Down
3 changes: 2 additions & 1 deletion django-stubs/contrib/admin/utils.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
from collections import defaultdict
from collections.abc import Callable, Iterable, Sequence
from typing import Any, Literal, TypeVar, overload
from typing import Any, Literal, TypeVar, overload, type_check_only
from uuid import UUID

from _typeshed import Unused
Expand Down Expand Up @@ -59,6 +59,7 @@ class NestedObjects(Collector):
def nested(self, format_callback: Callable[[Model], _T]) -> list[_T]: ...
def can_fast_delete(self, *args: Unused, **kwargs: Unused) -> Literal[False]: ...

@type_check_only
class _ModelFormatDict(TypedDict):
verbose_name: str
verbose_name_plural: str
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/contrib/auth/password_validation.pyi
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from collections.abc import Mapping, Sequence
from pathlib import Path, PosixPath
from typing import Any, Protocol
from typing import Any, Protocol, type_check_only

from django.db.models.base import Model
from typing_extensions import TypeAlias

_UserModel: TypeAlias = Model

@type_check_only
class PasswordValidator(Protocol):
def validate(self, __password: str, __user: _UserModel | None = ...) -> None: ...
def get_help_text(self) -> str: ...
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/contrib/gis/geos/factory.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Any, Protocol
from typing import Any, Protocol, type_check_only

from django.contrib.gis.geos.geometry import GEOSGeometry

@type_check_only
class _Reader(Protocol):
def read(self) -> str | bytes: ...

Expand Down
3 changes: 2 additions & 1 deletion django-stubs/contrib/gis/utils/layermapping.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections.abc import Mapping
from pathlib import Path
from typing import Any, Protocol
from typing import Any, Protocol, type_check_only

from django.contrib.gis.gdal import DataSource, OGRGeomType
from django.contrib.gis.gdal.field import Field as OGRField
Expand All @@ -14,6 +14,7 @@ class InvalidDecimal(LayerMapError): ...
class InvalidInteger(LayerMapError): ...
class MissingForeignKey(LayerMapError): ...

@type_check_only
class _Writer(Protocol):
def write(self, __s: str) -> Any: ...

Expand Down
4 changes: 3 additions & 1 deletion django-stubs/core/checks/registry.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Callable, Iterable, Sequence
from typing import Any, Protocol, TypeVar, overload
from typing import Any, Protocol, TypeVar, overload, type_check_only

from django.apps.config import AppConfig
from django.core.checks.messages import CheckMessage
Expand All @@ -20,6 +20,7 @@ class Tags:
translation: str
urls: str

@type_check_only
class _CheckCallable(Protocol):
def __call__(
self,
Expand All @@ -31,6 +32,7 @@ class _CheckCallable(Protocol):

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

@type_check_only
class _ProcessedCheckCallable(Protocol[_C]):
tags: Sequence[str]
__call__: _C
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/core/paginator.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Iterable, Iterator, Sequence, Sized
from typing import ClassVar, Generic, Protocol, TypeVar, overload
from typing import ClassVar, Generic, Protocol, TypeVar, overload, type_check_only

from django.utils.functional import _StrPromise, cached_property

Expand All @@ -10,6 +10,7 @@ class EmptyPage(InvalidPage): ...

_T = TypeVar("_T")

@type_check_only
class _SupportsPagination(Protocol[_T], Sized, Iterable):
@overload
def __getitem__(self, __index: int) -> _T: ...
Expand Down
4 changes: 2 additions & 2 deletions django-stubs/core/signing.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import timedelta
from typing import Any, Protocol
from typing import Any, Protocol, type_check_only

class BadSignature(Exception): ...
class SignatureExpired(BadSignature): ...
Expand All @@ -8,7 +8,7 @@ def b64_encode(s: bytes) -> bytes: ...
def b64_decode(s: bytes) -> bytes: ...
def base64_hmac(salt: str, value: bytes | str, key: bytes | str, algorithm: str = ...) -> str: ...
def get_cookie_signer(salt: str = ...) -> TimestampSigner: ...

@type_check_only
class Serializer(Protocol):
def dumps(self, obj: Any) -> bytes: ...
def loads(self, data: bytes) -> Any: ...
Expand Down
4 changes: 3 additions & 1 deletion django-stubs/db/backends/ddl_references.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from collections.abc import Sequence
from typing import Any, Protocol
from typing import Any, Protocol, type_check_only

@type_check_only
class _QuoteCallable(Protocol):
"""Get rid of `cannot assign to method`"""

Expand Down Expand Up @@ -35,6 +36,7 @@ class Columns(TableColumns):
self, table: str, columns: list[str], quote_name: _QuoteCallable, col_suffixes: Sequence[str] = ...
) -> None: ...

@type_check_only
class _NameCallable(Protocol):
"""Get rid of `cannot assign to method`"""

Expand Down
3 changes: 2 additions & 1 deletion django-stubs/db/backends/utils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ from contextlib import contextmanager
from decimal import Decimal
from logging import Logger
from types import TracebackType
from typing import Any, Literal, Protocol, overload
from typing import Any, Literal, Protocol, overload, type_check_only
from uuid import UUID

from typing_extensions import Self, TypeAlias

logger: Logger

# Protocol matching psycopg2.sql.Composable, to avoid depending psycopg2
@type_check_only
class _Composable(Protocol):
def as_string(self, context: Any) -> str: ...
def __add__(self, other: Self) -> _Composable: ...
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/db/migrations/executor.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Sequence
from typing import Protocol
from typing import Protocol, type_check_only

from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.migrations.migration import Migration
Expand All @@ -8,6 +8,7 @@ from .loader import MigrationLoader
from .recorder import MigrationRecorder
from .state import ProjectState

@type_check_only
class _ProgressCallbackT(Protocol):
def __call__(self, __action: str, __migration: Migration | None = ..., __fake: bool | None = ...) -> None: ...

Expand Down
3 changes: 2 additions & 1 deletion django-stubs/db/migrations/operations/special.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Mapping, Sequence
from typing import Any, Literal, Protocol
from typing import Any, Literal, Protocol, type_check_only

from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.migrations.state import StateApps
Expand Down Expand Up @@ -35,6 +35,7 @@ class RunSQL(Operation):
@property
def reversible(self) -> bool: ... # type: ignore[override]

@type_check_only
class _CodeCallable(Protocol):
def __call__(self, __state_apps: StateApps, __schema_editor: BaseDatabaseSchemaEditor) -> None: ...

Expand Down
4 changes: 3 additions & 1 deletion django-stubs/db/models/enums.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import enum
import sys
from typing import Any, TypeVar
from typing import Any, TypeVar, type_check_only

from typing_extensions import Self

Expand Down Expand Up @@ -38,6 +38,7 @@ class Choices(enum.Enum, metaclass=ChoicesMeta):
def do_not_call_in_templates(self) -> bool: ...

# fake, to keep simulate class properties
@type_check_only
class _IntegerChoicesMeta(ChoicesMeta):
@property
def choices(self) -> list[tuple[int, str]]: ...
Expand All @@ -50,6 +51,7 @@ class IntegerChoices(int, Choices, metaclass=_IntegerChoicesMeta):
def value(self) -> int: ...

# fake, to keep simulate class properties
@type_check_only
class _TextChoicesMeta(ChoicesMeta):
@property
def choices(self) -> list[tuple[str, str]]: ...
Expand Down
4 changes: 3 additions & 1 deletion django-stubs/db/models/fields/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import uuid
from collections.abc import Callable, Iterable, Mapping, Sequence
from datetime import date, time, timedelta
from datetime import datetime as real_datetime
from typing import Any, ClassVar, Generic, Literal, Protocol, TypeVar, overload
from typing import Any, ClassVar, Generic, Literal, Protocol, TypeVar, overload, type_check_only

from django import forms
from django.core import validators # due to weird mypy.stubtest error
Expand Down Expand Up @@ -33,9 +33,11 @@ _LimitChoicesTo: TypeAlias = Q | dict[str, Any]

_F = TypeVar("_F", bound=Field, covariant=True)

@type_check_only
class _ChoicesCallable(Protocol):
def __call__(self) -> _FieldChoices: ...

@type_check_only
class _FieldDescriptor(Protocol[_F]):
"""
Accessing fields of a model class (not instance) returns an object conforming to this protocol.
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/db/models/fields/files.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Callable, Iterable
from typing import Any, Protocol, TypeVar, overload
from typing import Any, Protocol, TypeVar, overload, type_check_only

from django.core import validators # due to weird mypy.stubtest error
from django.core.files.base import File
Expand Down Expand Up @@ -37,6 +37,7 @@ class FileDescriptor(DeferredAttribute):

_M = TypeVar("_M", bound=Model, contravariant=True)

@type_check_only
class _UploadToCallable(Protocol[_M]):
def __call__(self, __instance: _M, __filename: str) -> _PathCompatible: ...

Expand Down
4 changes: 3 additions & 1 deletion django-stubs/db/models/fields/related_descriptors.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections.abc import Callable, Iterable
from typing import Any, Generic, NoReturn, TypeVar, overload
from typing import Any, Generic, NoReturn, TypeVar, overload, type_check_only

from django.core.exceptions import ObjectDoesNotExist
from django.db.models.base import Model
Expand Down Expand Up @@ -89,6 +89,7 @@ class ReverseManyToOneDescriptor:
def __set__(self, instance: Any, value: Any) -> NoReturn: ...

# Fake class, Django defines 'RelatedManager' inside a function body
@type_check_only
class RelatedManager(Manager[_M], Generic[_M]):
related_val: tuple[int, ...]
def add(self, *objs: _M | int, bulk: bool = ...) -> None: ...
Expand Down Expand Up @@ -131,6 +132,7 @@ class ManyToManyDescriptor(ReverseManyToOneDescriptor, Generic[_To, _Through]):
def __get__(self, instance: Model, cls: Any = ...) -> ManyRelatedManager[_To]: ...

# Fake class, Django defines 'ManyRelatedManager' inside a function body
@type_check_only
class ManyRelatedManager(Manager[_M], Generic[_M]):
related_val: tuple[int, ...]
def add(self, *objs: _M | int, bulk: bool = ...) -> None: ...
Expand Down
3 changes: 2 additions & 1 deletion django-stubs/forms/fields.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import datetime
from collections.abc import Collection, Iterator, Sequence
from decimal import Decimal
from re import Pattern
from typing import Any, Protocol
from typing import Any, Protocol, type_check_only
from uuid import UUID

from django.core.files import File
Expand Down Expand Up @@ -352,6 +352,7 @@ class ChoiceField(Field):
def validate(self, value: Any) -> None: ...
def valid_value(self, value: Any) -> bool: ...

@type_check_only
class _CoerceCallable(Protocol):
def __call__(self, __value: Any) -> Any: ...

Expand Down
4 changes: 2 additions & 2 deletions django-stubs/forms/widgets.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import datetime
from collections.abc import Iterable, Iterator, Mapping, Sequence
from typing import Any, Literal, Protocol
from typing import Any, Literal, Protocol, type_check_only

from django.core.files.base import File
from django.db.models.fields import _FieldChoices
Expand Down Expand Up @@ -137,7 +137,7 @@ class TimeInput(DateTimeBaseInput):
template_name: str

def boolean_check(v: Any) -> bool: ...

@type_check_only
class _CheckCallable(Protocol):
def __call__(self, __value: Any) -> bool: ...

Expand Down
4 changes: 3 additions & 1 deletion django-stubs/http/request.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from collections.abc import Iterable, Mapping
from io import BytesIO
from re import Pattern
from typing import Any, BinaryIO, Literal, NoReturn, TypeVar, overload
from typing import Any, BinaryIO, Literal, NoReturn, TypeVar, overload, type_check_only

from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import AnonymousUser
Expand Down Expand Up @@ -103,6 +103,7 @@ class HttpRequest(BytesIO):
def _load_post_and_files(self) -> None: ...
def accepts(self, media_type: str) -> bool: ...

@type_check_only
class _MutableHttpRequest(HttpRequest):
GET: QueryDict # type: ignore[assignment]
POST: QueryDict # type: ignore[assignment]
Expand Down Expand Up @@ -167,6 +168,7 @@ class QueryDict(MultiValueDict[str, str]):
def copy(self) -> QueryDict: ...
def urlencode(self, safe: str | None = ...) -> str: ...

@type_check_only
class _ImmutableQueryDict(QueryDict):
_mutable: Literal[False]
# def __init__(
Expand Down
Loading