Skip to content

Commit 49ec4de

Browse files
committed
Broaden type annotation for verbose_name(_plural) to accept lazystr.
Fixes typeddjango#1137. Signed-off-by: Zixuan James Li <[email protected]>
1 parent 74e31c7 commit 49ec4de

File tree

11 files changed

+44
-30
lines changed

11 files changed

+44
-30
lines changed

django-stubs/apps/config.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ from typing import Dict, Iterator, Optional, Type
33

44
from django.apps.registry import Apps
55
from django.db.models.base import Model
6+
from django.utils.functional import _StrOrPromise
67

78
MODELS_MODULE_NAME: str
89

@@ -11,7 +12,7 @@ class AppConfig:
1112
module: Optional[types.ModuleType] = ...
1213
apps: Optional[Apps] = ...
1314
label: str = ...
14-
verbose_name: str = ...
15+
verbose_name: _StrOrPromise = ...
1516
path: str = ...
1617
models_module: Optional[str] = ...
1718
models: Dict[str, Type[Model]] = ...

django-stubs/contrib/admin/options.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ from django.http.response import HttpResponse, HttpResponseRedirect, JsonRespons
4141
from django.template.response import _TemplateForResponseT
4242
from django.urls.resolvers import URLPattern
4343
from django.utils.datastructures import _ListOrTuple
44+
from django.utils.functional import _StrOrPromise
4445
from django.utils.safestring import SafeString
4546
from typing_extensions import Literal, TypedDict
4647

