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

Type django.utils.* against Django 4.2 #1575

Merged
merged 21 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions django-stubs/utils/autoreload.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import threading
import types
from collections.abc import Callable, Iterable, Iterator
from logging import Logger
from pathlib import Path
from typing import Any

Expand All @@ -11,6 +12,7 @@ from typing_extensions import ParamSpec

_P = ParamSpec("_P")

logger: Logger
autoreload_started: Signal
file_changed: Signal
DJANGO_AUTORELOAD_ENV: str
Expand Down
8 changes: 5 additions & 3 deletions django-stubs/utils/connection.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from collections.abc import Iterator, Mapping, Sequence
from typing import Any, Generic, TypeVar

from django.utils.functional import cached_property

class ConnectionProxy:
def __init__(self, connections: Mapping[str, Any], alias: str) -> None: ...
def __getattr__(self, item: str) -> Any: ...
Expand All @@ -17,13 +19,13 @@ class BaseConnectionHandler(Generic[_T]):
settings_name: str | None
exception_class: type[Exception]
thread_critical: bool
settings: cached_property[dict[str, Any]]
GabDug marked this conversation as resolved.
Show resolved Hide resolved
def __init__(self, settings: Any | None = ...) -> None: ...
@property
def settings(self) -> dict[str, Any]: ...
def configure_settings(self, settings: dict[str, Any] | None) -> dict[str, Any]: ...
def create_connection(self, alias: str) -> _T: ...
def __getitem__(self, alias: str) -> _T: ...
def __setitem__(self, key: str, value: _T) -> None: ...
def __delitem__(self, key: str) -> None: ...
def __iter__(self) -> Iterator[str]: ...
def all(self) -> Sequence[_T]: ...
def all(self, initialized_only: bool = ...) -> Sequence[_T]: ...
def close_all(self) -> None: ...
5 changes: 3 additions & 2 deletions django-stubs/utils/crypto.pyi
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from collections.abc import Callable
from hmac import HMAC

using_sysrandom: bool
RANDOM_STRING_CHARS: str

class InvalidAlgorithm(ValueError): ...

