@@ -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,25 @@ 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
+ @type_check_only
19
+ class _WidgetTypeOrInstance :
20
+ def __init__ (self , origin_type : type [Widget ]) -> None : ...
21
+ @overload
22
+ def __get__ (self , instance : None , owner : type [Field ]) -> type [Widget ] | Widget : ...
23
+ @overload
24
+ def __get__ (self , instance : Field , owner : type [Field ]) -> Widget : ...
25
+ def __get__ (self , instance : Field , owner : type [Field ]) -> type [Widget ] | Widget : ...
26
+ @overload
27
+ def __set__ (self , instance : None , value : type [Widget ]) -> None : ...
28
+ @overload
29
+ def __set__ (self , instance : Field , value : Widget ) -> None : ...
30
+ def __set__ (self , instance : Field , value : type [Widget ] | Widget ) -> None : ...
26
31
27
32
class Field :
28
33
initial : Any
29
34
label : _StrOrPromise | None
30
35
required : bool
31
- widget : _ClassLevelWidgetT
36
+ widget : _WidgetTypeOrInstance
32
37
hidden_widget : type [Widget ]
33
38
default_validators : list [_ValidatorCallable ]
34
39
default_error_messages : ClassVar [_ErrorMessagesDict ]
0 commit comments