@@ -296,8 +297,8 @@ class InlineModelAdmin(Generic[_ChildModelT, _ParentModelT], BaseModelAdmin[_Chi
296297
min_num: Optional[int] = ...
297298
max_num: Optional[int] = ...
298299
template: str = ...
299-
verbose_name: Optional[str] = ...
300-
verbose_name_plural: Optional[str] = ...
300+
verbose_name: Optional[_StrOrPromise] = ...
301+
verbose_name_plural: Optional[_StrOrPromise] = ...
301302
can_delete: bool = ...
302303
show_change_link: bool = ...
303304
classes: Optional[Sequence[str]] = ...

django-stubs/contrib/admin/widgets.pyi

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ from django.db.models.fields import _FieldChoices
77
from django.db.models.fields.reverse_related import ForeignObjectRel, ManyToManyRel, ManyToOneRel
88
from django.forms.models import ModelChoiceIterator
99
from django.forms.widgets import Media, _OptAttrs
10+
from django.utils.functional import _StrOrPromise
1011

1112
class FilteredSelectMultiple(forms.SelectMultiple):
12-
verbose_name: str = ...
13+
verbose_name: _StrOrPromise = ...
1314
is_stacked: bool = ...
1415
def __init__(
15-
self, verbose_name: str, is_stacked: bool, attrs: Optional[_OptAttrs] = ..., choices: _FieldChoices = ...
16+
self,
17+
verbose_name: _StrOrPromise,
18+
is_stacked: bool,
19+
attrs: Optional[_OptAttrs] = ...,
20+
choices: _FieldChoices = ...,
1621
) -> None: ...
1722

1823
class AdminDateWidget(forms.DateInput):

django-stubs/contrib/gis/db/models/fields.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ from typing import Any, Iterable, NamedTuple, Optional, Tuple, TypeVar, Union
22

33
from django.core.validators import _ValidatorCallable
44
from django.db.models.fields import Field, _ErrorMessagesT, _FieldChoices
5+
from django.utils.functional import _StrOrPromise
56

67
# __set__ value type
78
_ST = TypeVar("_ST")
@@ -19,7 +20,7 @@ def get_srid_info(srid: int, connection: Any) -> SRIDCacheEntry: ...
1920
class BaseSpatialField(Field[_ST, _GT]):
2021
def __init__(
2122
self,
22-
verbose_name: Optional[Union[str, bytes]] = ...,
23+
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
2324
srid: int = ...,
2425
spatial_index: bool = ...,
2526
*,
@@ -65,7 +66,7 @@ class GeometryField(BaseSpatialField):
6566
geography: Any = ...
6667
def __init__(
6768
self,
68-
verbose_name: Optional[Union[str, bytes]] = ...,
69+
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
6970
dim: int = ...,
7071
geography: bool = ...,
7172
*,

django-stubs/core/cache/backends/db.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from typing import Any, Dict
22

33
from django.core.cache.backends.base import BaseCache
4+
from django.utils.functional import _StrOrPromise
45

56
class Options:
67
db_table: str = ...
78
app_label: str = ...
89
model_name: str = ...
9-
verbose_name: str = ...
10-
verbose_name_plural: str = ...
10+
verbose_name: _StrOrPromise = ...
11+
verbose_name_plural: _StrOrPromise = ...
1112
object_name: str = ...
1213
abstract: bool = ...
1314
managed: bool = ...

django-stubs/db/models/fields/__init__.pyi

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ from django.db.models.query_utils import Q, RegisterLookupMixin
3030
from django.forms import Field as FormField
3131
from django.forms import Widget
3232
from django.utils.datastructures import DictWrapper
33-
from django.utils.functional import _Getter
33+
from django.utils.functional import _Getter, _StrOrPromise
3434
from typing_extensions import Protocol
3535

3636
class Empty: ...
@@ -134,7 +134,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
134134
max_length: Optional[int]
135135
model: Type[Model]
136136
name: str
137-
verbose_name: str
137+
verbose_name: _StrOrPromise
138138
description: Union[str, _Getter[str]]
139139
blank: bool
140140
null: bool
@@ -158,7 +158,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
158158
non_db_attrs: Tuple[str, ...]
159159
def __init__(
160160
self,
161-
verbose_name: Optional[str] = ...,
161+
verbose_name: Optional[_StrOrPromise] = ...,
162162
name: Optional[str] = ...,
163163
primary_key: bool = ...,
164164
max_length: Optional[int] = ...,
@@ -260,7 +260,7 @@ class DecimalField(Field[_ST, _GT]):
260260
decimal_places: int = ...
261261
def __init__(
262262
self,
263-
verbose_name: Optional[str] = ...,
263+
verbose_name: Optional[_StrOrPromise] = ...,
264264
name: Optional[str] = ...,
265265
max_digits: Optional[int] = ...,
266266
decimal_places: Optional[int] = ...,
@@ -289,7 +289,7 @@ class CharField(Field[_ST, _GT]):
289289
_pyi_lookup_exact_type: Any
290290
def __init__(
291291
self,
292-
verbose_name: Optional[str] = ...,
292+
verbose_name: Optional[_StrOrPromise] = ...,
293293
name: Optional[str] = ...,
294294
primary_key: bool = ...,
295295
max_length: Optional[int] = ...,
@@ -319,7 +319,7 @@ class CommaSeparatedIntegerField(CharField[_ST, _GT]): ...
319319
class SlugField(CharField[_ST, _GT]):
320320
def __init__(
321321
self,
322-
verbose_name: Optional[str] = ...,
322+
verbose_name: Optional[_StrOrPromise] = ...,
323323
name: Optional[str] = ...,
324324
primary_key: bool = ...,
325325
unique: bool = ...,
@@ -349,7 +349,7 @@ class EmailField(CharField[_ST, _GT]): ...
349349
class URLField(CharField[_ST, _GT]):
350350
def __init__(
351351
self,
352-
verbose_name: Optional[str] = ...,
352+
verbose_name: Optional[_StrOrPromise] = ...,
353353
name: Optional[str] = ...,
354354
*,
355355
primary_key: bool = ...,
@@ -381,7 +381,7 @@ class TextField(Field[_ST, _GT]):
381381
_pyi_lookup_exact_type: Any
382382
def __init__(
383383
self,
384-
verbose_name: Optional[str] = ...,
384+
verbose_name: Optional[_StrOrPromise] = ...,
385385
name: Optional[str] = ...,
386386
primary_key: bool = ...,
387387
max_length: Optional[int] = ...,
@@ -458,7 +458,7 @@ class DateField(DateTimeCheckMixin, Field[_ST, _GT]):
458458
_pyi_lookup_exact_type: Union[str, date]
459459
def __init__(
460460
self,
461-
verbose_name: Optional[str] = ...,
461+
verbose_name: Optional[_StrOrPromise] = ...,
462462
name: Optional[str] = ...,
463463
auto_now: bool = ...,
464464
auto_now_add: bool = ...,
@@ -486,7 +486,7 @@ class TimeField(DateTimeCheckMixin, Field[_ST, _GT]):
486486
_pyi_private_get_type: time
487487
def __init__(
488488
self,
489-
verbose_name: Optional[str] = ...,
489+
verbose_name: Optional[_StrOrPromise] = ...,
490490
name: Optional[str] = ...,
491491
auto_now: bool = ...,
492492
auto_now_add: bool = ...,
@@ -518,7 +518,7 @@ class UUIDField(Field[_ST, _GT]):
518518
_pyi_private_get_type: uuid.UUID
519519
def __init__(
520520
self,
521-
verbose_name: Optional[str] = ...,
521+
verbose_name: Optional[_StrOrPromise] = ...,
522522
*,
523523
name: Optional[str] = ...,
524524
primary_key: bool = ...,
@@ -551,7 +551,7 @@ class FilePathField(Field[_ST, _GT]):
551551
allow_folders: bool = ...
552552
def __init__(
553553
self,
554-
verbose_name: Optional[str] = ...,
554+
verbose_name: Optional[_StrOrPromise] = ...,
555555
name: Optional[str] = ...,
556556
path: Union[str, Callable[..., str]] = ...,
557557
match: Optional[str] = ...,

django-stubs/db/models/fields/files.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ from django.db.models.base import Model
88
from django.db.models.fields import Field, _ErrorMessagesT, _FieldChoices
99
from django.db.models.query_utils import DeferredAttribute
1010
from django.utils._os import _PathCompatible
11+
from django.utils.functional import _StrOrPromise
1112
from typing_extensions import Protocol
1213

1314
class FieldFile(File):
@@ -46,7 +47,7 @@ class FileField(Field):
4647
upload_to: Union[_PathCompatible, _UploadToCallable] = ...
4748
def __init__(
4849
self,
49-
verbose_name: Optional[str] = ...,
50+
verbose_name: Optional[_StrOrPromise] = ...,
5051
name: Optional[str] = ...,
5152
upload_to: Union[_PathCompatible, _UploadToCallable] = ...,
5253
storage: Optional[Union[Storage, Callable[[], Storage]]] = ...,
@@ -92,7 +93,7 @@ class ImageFieldFile(ImageFile, FieldFile):
9293
class ImageField(FileField):
9394
def __init__(
9495
self,
95-
verbose_name: Optional[str] = ...,
96+
verbose_name: Optional[_StrOrPromise] = ...,
9697
name: Optional[str] = ...,
9798
width_field: Optional[str] = ...,
9899
height_field: Optional[str] = ...,

django-stubs/db/models/fields/json.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ from django.db.backends.base.base import BaseDatabaseWrapper
55
from django.db.models import lookups
66
from django.db.models.lookups import PostgresOperatorLookup, Transform
77
from django.db.models.sql.compiler import SQLCompiler
8+
from django.utils.functional import _StrOrPromise
89

910
from . import Field
1011
from .mixins import CheckFieldDefaultMixin
@@ -14,7 +15,7 @@ class JSONField(CheckFieldDefaultMixin, Field):
1415
decoder: Optional[Type[json.JSONDecoder]]
1516
def __init__(
1617
self,
17-
verbose_name: Optional[str] = ...,
18+
verbose_name: Optional[_StrOrPromise] = ...,
1819
name: Optional[str] = ...,
1920
encoder: Optional[Type[json.JSONEncoder]] = ...,
2021
decoder: Optional[Type[json.JSONDecoder]] = ...,

django-stubs/db/models/fields/related.pyi

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ from django.db.models.fields.reverse_related import ManyToOneRel as ManyToOneRel
2020
from django.db.models.fields.reverse_related import OneToOneRel as OneToOneRel
2121
from django.db.models.manager import RelatedManager
2222
from django.db.models.query_utils import FilteredRelation, PathInfo, Q
23+
from django.utils.functional import _StrOrPromise
2324
from typing_extensions import Literal
2425

2526
_T = TypeVar("_T", bound=models.Model)
@@ -75,7 +76,7 @@ class ForeignObject(RelatedField[_ST, _GT]):
7576
swappable: bool = ...,
7677
*,
7778
db_constraint: bool = ...,
78-
verbose_name: Optional[str] = ...,
79+
verbose_name: Optional[_StrOrPromise] = ...,
7980
name: Optional[str] = ...,
8081
primary_key: bool = ...,
8182
unique: bool = ...,
@@ -120,7 +121,7 @@ class ForeignKey(ForeignObject[_ST, _GT]):
120121
to_field: Optional[str] = ...,
121122
db_constraint: bool = ...,
122123
*,
123-
verbose_name: Optional[Union[str, bytes]] = ...,
124+
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
124125
name: Optional[str] = ...,
125126
primary_key: bool = ...,
126127
max_length: Optional[int] = ...,
@@ -169,7 +170,7 @@ class OneToOneField(ForeignKey[_ST, _GT]):
169170
limit_choices_to: Optional[_AllLimitChoicesTo] = ...,
170171
parent_link: bool = ...,
171172
db_constraint: bool = ...,
172-
verbose_name: Optional[Union[str, bytes]] = ...,
173+
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
173174
name: Optional[str] = ...,
174175
primary_key: bool = ...,
175176
max_length: Optional[int] = ...,
@@ -229,7 +230,7 @@ class ManyToManyField(RelatedField[_ST, _GT]):
229230
db_table: Optional[str] = ...,
230231
swappable: bool = ...,
231232
*,
232-
verbose_name: Optional[Union[str, bytes]] = ...,
233+
verbose_name: Optional[Union[_StrOrPromise, bytes]] = ...,
233234
name: Optional[str] = ...,
234235
primary_key: bool = ...,
235236
max_length: Optional[int] = ...,

django-stubs/db/models/options.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ from django.db.models.fields.reverse_related import ForeignObjectRel
1212
from django.db.models.manager import Manager
1313
from django.db.models.query_utils import PathInfo
1414
from django.utils.datastructures import ImmutableList, _ListOrTuple
15+
from django.utils.functional import _StrOrPromise
1516
from typing_extensions import Literal
1617

1718
PROXY_PARENTS: object
@@ -46,8 +47,8 @@ class Options(Generic[_M]):
4647
base_manager_name: Optional[str] = ...
4748
default_manager_name: Optional[str] = ...
4849
model_name: Optional[str] = ...
49-
verbose_name: Optional[str] = ...
50-
verbose_name_plural: Optional[str] = ...
50+
verbose_name: Optional[_StrOrPromise] = ...
51+
verbose_name_plural: Optional[_StrOrPromise] = ...
5152
db_table: str = ...
5253
ordering: Optional[Sequence[str]] = ...
5354
indexes: List[Any] = ...

django-stubs/utils/functional.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class _StrPromise(Promise, Sequence[str]):
4343
# Mypy requires this for the attribute hook to take effect
4444
def __getattribute__(self, __name: str) -> Any: ...
4545

46+
_StrOrPromise = Union[str, _StrPromise]
4647
_C = TypeVar("_C", bound=Callable)
4748

4849
def lazy(func: _C, *resultclasses: Any) -> _C: ...

0 commit comments

Comments
 (0)