Broaden type annotation for verbose_name(_plural) to accept lazystr. (#1139)

* Broaden type annotation for verbose_name(_plural) to accept lazystr.

Fixes #1137.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>

* Broaden type annotation for help_text to accept lazystr.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>

* Broaden type annotation for ValidationError to accept lazystr.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>

* Broaden type annotation for label to accept lazystr.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>

* Add StrPromise and StrOrPromise aliases to django_stubs_ext.

We make StrPromise and StrOrPromise available via django_stubs_ext so
that conditional imports with TYPE_CHECKING is not required.
These aliases fall back to Promise or Union[str, Promise]
when not TYPE_CHECKING.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
This commit is contained in:
PIG208
2022-09-19 10:01:44 -04:00
committed by GitHub
parent a2a3543198
commit 9a41aa63ba
19 changed files with 138 additions and 104 deletions

View File

@@ -3,6 +3,7 @@ from typing import Dict, Iterator, Optional, Type
from django.apps.registry import Apps
from django.db.models.base import Model
from django.utils.functional import _StrOrPromise
MODELS_MODULE_NAME: str
@@ -11,7 +12,7 @@ class AppConfig:
module: Optional[types.ModuleType] = ...
apps: Optional[Apps] = ...
label: str = ...
verbose_name: str = ...
verbose_name: _StrOrPromise = ...
path: str = ...
models_module: Optional[str] = ...
models: Dict[str, Type[Model]] = ...

View File

@@ -41,6 +41,7 @@ from django.http.response import HttpResponse, HttpResponseRedirect, JsonRespons
from django.template.response import _TemplateForResponseT
from django.urls.resolvers import URLPattern
from django.utils.datastructures import _ListOrTuple
from django.utils.functional import _StrOrPromise
from django.utils.safestring import SafeString
from typing_extensions import Literal, TypedDict
@@ -296,8 +297,8 @@ class InlineModelAdmin(Generic[_ChildModelT, _ParentModelT], BaseModelAdmin[_Chi
min_num: Optional[int] = ...
max_num: Optional[int] = ...
template: str = ...
verbose_name: Optional[str] = ...
verbose_name_plural: Optional[str] = ...
verbose_name: Optional[_StrOrPromise] = ...
verbose_name_plural: Optional[_StrOrPromise] = ...
can_delete: bool = ...
show_change_link: bool = ...
classes: Optional[Sequence[str]] = ...

View File

@@ -11,7 +11,7 @@ from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.template.response import TemplateResponse
from django.urls import URLPattern, URLResolver
from django.utils.functional import LazyObject
from django.utils.functional import LazyObject, _StrOrPromise
if sys.version_info >= (3, 9):
from weakref import WeakSet
@@ -77,7 +77,7 @@ class AdminSite:
def i18n_javascript(self, request: HttpRequest, extra_context: Optional[Dict[str, Any]] = ...) -> HttpResponse: ...
def logout(self, request: HttpRequest, extra_context: Optional[Dict[str, Any]] = ...) -> TemplateResponse: ...
def login(self, request: HttpRequest, extra_context: Optional[Dict[str, Any]] = ...) -> HttpResponse: ...
def _build_app_dict(self, request: HttpRequest, label: Optional[str] = ...) -> Dict[str, Any]: ...
def _build_app_dict(self, request: HttpRequest, label: Optional[_StrOrPromise] = ...) -> Dict[str, Any]: ...
def get_app_list(self, request: HttpRequest) -> List[Any]: ...
def index(self, request: HttpRequest, extra_context: Optional[Dict[str, Any]] = ...) -> TemplateResponse: ...
def app_index(

View File

@@ -7,12 +7,17 @@ from django.db.models.fields import _FieldChoices
from django.db.models.fields.reverse_related import ForeignObjectRel, ManyToManyRel, ManyToOneRel
from django.forms.models import ModelChoiceIterator
from django.forms.widgets import Media, _OptAttrs
from django.utils.functional import _StrOrPromise
class FilteredSelectMultiple(forms.SelectMultiple):
verbose_name: str = ...
verbose_name: _StrOrPromise = ...
is_stacked: bool = ...
def __init__(
self, verbose_name: str, is_stacked: bool, attrs: Optional[_OptAttrs] = ..., choices: _FieldChoices = ...
self,
verbose_name: _StrOrPromise,
is_stacked: bool,
attrs: Optional[_OptAttrs] = ...,
choices: _FieldChoices = ...,
) -> None: ...
class AdminDateWidget(forms.DateInput):

View File

@@ -2,6 +2,7 @@ from typing import Any, Iterable, NamedTuple, Optional, Tuple, TypeVar, Union
from django.core.validators import _ValidatorCallable
from django.db.models.fields import Field, _ErrorMessagesT, _FieldChoices
from django.utils.functional import _StrOrPromise
# __set__ value type
_ST = TypeVar("_ST")
@@ -19,7 +20,7 @@ def get_srid_info(srid: int, connection: Any) -> SRIDCacheEntry: ...
class BaseSpatialField(Field[_ST, _GT]):
def __init__(
self,
verbose_name: Optional[Union[str, bytes]] = ...,
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
srid: int = ...,
spatial_index: bool = ...,
*,
@@ -38,7 +39,7 @@ class BaseSpatialField(Field[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[_ValidatorCallable] = ...,
@@ -65,7 +66,7 @@ class GeometryField(BaseSpatialField):
geography: Any = ...
def __init__(
self,
verbose_name: Optional[Union[str, bytes]] = ...,
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
dim: int = ...,
geography: bool = ...,
*,
@@ -88,7 +89,7 @@ class GeometryField(BaseSpatialField):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[_ValidatorCallable] = ...,

View File

@@ -5,6 +5,7 @@ from django.db.models import Field, Transform
from django.db.models.expressions import Combinable
from django.db.models.fields import _ErrorMessagesT, _FieldChoices
from django.db.models.fields.mixins import CheckFieldDefaultMixin
from django.utils.functional import _StrOrPromise
# __set__ value type
_ST = TypeVar("_ST")
@@ -42,7 +43,7 @@ class ArrayField(CheckFieldDefaultMixin, Field[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[_ValidatorCallable] = ...,

View File

@@ -1,13 +1,14 @@
from typing import Any, Dict
from django.core.cache.backends.base import BaseCache
from django.utils.functional import _StrOrPromise
class Options:
db_table: str = ...
app_label: str = ...
model_name: str = ...
verbose_name: str = ...
verbose_name_plural: str = ...
verbose_name: _StrOrPromise = ...
verbose_name_plural: _StrOrPromise = ...
object_name: str = ...
abstract: bool = ...
managed: bool = ...

View File

@@ -1,5 +1,6 @@
from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
from django.utils.functional import _StrPromise
from typing_extensions import Literal
class FieldDoesNotExist(Exception): ...
@@ -35,7 +36,7 @@ class ValidationError(Exception):
def __init__(
self,
# Accepts arbitrarily nested data structure, mypy doesn't allow describing it accurately.
message: Union[str, ValidationError, Dict[str, Any], List[Any]],
message: Union[str, _StrPromise, ValidationError, Dict[str, Any], List[Any]],
code: Optional[str] = ...,
params: Optional[Dict[str, Any]] = ...,
) -> None: ...

View File

@@ -30,7 +30,7 @@ from django.db.models.query_utils import Q, RegisterLookupMixin
from django.forms import Field as FormField
from django.forms import Widget
from django.utils.datastructures import DictWrapper
from django.utils.functional import _Getter
from django.utils.functional import _Getter, _StrOrPromise
from typing_extensions import Protocol
class Empty: ...
@@ -120,7 +120,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
_pyi_lookup_exact_type: Any
widget: Widget
help_text: str
help_text: _StrOrPromise
attname: str
auto_created: bool
primary_key: bool
@@ -134,7 +134,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
max_length: Optional[int]
model: Type[Model]
name: str
verbose_name: str
verbose_name: _StrOrPromise
description: Union[str, _Getter[str]]
blank: bool
null: bool
@@ -158,7 +158,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
non_db_attrs: Tuple[str, ...]
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
max_length: Optional[int] = ...,
@@ -174,7 +174,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
auto_created: bool = ...,
@@ -260,7 +260,7 @@ class DecimalField(Field[_ST, _GT]):
decimal_places: int = ...
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
max_digits: Optional[int] = ...,
decimal_places: Optional[int] = ...,
@@ -275,7 +275,7 @@ class DecimalField(Field[_ST, _GT]):
auto_created: bool = ...,
serialize: bool = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -289,7 +289,7 @@ class CharField(Field[_ST, _GT]):
_pyi_lookup_exact_type: Any
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
max_length: Optional[int] = ...,
@@ -305,7 +305,7 @@ class CharField(Field[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -319,7 +319,7 @@ class CommaSeparatedIntegerField(CharField[_ST, _GT]): ...
class SlugField(CharField[_ST, _GT]):
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
unique: bool = ...,
@@ -333,7 +333,7 @@ class SlugField(CharField[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -349,7 +349,7 @@ class EmailField(CharField[_ST, _GT]): ...
class URLField(CharField[_ST, _GT]):
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
*,
primary_key: bool = ...,
@@ -366,7 +366,7 @@ class URLField(CharField[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
auto_created: bool = ...,
@@ -381,7 +381,7 @@ class TextField(Field[_ST, _GT]):
_pyi_lookup_exact_type: Any
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
max_length: Optional[int] = ...,
@@ -397,7 +397,7 @@ class TextField(Field[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -443,7 +443,7 @@ class GenericIPAddressField(Field[_ST, _GT]):
auto_created: bool = ...,
serialize: bool = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -458,7 +458,7 @@ class DateField(DateTimeCheckMixin, Field[_ST, _GT]):
_pyi_lookup_exact_type: Union[str, date]
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
auto_now: bool = ...,
auto_now_add: bool = ...,
@@ -474,7 +474,7 @@ class DateField(DateTimeCheckMixin, Field[_ST, _GT]):
auto_created: bool = ...,
serialize: bool = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -486,7 +486,7 @@ class TimeField(DateTimeCheckMixin, Field[_ST, _GT]):
_pyi_private_get_type: time
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
auto_now: bool = ...,
auto_now_add: bool = ...,
@@ -501,7 +501,7 @@ class TimeField(DateTimeCheckMixin, Field[_ST, _GT]):
auto_created: bool = ...,
serialize: bool = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -518,7 +518,7 @@ class UUIDField(Field[_ST, _GT]):
_pyi_private_get_type: uuid.UUID
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
*,
name: Optional[str] = ...,
primary_key: bool = ...,
@@ -535,7 +535,7 @@ class UUIDField(Field[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
auto_created: bool = ...,
@@ -551,7 +551,7 @@ class FilePathField(Field[_ST, _GT]):
allow_folders: bool = ...
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
path: Union[str, Callable[..., str]] = ...,
match: Optional[str] = ...,
@@ -570,7 +570,7 @@ class FilePathField(Field[_ST, _GT]):
auto_created: bool = ...,
serialize: bool = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,

View File

@@ -8,6 +8,7 @@ from django.db.models.base import Model
from django.db.models.fields import Field, _ErrorMessagesT, _FieldChoices
from django.db.models.query_utils import DeferredAttribute
from django.utils._os import _PathCompatible
from django.utils.functional import _StrOrPromise
from typing_extensions import Protocol
class FieldFile(File):
@@ -46,7 +47,7 @@ class FileField(Field):
upload_to: Union[_PathCompatible, _UploadToCallable] = ...
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
upload_to: Union[_PathCompatible, _UploadToCallable] = ...,
storage: Optional[Union[Storage, Callable[[], Storage]]] = ...,
@@ -64,7 +65,7 @@ class FileField(Field):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -92,7 +93,7 @@ class ImageFieldFile(ImageFile, FieldFile):
class ImageField(FileField):
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
width_field: Optional[str] = ...,
height_field: Optional[str] = ...,

View File

@@ -5,6 +5,7 @@ from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.models import lookups
from django.db.models.lookups import PostgresOperatorLookup, Transform
from django.db.models.sql.compiler import SQLCompiler
from django.utils.functional import _StrOrPromise
from . import Field
from .mixins import CheckFieldDefaultMixin
@@ -14,7 +15,7 @@ class JSONField(CheckFieldDefaultMixin, Field):
decoder: Optional[Type[json.JSONDecoder]]
def __init__(
self,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
encoder: Optional[Type[json.JSONEncoder]] = ...,
decoder: Optional[Type[json.JSONDecoder]] = ...,

View File

@@ -20,6 +20,7 @@ from django.db.models.fields.reverse_related import ManyToOneRel as ManyToOneRel
from django.db.models.fields.reverse_related import OneToOneRel as OneToOneRel
from django.db.models.manager import RelatedManager
from django.db.models.query_utils import FilteredRelation, PathInfo, Q
from django.utils.functional import _StrOrPromise
from typing_extensions import Literal
_T = TypeVar("_T", bound=models.Model)
@@ -75,7 +76,7 @@ class ForeignObject(RelatedField[_ST, _GT]):
swappable: bool = ...,
*,
db_constraint: bool = ...,
verbose_name: Optional[str] = ...,
verbose_name: Optional[_StrOrPromise] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
unique: bool = ...,
@@ -87,7 +88,7 @@ class ForeignObject(RelatedField[_ST, _GT]):
auto_created: bool = ...,
serialize: bool = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -120,7 +121,7 @@ class ForeignKey(ForeignObject[_ST, _GT]):
to_field: Optional[str] = ...,
db_constraint: bool = ...,
*,
verbose_name: Optional[Union[str, bytes]] = ...,
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
max_length: Optional[int] = ...,
@@ -136,7 +137,7 @@ class ForeignKey(ForeignObject[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -169,7 +170,7 @@ class OneToOneField(ForeignKey[_ST, _GT]):
limit_choices_to: Optional[_AllLimitChoicesTo] = ...,
parent_link: bool = ...,
db_constraint: bool = ...,
verbose_name: Optional[Union[str, bytes]] = ...,
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
max_length: Optional[int] = ...,
@@ -185,7 +186,7 @@ class OneToOneField(ForeignKey[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,
@@ -229,7 +230,7 @@ class ManyToManyField(RelatedField[_ST, _GT]):
db_table: Optional[str] = ...,
swappable: bool = ...,
*,
verbose_name: Optional[Union[str, bytes]] = ...,
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
name: Optional[str] = ...,
primary_key: bool = ...,
max_length: Optional[int] = ...,
@@ -245,7 +246,7 @@ class ManyToManyField(RelatedField[_ST, _GT]):
unique_for_month: Optional[str] = ...,
unique_for_year: Optional[str] = ...,
choices: Optional[_FieldChoices] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
db_column: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
validators: Iterable[validators._ValidatorCallable] = ...,

View File

@@ -12,6 +12,7 @@ from django.db.models.fields.reverse_related import ForeignObjectRel
from django.db.models.manager import Manager
from django.db.models.query_utils import PathInfo
from django.utils.datastructures import ImmutableList, _ListOrTuple
from django.utils.functional import _StrOrPromise
from typing_extensions import Literal
PROXY_PARENTS: object
@@ -46,8 +47,8 @@ class Options(Generic[_M]):
base_manager_name: Optional[str] = ...
default_manager_name: Optional[str] = ...
model_name: Optional[str] = ...
verbose_name: Optional[str] = ...
verbose_name_plural: Optional[str] = ...
verbose_name: Optional[_StrOrPromise] = ...
verbose_name_plural: Optional[_StrOrPromise] = ...
db_table: str = ...
ordering: Optional[Sequence[str]] = ...
indexes: List[Any] = ...

View File

@@ -5,6 +5,7 @@ from django.forms.forms import BaseForm
from django.forms.renderers import BaseRenderer
from django.forms.utils import ErrorList
from django.forms.widgets import Widget
from django.utils.functional import _StrOrPromise
from django.utils.safestring import SafeString
_AttrsT = Dict[str, Union[str, bool]]
@@ -16,8 +17,8 @@ class BoundField:
html_name: str = ...
html_initial_name: str = ...
html_initial_id: str = ...
label: str = ...
help_text: str = ...
label: _StrOrPromise = ...
help_text: _StrOrPromise = ...
def __init__(self, form: BaseForm, field: Field, name: str) -> None: ...
@property
def subwidgets(self) -> List[BoundWidget]: ...

View File

@@ -10,6 +10,7 @@ from django.forms.boundfield import BoundField
from django.forms.forms import BaseForm
from django.forms.widgets import ChoiceWidget, Widget
from django.utils.datastructures import _PropertyDescriptor
from django.utils.functional import _StrOrPromise
# Problem: attribute `widget` is always of type `Widget` after field instantiation.
# However, on class level it can be set to `Type[Widget]` too.
@@ -22,7 +23,7 @@ _ClassLevelWidgetT = Any
class Field:
initial: Any
label: Optional[str]
label: Optional[_StrOrPromise]
required: bool
widget: _ClassLevelWidgetT = ...
hidden_widget: Type[Widget] = ...
@@ -30,7 +31,7 @@ class Field:
default_error_messages: _ErrorMessagesT = ...
empty_values: Sequence[Any] = ...
show_hidden_initial: bool = ...
help_text: str = ...
help_text: _StrOrPromise = ...
disabled: bool = ...
label_suffix: Optional[str] = ...
localize: bool = ...
@@ -42,9 +43,9 @@ class Field:
*,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -77,9 +78,9 @@ class CharField(Field):
empty_value: Optional[str] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -101,9 +102,9 @@ class IntegerField(Field):
min_value: Optional[int] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -122,9 +123,9 @@ class FloatField(IntegerField):
min_value: Union[int, float, None] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -148,9 +149,9 @@ class DecimalField(IntegerField):
decimal_places: Optional[int] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -170,9 +171,9 @@ class BaseTemporalField(Field):
input_formats: Optional[Any] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -214,9 +215,9 @@ class RegexField(CharField):
empty_value: Optional[str] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -235,9 +236,9 @@ class EmailField(CharField):
empty_value: Optional[str] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -255,9 +256,9 @@ class FileField(Field):
allow_empty_file: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -284,9 +285,9 @@ class URLField(CharField):
empty_value: Optional[str] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -322,9 +323,9 @@ class ChoiceField(Field):
choices: Union[_FieldChoices, _ChoicesCallable] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -352,9 +353,9 @@ class TypedChoiceField(ChoiceField):
choices: Union[_FieldChoices, _ChoicesCallable] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -380,9 +381,9 @@ class TypedMultipleChoiceField(MultipleChoiceField):
choices: Union[_FieldChoices, _ChoicesCallable] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -401,9 +402,9 @@ class ComboField(Field):
*,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -423,9 +424,9 @@ class MultiValueField(Field):
require_all_fields: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -456,9 +457,9 @@ class FilePathField(ChoiceField):
choices: Union[_FieldChoices, _ChoicesCallable] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -477,9 +478,9 @@ class SplitDateTimeField(MultiValueField):
require_all_fields: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -498,9 +499,9 @@ class GenericIPAddressField(CharField):
unpack_ipv4: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,
@@ -522,9 +523,9 @@ class SlugField(CharField):
empty_value: Optional[str] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
error_messages: Optional[_ErrorMessagesT] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[_ValidatorCallable] = ...,

View File

@@ -33,6 +33,7 @@ from django.forms.renderers import BaseRenderer
from django.forms.utils import ErrorList, _DataT, _FilesT
from django.forms.widgets import ChoiceWidget, Input, Widget
from django.utils.datastructures import _IndexableCollection, _ListOrTuple, _PropertyDescriptor
from django.utils.functional import _StrOrPromise
from typing_extensions import Literal
ALL_FIELDS: Literal["__all__"]
@@ -233,7 +234,7 @@ def inlineformset_factory(
class InlineForeignKeyField(Field):
disabled: bool
help_text: str
help_text: _StrOrPromise
required: bool
show_hidden_initial: bool
widget: _ClassLevelWidgetT = ...
@@ -268,13 +269,13 @@ class ModelChoiceIterator:
class ModelChoiceField(ChoiceField):
disabled: bool
error_messages: Dict[str, str]
help_text: str
help_text: _StrOrPromise
required: bool
show_hidden_initial: bool
validators: List[Any]
default_error_messages: Dict[str, str] = ...
iterator: Type[ModelChoiceIterator] = ...
empty_label: Optional[str] = ...
empty_label: Optional[_StrOrPromise] = ...
queryset: Optional[QuerySet[models.Model]] = ...
limit_choices_to: Optional[_AllLimitChoicesTo] = ...
to_field_name: Optional[str] = ...
@@ -282,12 +283,12 @@ class ModelChoiceField(ChoiceField):
self,
queryset: Union[None, Manager[models.Model], QuerySet[models.Model]],
*,
empty_label: Optional[str] = ...,
empty_label: Optional[_StrOrPromise] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[str] = ...,
label: Optional[_StrOrPromise] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
help_text: _StrOrPromise = ...,
to_field_name: Optional[str] = ...,
limit_choices_to: Optional[_AllLimitChoicesTo] = ...,
blank: bool = ...,
@@ -306,8 +307,8 @@ class ModelChoiceField(ChoiceField):
class ModelMultipleChoiceField(ModelChoiceField):
disabled: bool
empty_label: Optional[str]
help_text: str
empty_label: Optional[_StrOrPromise]
help_text: _StrOrPromise
required: bool
show_hidden_initial: bool
widget: _ClassLevelWidgetT = ...

View File

@@ -43,6 +43,7 @@ class _StrPromise(Promise, Sequence[str]):
# Mypy requires this for the attribute hook to take effect
def __getattribute__(self, __name: str) -> Any: ...
_StrOrPromise = Union[str, _StrPromise]
_C = TypeVar("_C", bound=Callable)
def lazy(func: _C, *resultclasses: Any) -> _C: ...

View File

@@ -1,7 +1,16 @@
from .aliases import StrOrPromise, StrPromise
from .aliases import ValuesQuerySet as ValuesQuerySet
from .annotations import Annotations as Annotations
from .annotations import WithAnnotations as WithAnnotations
from .patch import monkeypatch as monkeypatch
from .types import AnyAttrAllowed as AnyAttrAllowed
__all__ = ["monkeypatch", "ValuesQuerySet", "WithAnnotations", "Annotations", "AnyAttrAllowed"]
__all__ = [
"monkeypatch",
"ValuesQuerySet",
"WithAnnotations",
"Annotations",
"AnyAttrAllowed",
"StrPromise",
"StrOrPromise",
]

View File

@@ -2,9 +2,15 @@ import typing
if typing.TYPE_CHECKING:
from django.db.models.query import _T, _QuerySet, _Row
from django.utils.functional import _StrOrPromise as StrOrPromise
from django.utils.functional import _StrPromise as StrPromise
ValuesQuerySet = _QuerySet[_T, _Row]
else:
from django.db.models.query import QuerySet
from django.utils.functional import Promise as StrPromise
ValuesQuerySet = QuerySet
StrOrPromise = typing.Union[str, StrPromise]
__all__ = ["StrOrPromise", "StrPromise", "ValuesQuerySet"]