@@ -2,7 +2,7 @@ import datetime
2
2
from collections .abc import Collection , Iterator , Sequence
3
3
from decimal import Decimal
4
4
from re import Pattern
5
- from typing import Any , ClassVar , Protocol , TypeAlias , type_check_only
5
+ from typing import Any , ClassVar , Protocol , overload , type_check_only
6
6
from uuid import UUID
7
7
8
8
from django .core .files import File
@@ -15,20 +15,24 @@ from django.utils.choices import CallableChoiceIterator, _ChoicesCallable, _Choi
15
15
from django .utils .datastructures import _PropertyDescriptor
16
16
from django .utils .functional import _StrOrPromise
17
17
18
- # Problem: attribute `widget` is always of type `Widget` after field instantiation.
19
- # However, on class level it can be set to `Type[Widget]` too.
20
- # If we annotate it as `Union[Widget, Type[Widget]]`, every code that uses field
21
- # instances will not typecheck.
22
- # If we annotate it as `Widget`, any widget subclasses that do e.g.
23
- # `widget = Select` will not typecheck.
24
- # `Any` gives too much freedom, but does not create false positives.
25
- _ClassLevelWidgetT : TypeAlias = Any
18
+ class _WidgetTypeOrInstance :
19
+ def __init__ (self , origin_type : type [Widget ]) -> None : ...
20
+ @overload
21
+ def __get__ (self , instance : None , owner : type [Field ]) -> type [Widget ] | Widget : ...
22
+ @overload
23
+ def __get__ (self , instance : Field , owner : type [Field ]) -> Widget : ...
24
+ def __get__ (self , instance : Field , owner : type [Field ]) -> type [Widget ] | Widget : ...
25
+ @overload
26
+ def __set__ (self , instance : None , value : type [Widget ]) -> None : ...
27
+ @overload
28
+ def __set__ (self , instance : Field , value : Widget ) -> None : ...
29
+ def __set__ (self , instance : Field , value : type [Widget ] | Widget ) -> None : ...
26
30
27
31
class Field :
28
32
initial : Any
29
33
label : _StrOrPromise | None
30
34
required : bool
31
- widget : _ClassLevelWidgetT
35
+ widget : _WidgetTypeOrInstance
32
36
hidden_widget : type [Widget ]
33
37
default_validators : list [_ValidatorCallable ]
34
38
default_error_messages : ClassVar [_ErrorMessagesDict ]
0 commit comments