def salted_hmac(
key_salt: bytes | str, value: bytes | str, secret: bytes | str | None = ..., *, algorithm: str = ...
) -> HMAC: ...
def get_random_string(length: int = ..., allowed_chars: str = ...) -> str: ...
def get_random_string(length: int, allowed_chars: str = ...) -> str: ...
def constant_time_compare(val1: bytes | str, val2: bytes | str) -> bool: ...
def pbkdf2(
password: bytes | str,
Expand Down
11 changes: 7 additions & 4 deletions django-stubs/utils/datastructures.pyi
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from collections.abc import Collection, Iterable, Iterator, Mapping, MutableSet
from typing import Any, Generic, Protocol, Tuple, TypeVar, overload # noqa: Y022
from collections.abc import Collection, Iterable, Iterator, Mapping, MutableMapping, MutableSet
from typing import Any, Generic, NoReturn, Protocol, Tuple, TypeVar, overload # noqa: Y022

from _typeshed import Self
from _typeshed import Incomplete, Self
from typing_extensions import TypeAlias

_K = TypeVar("_K")
Expand Down Expand Up @@ -46,6 +46,7 @@ class OrderedSet(MutableSet[_K]):
def __init__(self, iterable: Iterable[_K] | None = ...) -> None: ...
def __contains__(self, item: object) -> bool: ...
def __iter__(self) -> Iterator[_K]: ...
def __reversed__(self) -> Iterator[_K]: ...
def __bool__(self) -> bool: ...
def __len__(self) -> int: ...
def add(self, item: _K) -> None: ...
Expand Down Expand Up @@ -83,11 +84,13 @@ class MultiValueDict(dict[_K, _V]):
def __iter__(self) -> Iterator[_K]: ...
# Fake to make `values` work properly
def values(self) -> Iterator[_V | list[object]]: ... # type: ignore[override]
def __copy__(self) -> MultiValueDict: ...
GabDug marked this conversation as resolved.
Show resolved Hide resolved
def __deepcopy__(self, memo: MutableMapping[int, Incomplete]) -> MultiValueDict: ...
GabDug marked this conversation as resolved.
Show resolved Hide resolved

class ImmutableList(tuple[_V, ...]):
warning: str
def __new__(cls: type[Self], *args: Any, warning: str = ..., **kwargs: Any) -> Self: ...
def complain(self, *args: Any, **kwargs: Any) -> None: ...
def complain(self, *args: Any, **kwargs: Any) -> NoReturn: ...

class _ItemCallable(Protocol[_V]):
"""Don't mess with arguments when assigning in class body in stub"""
Expand Down
10 changes: 7 additions & 3 deletions django-stubs/utils/datetime_safe.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ from datetime import date as real_date
from datetime import datetime as real_datetime
from datetime import time as real_time

class date(real_date): ...
class datetime(real_datetime): ...
class time(real_time): ...
class date(real_date):
def strftime(self, fmt: str) -> str: ...

class datetime(real_datetime):
def strftime(self, fmt: str) -> str: ...
@classmethod
def combine(cls, date: real_date, time: real_time) -> datetime: ... # type: ignore

def new_date(d: real_date) -> date: ...
def new_datetime(d: real_date | real_datetime) -> datetime: ...
Expand Down
5 changes: 2 additions & 3 deletions django-stubs/utils/decorators.pyi
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from collections.abc import Awaitable, Callable, Iterable
from typing import Protocol, TypeVar
from typing import Protocol, TypeVar, type_check_only

from django.http.request import HttpRequest
from django.http.response import HttpResponseBase
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import classproperty as classproperty
from django.views.generic.base import View

_T = TypeVar("_T", bound=View | Callable) # Any callable
Expand All @@ -16,7 +15,7 @@ def method_decorator(decorator: Callable | Iterable[Callable], name: str = ...)
def decorator_from_middleware_with_args(middleware_class: type) -> Callable: ...
def decorator_from_middleware(middleware_class: type) -> Callable: ...
def make_middleware_decorator(middleware_class: type[MiddlewareMixin]) -> Callable: ...

@type_check_only
GabDug marked this conversation as resolved.
Show resolved Hide resolved
class AsyncGetResponseCallable(Protocol):
def __call__(self, __request: HttpRequest) -> Awaitable[HttpResponseBase]: ...

Expand Down
16 changes: 11 additions & 5 deletions django-stubs/utils/deprecation.pyi
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from collections.abc import Callable
from typing import Any, Protocol
from typing import Any, Protocol, type_check_only

from django.http.request import HttpRequest
from django.http.response import HttpResponseBase
from typing_extensions import TypeAlias

class RemovedInDjango40Warning(DeprecationWarning): ...
class RemovedInDjango41Warning(PendingDeprecationWarning): ...
class RemovedInDjango50Warning(DeprecationWarning): ...
class RemovedInDjango51Warning(PendingDeprecationWarning): ...

RemovedInNextVersionWarning: TypeAlias = RemovedInDjango40Warning
RemovedInNextVersionWarning: TypeAlias = RemovedInDjango50Warning
RemovedAfterNextVersionWarning: TypeAlias = RemovedInDjango51Warning

class warn_about_renamed_method:
class_name: str
Expand All @@ -29,10 +30,15 @@ class DeprecationInstanceCheck(type):
deprecation_warning: type[Warning]
def __instancecheck__(self, instance: Any) -> bool: ...

@type_check_only
GabDug marked this conversation as resolved.
Show resolved Hide resolved
class GetResponseCallable(Protocol):
GabDug marked this conversation as resolved.
Show resolved Hide resolved
def __call__(self, __request: HttpRequest) -> HttpResponseBase: ...

class MiddlewareMixin:
sync_capable: bool
async_capable: bool

get_response: GetResponseCallable
def __init__(self, get_response: GetResponseCallable = ...) -> None: ...
def __init__(self, get_response: GetResponseCallable) -> None: ...
def __call__(self, request: HttpRequest) -> HttpResponseBase: ...
async def __acall__(self, request: HttpRequest) -> HttpResponseBase: ...
6 changes: 0 additions & 6 deletions django-stubs/utils/encoding.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ def smart_str(s: _PT, encoding: str = ..., strings_only: Literal[True] = ..., er
def smart_str(s: _S, encoding: str = ..., strings_only: bool = ..., errors: str = ...) -> _S: ...
@overload
def smart_str(s: Any, encoding: str = ..., strings_only: bool = ..., errors: str = ...) -> str: ...

smart_text = smart_str # Deprecated

def is_protected_type(obj: Any) -> TypeGuard[_PT]: ...
@overload
def force_str(s: _S, encoding: str = ..., *, errors: str = ...) -> _S: ...
Expand All @@ -40,9 +37,6 @@ def force_str(s: _PT, encoding: str = ..., strings_only: Literal[True] = ..., er
def force_str(s: _S, encoding: str = ..., strings_only: bool = ..., errors: str = ...) -> _S: ...
@overload
def force_str(s: Any, encoding: str = ..., strings_only: bool = ..., errors: str = ...) -> str: ...

force_text = force_str # Deprecated

@overload
def smart_bytes(s: _P, encoding: str = ..., strings_only: bool = ..., errors: str = ...) -> _P: ...
@overload
Expand Down
1 change: 1 addition & 0 deletions django-stubs/utils/feedgenerator.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class Enclosure:

class RssFeed(SyndicationFeed):
content_type: str
def rss_attributes(self) -> dict[str, str]: ...
def write_items(self, handler: ContentHandler) -> None: ...
def endChannelElement(self, handler: ContentHandler) -> None: ...

Expand Down
3 changes: 2 additions & 1 deletion django-stubs/utils/formats.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ FORMAT_SETTINGS: frozenset[str]

def reset_format_cache() -> None: ...
def iter_format_modules(lang: str, format_module_path: list[str] | str | None = ...) -> Iterator[types.ModuleType]: ...
def get_format_modules(lang: str | None = ..., reverse: bool = ...) -> list[types.ModuleType]: ...
def get_format_modules(lang: str | None = ...) -> list[types.ModuleType]: ...
def get_format(format_type: str, lang: str | None = ..., use_l10n: bool | None = ...) -> Any: ...

get_format_lazy: Any
Expand Down Expand Up @@ -42,3 +42,4 @@ def localize_input( # type: ignore
@overload
def localize_input(value: _T, default: str | None = ...) -> _T: ...
def sanitize_separators(value: _T) -> _T: ...
def sanitize_strftime_format(fmt: str) -> str: ...
17 changes: 12 additions & 5 deletions django-stubs/utils/functional.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ _T = TypeVar("_T")

class cached_property(Generic[_T]):
func: Callable[..., _T]
name: str
def __init__(self, func: Callable[..., _T], name: str = ...) -> None: ...
name: str | None
def __init__(self, func: Callable[..., _T], name: str | None = ...) -> None: ...
@overload
def __get__(self: Self, instance: None, cls: type[Any] = ...) -> Self: ...
def __get__(self: Self, instance: None, cls: type[Any] | None = ...) -> Self: ...
@overload
def __get__(self, instance: object, cls: type[Any] = ...) -> _T: ...
def __get__(self, instance: object, cls: type[Any] | None = ...) -> _T: ...
def __set_name__(self, owner: type[Any], name: str) -> None: ...

# Promise is only subclassed by a proxy class defined in the lazy function
# so it makes sense for it to have all the methods available in that proxy class
Expand Down Expand Up @@ -63,6 +64,7 @@ class LazyObject:
def __delattr__(self, name: str) -> None: ...
def __reduce__(self) -> tuple[Callable, tuple[Model]]: ...
def __copy__(self) -> LazyObject: ...
GabDug marked this conversation as resolved.
Show resolved Hide resolved
def __deepcopy__(self, memo: dict[int, Any]) -> LazyObject: ...
__bytes__: Callable
__bool__: Callable
__dir__: Callable
Expand All @@ -74,12 +76,17 @@ class LazyObject:
__iter__: Callable
__len__: Callable
__contains__: Callable
__gt__: Callable
__lt__: Callable
__add__: Callable
__str__: Callable[..., str]

def unpickle_lazyobject(wrapped: Model) -> Model: ...

class SimpleLazyObject(LazyObject):
def __init__(self, func: Callable[[], Any]) -> None: ...
def __copy__(self) -> SimpleLazyObject: ...
__radd__: Callable

_PartitionMember = TypeVar("_PartitionMember")

Expand All @@ -92,7 +99,7 @@ _Get = TypeVar("_Get", covariant=True)
class classproperty(Generic[_Get]):
fget: Callable[[Any], _Get] | None
def __init__(self, method: Callable[[Any], _Get] | None = ...) -> None: ...
def __get__(self, instance: Any | None, cls: type[Any] = ...) -> _Get: ...
def __get__(self, instance: Any | None, cls: type[Any] | None = ...) -> _Get: ...
def getter(self, method: Callable[[Any], _Get]) -> classproperty[_Get]: ...

class _Getter(Protocol[_Get]):
Expand Down
42 changes: 33 additions & 9 deletions django-stubs/utils/html.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ from json import JSONEncoder
from re import Pattern
from typing import Any

from django.utils.safestring import SafeString

TRAILING_PUNCTUATION_CHARS: str
WRAPPING_PUNCTUATION: list[tuple[str, str]]
DOTS: list[str]
word_split_re: Pattern[str]
simple_url_re: Pattern[str]
simple_url_2_re: Pattern[str]
from _typeshed import Incomplete
from django.utils.functional import SimpleLazyObject, _StrPromise
from django.utils.safestring import SafeData, SafeString

def escape(text: Any) -> SafeString: ...
def escapejs(value: Any) -> SafeString: ...
def json_script(value: Any, element_id: str | None = ..., encoder: type[JSONEncoder] | None = ...) -> SafeString: ...
def conditional_escape(text: Any) -> str: ...

# conditional_escape could use a protocol to be more precise, see https://github.com/typeddjango/django-stubs/issues/1474
def conditional_escape(text: _StrPromise | SafeData) -> SafeString: ...
def format_html(format_string: str, *args: Any, **kwargs: Any) -> SafeString: ...
def format_html_join(sep: str, format_string: str, args_generator: Iterable[Iterable[Any]]) -> SafeString: ...
def linebreaks(value: Any, autoescape: bool = ...) -> str: ...
Expand All @@ -35,3 +32,30 @@ def smart_urlquote(url: str) -> str: ...
def urlize(text: str, trim_url_limit: int | None = ..., nofollow: bool = ..., autoescape: bool = ...) -> str: ...
def avoid_wrapping(value: str) -> str: ...
def html_safe(klass: type) -> type: ...

class Urlizer:
trailing_punctuation_chars: str
wrapping_punctuation: Incomplete
word_split_re: Pattern[str] | SimpleLazyObject
simple_url_re: Pattern[str] | SimpleLazyObject
simple_url_2_re: Pattern[str] | SimpleLazyObject
mailto_template: str
url_template: str
def __call__(
self, text: Incomplete, trim_url_limit: Incomplete | None = ..., nofollow: bool = ..., autoescape: bool = ...
) -> Incomplete: ...
def handle_word(
self,
word: Incomplete,
*,
safe_input: Incomplete,
trim_url_limit: Incomplete | None = ...,
nofollow: bool = ...,
autoescape: bool = ...,
) -> Incomplete: ...
def trim_url(self, x: str, *, limit: int | None) -> Incomplete: ...
def trim_punctuation(self, word: str) -> tuple[str, str, str]: ...
@staticmethod
def is_email_simple(value: str) -> bool: ...

urlizer: Urlizer
15 changes: 1 addition & 14 deletions django-stubs/utils/http.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ ASCTIME_DATE: Pattern[str]
RFC3986_GENDELIMS: str
RFC3986_SUBDELIMS: str

def urlquote(url: str, safe: str = ...) -> str: ...
def urlquote_plus(url: str, safe: str = ...) -> str: ...
def urlunquote(quoted_url: str) -> str: ...
def urlunquote_plus(quoted_url: str) -> str: ...
def urlencode(
query: Mapping[str, str | bytes | int | Iterable[str | bytes | int]]
| Iterable[tuple[str, str | bytes | int | Iterable[str | bytes | int]]]
Expand All @@ -32,15 +28,6 @@ def is_same_domain(host: str, pattern: str) -> bool: ...
def url_has_allowed_host_and_scheme(
url: str | None, allowed_hosts: str | Iterable[str] | None, require_https: bool = ...
) -> bool: ...
def is_safe_url(url: str | None, allowed_hosts: str | Iterable[str] | None, require_https: bool = ...) -> bool: ...
def parse_qsl(
qs: str,
keep_blank_values: bool = ...,
strict_parsing: bool = ...,
encoding: str = ...,
errors: str = ...,
max_num_fields: int | None = ...,
separator: str = ...,
) -> list[tuple[str, str]]: ...
def escape_leading_slashes(url: str) -> str: ...
def content_disposition_header(as_attachment: bool, filename: str) -> str | None: ...
def parse_header_parameters(line: str) -> tuple[str, dict[str, str]]: ...
1 change: 1 addition & 0 deletions django-stubs/utils/module_loading.pyi
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Any

def cached_import(module_path: str, class_name: str) -> Any: ...
def import_string(dotted_path: str) -> Any: ...
def autodiscover_modules(*args: Any, **kwargs: Any) -> None: ...
def module_has_submodule(package: Any, module_name: str) -> bool: ...
Expand Down
5 changes: 2 additions & 3 deletions django-stubs/utils/text.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,17 @@ def get_text_list(list_: list[str], last_word: str = ...) -> str: ...
def get_text_list(list_: list[_StrOrPromise], last_word: _StrOrPromise = ...) -> _StrOrPromise: ...
def normalize_newlines(text: _StrOrPromiseT) -> _StrOrPromiseT: ...
def phone2numeric(phone: _StrOrPromiseT) -> _StrOrPromiseT: ...
def compress_string(s: bytes) -> bytes: ...
def compress_string(s: bytes, *, max_random_bytes: int | None = ...) -> bytes: ...

class StreamingBuffer(BytesIO):
vals: list[bytes]
def read(self) -> bytes: ... # type: ignore

def compress_sequence(sequence: Iterable[bytes]) -> Iterator[bytes]: ...
def compress_sequence(sequence: Iterable[bytes], *, max_random_bytes: int | None = ...) -> Iterator[bytes]: ...

smart_split_re: Pattern[str]

def smart_split(text: str) -> Iterator[str]: ...
def unescape_entities(text: _StrOrPromiseT) -> _StrOrPromiseT: ...
def unescape_string_literal(s: _StrOrPromiseT) -> _StrOrPromiseT: ...
def slugify(value: _StrOrPromiseT, allow_unicode: bool = ...) -> _StrOrPromiseT: ...
def camel_case_to_spaces(value: str) -> str: ...
Expand Down
5 changes: 3 additions & 2 deletions django-stubs/utils/timesince.pyi
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from datetime import date
from typing import Any

TIME_STRINGS: dict[str, str]
TIMESINCE_CHUNKS: Any
TIME_STRINGS_KEYS: list[str]
TIME_CHUNKS: list[int]
MONTHS_DAYS: tuple[int, ...]

def timesince(
d: date,
Expand Down
Loading