1- from _typeshed import StrPath
1+ from _typeshed import Incomplete , StrPath
22
33# Use aliases to avoid name conflicts with Path methods
44from builtins import (
@@ -13,8 +13,8 @@ from builtins import (
1313)
1414from collections .abc import Callable , Mapping , MutableMapping
1515from logging import Logger
16- from typing import IO , Any , ClassVar , Generic , SupportsIndex , TypedDict , TypeVar , overload , type_check_only
17- from typing_extensions import Required , TypeAlias , Unpack
16+ from typing import IO , Any , ClassVar , Generic , Literal , SupportsIndex , TypedDict , TypeVar , overload , type_check_only
17+ from typing_extensions import NotRequired , Required , TypeAlias , Unpack
1818from urllib .parse import ParseResult
1919
2020from .fileaware_mapping import FileAwareMapping
@@ -24,17 +24,66 @@ logger: Logger
2424
2525class NoValue : ...
2626
27- _T1 = TypeVar ("_T1" )
28- _T2 = TypeVar ("_T2" )
29- _Cast : TypeAlias = Callable [[str ], _T1 ]
30- _SchemeValue : TypeAlias = _Cast [Any ] | tuple [_Cast [Any ], Any ]
27+ _T = TypeVar ("_T" )
28+ _KT = TypeVar ("_KT" )
29+ _VT = TypeVar ("_VT" )
30+
31+ _Cast : TypeAlias = Callable [[str ], _T ]
32+ _SchemeValue : TypeAlias = _Cast [object ] | tuple [_Cast [object ], object ]
3133_EmptyDict : TypeAlias = dict [object , object ] # stands for {}
3234
3335@type_check_only
34- class CastDict (TypedDict , Generic [_T1 , _T2 ], total = False ):
35- key : _Cast [_T1 ]
36- value : _Cast [_T2 ]
37- cast : dict [str , _Cast [Any ]] # value cast by key
36+ class CastDict (TypedDict , Generic [_KT , _VT ], total = False ):
37+ key : _Cast [_KT ]
38+ value : _Cast [_VT ]
39+ # key-specific value casts
40+ cast : dict [str , _Cast [object ]]
41+
42+ # One CastDict for each combination of 'key', 'value' and 'cast' (8 in total).
43+ # Use auxiliary '_type' to make them distinguishable for type checkers.
44+ @type_check_only
45+ class CastDict000 (TypedDict ):
46+ _type : NotRequired [Literal ["000" ]]
47+
48+ @type_check_only
49+ class CastDict001 (TypedDict ):
50+ _type : NotRequired [Literal ["001" ]]
51+ cast : dict [str , _Cast [object ]]
52+
53+ @type_check_only
54+ class CastDict010 (TypedDict , Generic [_VT ]):
55+ _type : NotRequired [Literal ["010" ]]
56+ value : _Cast [_VT ]
57+
58+ @type_check_only
59+ class CastDict011 (TypedDict , Generic [_VT ]):
60+ _type : NotRequired [Literal ["011" ]]
61+ value : _Cast [_VT ]
62+ cast : dict [str , _Cast [object ]]
63+
64+ @type_check_only
65+ class CastDict100 (TypedDict , Generic [_KT ]):
66+ _type : NotRequired [Literal ["100" ]]
67+ key : _Cast [_KT ]
68+
69+ @type_check_only
70+ class CastDict101 (TypedDict , Generic [_KT ]):
71+ _type : NotRequired [Literal ["101" ]]
72+ key : _Cast [_KT ]
73+ cast : dict [str , _Cast [object ]]
74+
75+ @type_check_only
76+ class CastDict110 (TypedDict , Generic [_KT , _VT ]):
77+ _type : NotRequired [Literal ["110" ]]
78+ key : _Cast [_KT ]
79+ value : _Cast [_VT ]
80+
81+ @type_check_only
82+ class CastDict111 (TypedDict , Generic [_KT , _VT ]):
83+ _type : NotRequired [Literal ["111" ]]
84+ key : _Cast [_KT ]
85+ value : _Cast [_VT ]
86+ cast : dict [str , _Cast [object ]]
3887
3988@type_check_only
4089class PathKwargs (TypedDict , total = False ):
@@ -60,7 +109,7 @@ class DbConfig(MemoryDbConfig, total=False):
60109 AUTOCOMMIT : bool
61110 DISABLE_SERVER_SIDE_CURSORS : bool
62111 # Remaining options read from queryParams
63- OPTIONS : dict [str , Any ]
112+ OPTIONS : dict [str , Incomplete ]
64113
65114@type_check_only
66115class EmailConfig (TypedDict , total = False ):
@@ -74,13 +123,13 @@ class EmailConfig(TypedDict, total=False):
74123 EMAIL_USE_TLS : bool
75124 EMAIL_USE_SSL : bool
76125 # Remaining options read from queryParams
77- OPTIONS : dict [str , Any ]
126+ OPTIONS : dict [str , Incomplete ]
78127
79128# https://github.com/django/channels
80129@type_check_only
81130class ChannelsConfig (TypedDict , total = False ):
82131 BACKEND : Required [str ]
83- CONFIG : dict [str , Any ]
132+ CONFIG : dict [str , Incomplete ]
84133
85134# https://github.com/django-haystack/django-haystack
86135@type_check_only
@@ -95,13 +144,13 @@ class SimpleSearchConfig(TypedDict, total=False):
95144class SolrSearchConfig (SimpleSearchConfig , total = False ):
96145 URL : Required [str ]
97146 TIMEOUT : int
98- KWARGS : dict [str , Any ]
147+ KWARGS : dict [str , Incomplete ]
99148
100149@type_check_only
101150class ElasticsearchSearchConfig (SimpleSearchConfig , total = False ):
102151 URL : Required [str ]
103152 TIMEOUT : int
104- KWARGS : dict [str , Any ]
153+ KWARGS : dict [str , Incomplete ]
105154 INDEX_NAME : str
106155
107156@type_check_only
@@ -127,7 +176,7 @@ class CacheConfig(TypedDict, total=False):
127176 TIMEOUT : int
128177 VERSION : int
129178 # Remaining options read from queryParams
130- OPTIONS : dict [str , Any ]
179+ OPTIONS : dict [str , Incomplete ]
131180
132181class Env :
133182 ENVIRON : MutableMapping [_str , _str ]
@@ -155,20 +204,20 @@ class Env:
155204 def __init__ (self , ** scheme : _SchemeValue ) -> None : ...
156205 @overload
157206 def __call__ (
158- self , var : _str , cast : _Cast [_T1 ] | None = None , default : _T1 | NoValue = ..., parse_default : _bool = False
159- ) -> _T1 : ...
207+ self , var : _str , cast : _Cast [_T ] | None = None , default : _T | NoValue = ..., parse_default : _bool = False
208+ ) -> _T : ...
160209 @overload
161210 def __call__ (
162- self , var : _str , cast : _list [_Cast [_T1 ]], default : _list [_T1 ] | NoValue = ..., parse_default : _bool = False
163- ) -> _list [_T1 ]: ...
211+ self , var : _str , cast : _list [_Cast [_T ]], default : _list [_T ] | NoValue = ..., parse_default : _bool = False
212+ ) -> _list [_T ]: ...
164213 @overload
165214 def __call__ (
166- self , var : _str , cast : _tuple [_Cast [_T1 ] ], default : _tuple [_T1 ] | NoValue = ..., parse_default : _bool = False
167- ) -> _tuple [_T1 ]: ...
215+ self , var : _str , cast : _tuple [_Cast [_T ], ... ], default : _tuple [_T , ... ] | NoValue = ..., parse_default : _bool = False
216+ ) -> _tuple [_T , ... ]: ...
168217 @overload
169218 def __call__ (
170- self , var : _str , cast : CastDict [_T1 , _T2 ], default : _dict [_T1 , _T2 ] | NoValue = ..., parse_default : _bool = False
171- ) -> _dict [_T1 , _T2 ]: ...
219+ self , var : _str , cast : CastDict [_KT , _VT ], default : _dict [_KT , _VT ] | NoValue = ..., parse_default : _bool = False
220+ ) -> _dict [_KT , _VT | object ]: ...
172221 @overload
173222 # Any (subclass of) list/tuple/dict builtin types are valid for cast.
174223 def __call__ (
@@ -188,13 +237,18 @@ class Env:
188237 def bool (self , var : _str , default : _bool | NoValue = ...) -> _bool : ...
189238 def int (self , var : _str , default : _int | NoValue = ...) -> _int : ...
190239 def float (self , var : _str , default : _float | NoValue = ...) -> _float : ...
191- def json (self , var : _str , default : Any | NoValue = ...) -> Any : ...
192- def list (self , var : _str , cast : _Cast [_T1 ] | None = None , default : _list [_T1 ] | NoValue = ...) -> _list [_T1 ]: ...
193- def tuple (self , var : _str , cast : _Cast [_T1 ] | None = None , default : _tuple [_T1 ] | NoValue = ...) -> _tuple [_T1 ]: ...
194240 @overload
195- def dict (self , var : _str , cast : None = ..., default : _dict [_str , Any ] | NoValue = ...) -> _dict [_str , Any ]: ...
241+ def json (self , var : _str , default : NoValue = ...) -> Any : ...
242+ @overload
243+ def json (self , var : _str , default : _T ) -> _T : ...
244+ def list (self , var : _str , cast : _Cast [_T ] | None = None , default : _list [_T ] | NoValue = ...) -> _list [_T ]: ...
245+ def tuple (self , var : _str , cast : _Cast [_T ] | None = None , default : _tuple [_T , ...] | NoValue = ...) -> _tuple [_T , ...]: ...
196246 @overload
197- def dict (self , var : _str , cast : _Cast [_T1 ], default : _dict [Any , _T1 ] | NoValue = ...) -> _dict [Any , _T1 ]: ...
247+ def dict (
248+ self , var : _str , cast : CastDict [_KT , _VT ] | None = None , default : _dict [_KT , _VT ] | NoValue = ...
249+ ) -> _dict [_KT , _VT | object ]: ...
250+ @overload
251+ def dict (self , var : _str , cast : _Cast [_T ], default : _T | NoValue = ...) -> _T : ...
198252 def url (self , var : _str , default : _str | NoValue = ...) -> _str : ...
199253 def db_url (
200254 self , var : _str = ..., default : _str | NoValue = ..., engine : _str | None = None
@@ -222,20 +276,20 @@ class Env:
222276 def path (self , var : _str , default : _str | NoValue = ..., ** kwargs : Unpack [PathKwargs ]) -> Path : ...
223277 @overload
224278 def get_value (
225- self , var : _str , cast : _Cast [_T1 ] | None = None , default : _T1 | NoValue = ..., parse_default : _bool = False
226- ) -> _T1 : ...
279+ self , var : _str , cast : _Cast [_T ] | None = None , default : _T | NoValue = ..., parse_default : _bool = False
280+ ) -> _T : ...
227281 @overload
228282 def get_value (
229- self , var : _str , cast : _list [_Cast [_T1 ]], default : _list [_T1 ] | NoValue = ..., parse_default : _bool = False
230- ) -> _list [_T1 ]: ...
283+ self , var : _str , cast : _list [_Cast [_T ]], default : _list [_T ] | NoValue = ..., parse_default : _bool = False
284+ ) -> _list [_T ]: ...
231285 @overload
232286 def get_value (
233- self , var : _str , cast : _tuple [_Cast [_T1 ] ], default : _tuple [_T1 ] | NoValue = ..., parse_default : _bool = False
234- ) -> _tuple [_T1 ]: ...
287+ self , var : _str , cast : _tuple [_Cast [_T ], ... ], default : _tuple [_T , ... ] | NoValue = ..., parse_default : _bool = False
288+ ) -> _tuple [_T , ... ]: ...
235289 @overload
236290 def get_value (
237- self , var : _str , cast : CastDict [_T1 , _T2 ], default : _dict [_T1 , _T2 ] | NoValue = ..., parse_default : _bool = False
238- ) -> _dict [_T1 , _T2 ]: ...
291+ self , var : _str , cast : CastDict [_KT , _VT ], default : _dict [_KT , _VT ] | NoValue = ..., parse_default : _bool = False
292+ ) -> _dict [_KT , _VT | object ]: ...
239293 @overload
240294 # Any (subclass of) list/tuple/dict builtin types are valid for cast.
241295 def get_value (
@@ -254,16 +308,40 @@ class Env:
254308 def parse_value (cls , value : _str , cast : None ) -> _str : ...
255309 @classmethod
256310 @overload
257- def parse_value (cls , value : _str , cast : _Cast [_T1 ]) -> _T1 : ...
311+ def parse_value (cls , value : _str , cast : _Cast [_T ]) -> _T : ...
312+ @classmethod
313+ @overload
314+ def parse_value (cls , value : _str , cast : _list [_Cast [_T ]]) -> _list [_T ]: ...
315+ @classmethod
316+ @overload
317+ def parse_value (cls , value : _str , cast : _tuple [_Cast [_T ], ...]) -> _tuple [_T , ...]: ...
318+ @classmethod
319+ @overload
320+ def parse_value (cls , value : _str , cast : CastDict000 ) -> _dict [_str , _str ]: ...
321+ @classmethod
322+ @overload
323+ def parse_value (cls , value : _str , cast : CastDict001 ) -> _dict [_str , _str | object ]: ...
324+ @classmethod
325+ @overload
326+ def parse_value (cls , value : _str , cast : CastDict010 [_VT ]) -> _dict [_str , _VT ]: ...
327+ @classmethod
328+ @overload
329+ def parse_value (cls , value : _str , cast : CastDict011 [_VT ]) -> _dict [_str , _VT | object ]: ...
330+ @classmethod
331+ @overload
332+ def parse_value (cls , value : _str , cast : CastDict100 [_KT ]) -> _dict [_KT , _str ]: ...
333+ @classmethod
334+ @overload
335+ def parse_value (cls , value : _str , cast : CastDict101 [_KT ]) -> _dict [_KT , _str | object ]: ...
258336 @classmethod
259337 @overload
260- def parse_value (cls , value : _str , cast : _list [ _Cast [ _T1 ]] ) -> _list [ _T1 ]: ...
338+ def parse_value (cls , value : _str , cast : CastDict110 [ _KT , _VT ] ) -> _dict [ _KT , _VT ]: ...
261339 @classmethod
262340 @overload
263- def parse_value (cls , value : _str , cast : _tuple [ _Cast [ _T1 ], ... ]) -> _tuple [ _T1 ]: ...
341+ def parse_value (cls , value : _str , cast : CastDict111 [ _KT , _VT ]) -> _dict [ _KT , _VT | object ]: ...
264342 @classmethod
265343 @overload
266- def parse_value (cls , value : _str , cast : CastDict [_T1 , _T2 ]) -> _dict [_T1 , _T2 ]: ...
344+ def parse_value (cls , value : _str , cast : CastDict [_KT , _VT ]) -> _dict [_KT , _VT | object ]: ...
267345 @classmethod
268346 @overload
269347 # Any (subclass of) list/tuple/dict builtin types are valid for cast.
0 commit comments