7
7
from __future__ import annotations
8
8
9
9
import itertools
10
- from collections .abc import Callable , Iterator
10
+ from collections .abc import Callable , Iterable
11
11
from functools import partial
12
- from typing import Any , Type , Union , cast
12
+ from typing import TYPE_CHECKING , Any , Iterator , NoReturn , Type , Union , cast
13
13
14
14
from astroid import arguments , helpers , inference_tip , nodes , objects , util
15
15
from astroid .builder import AstroidBuilder
29
29
SuccessfulInferenceResult ,
30
30
)
31
31
32
+ if TYPE_CHECKING :
33
+ from astroid .bases import Instance
34
+
32
35
ContainerObjects = Union [
33
36
objects .FrozenSet ,
34
37
objects .DictItems ,
43
46
Type [frozenset ],
44
47
]
45
48
49
+ CopyResult = Union [
50
+ nodes .Dict ,
51
+ nodes .List ,
52
+ nodes .Set ,
53
+ objects .FrozenSet ,
54
+ ]
55
+
46
56
OBJECT_DUNDER_NEW = "object.__new__"
47
57
48
58
STR_CLASS = """
@@ -127,6 +137,10 @@ def ljust(self, width, fillchar=None):
127
137
"""
128
138
129
139
140
+ def _use_default () -> NoReturn : # pragma: no cover
141
+ raise UseInferenceDefault ()
142
+
143
+
130
144
def _extend_string_class (class_node , code , rvalue ):
131
145
"""Function to extend builtin str/unicode class."""
132
146
code = code .format (rvalue = rvalue )
@@ -193,7 +207,9 @@ def register_builtin_transform(transform, builtin_name) -> None:
193
207
an optional context.
194
208
"""
195
209
196
- def _transform_wrapper (node , context : InferenceContext | None = None ):
210
+ def _transform_wrapper (
211
+ node : nodes .Call , context : InferenceContext | None = None , ** kwargs : Any
212
+ ) -> Iterator :
197
213
result = transform (node , context = context )
198
214
if result :
199
215
if not result .parent :
@@ -257,10 +273,12 @@ def _container_generic_transform(
257
273
iterables : tuple [type [nodes .BaseContainer ] | type [ContainerObjects ], ...],
258
274
build_elts : BuiltContainers ,
259
275
) -> nodes .BaseContainer | None :
276
+ elts : Iterable | str | bytes
277
+
260
278
if isinstance (arg , klass ):
261
279
return arg
262
280
if isinstance (arg , iterables ):
263
- arg = cast (ContainerObjects , arg )
281
+ arg = cast (Union [ nodes . BaseContainer , ContainerObjects ] , arg )
264
282
if all (isinstance (elt , nodes .Const ) for elt in arg .elts ):
265
283
elts = [cast (nodes .Const , elt ).value for elt in arg .elts ]
266
284
else :
@@ -277,9 +295,10 @@ def _container_generic_transform(
277
295
elts .append (evaluated_object )
278
296
elif isinstance (arg , nodes .Dict ):
279
297
# Dicts need to have consts as strings already.
280
- if not all (isinstance (elt [0 ], nodes .Const ) for elt in arg .items ):
281
- raise UseInferenceDefault ()
282
- elts = [item [0 ].value for item in arg .items ]
298
+ elts = [
299
+ item [0 ].value if isinstance (item [0 ], nodes .Const ) else _use_default ()
300
+ for item in arg .items
301
+ ]
283
302
elif isinstance (arg , nodes .Const ) and isinstance (arg .value , (str , bytes )):
284
303
elts = arg .value
285
304
else :
@@ -399,6 +418,7 @@ def infer_dict(node: nodes.Call, context: InferenceContext | None = None) -> nod
399
418
args = call .positional_arguments
400
419
kwargs = list (call .keyword_arguments .items ())
401
420
421
+ items : list [tuple [InferenceResult , InferenceResult ]]
402
422
if not args and not kwargs :
403
423
# dict()
404
424
return nodes .Dict (
@@ -695,7 +715,9 @@ def infer_slice(node, context: InferenceContext | None = None):
695
715
return slice_node
696
716
697
717
698
- def _infer_object__new__decorator (node , context : InferenceContext | None = None ):
718
+ def _infer_object__new__decorator (
719
+ node : nodes .ClassDef , context : InferenceContext | None = None , ** kwargs : Any
720
+ ) -> Iterator [Instance ]:
699
721
# Instantiate class immediately
700
722
# since that's what @object.__new__ does
701
723
return iter ((node .instantiate_class (),))
@@ -944,10 +966,10 @@ def _build_dict_with_elements(elements):
944
966
if isinstance (inferred_values , nodes .Const ) and isinstance (
945
967
inferred_values .value , (str , bytes )
946
968
):
947
- elements = [
969
+ elements_with_value = [
948
970
(nodes .Const (element ), default ) for element in inferred_values .value
949
971
]
950
- return _build_dict_with_elements (elements )
972
+ return _build_dict_with_elements (elements_with_value )
951
973
if isinstance (inferred_values , nodes .Dict ):
952
974
keys = inferred_values .itered ()
953
975
for key in keys :
@@ -964,7 +986,7 @@ def _build_dict_with_elements(elements):
964
986
965
987
def _infer_copy_method (
966
988
node : nodes .Call , context : InferenceContext | None = None , ** kwargs : Any
967
- ) -> Iterator [InferenceResult ]:
989
+ ) -> Iterator [CopyResult ]:
968
990
assert isinstance (node .func , nodes .Attribute )
969
991
inferred_orig , inferred_copy = itertools .tee (node .func .expr .infer (context = context ))
970
992
if all (
@@ -973,9 +995,9 @@ def _infer_copy_method(
973
995
)
974
996
for inferred_node in inferred_orig
975
997
):
976
- return inferred_copy
998
+ return cast ( Iterator [ CopyResult ], inferred_copy )
977
999
978
- raise UseInferenceDefault ()
1000
+ raise UseInferenceDefault
979
1001
980
1002
981
1003
def _is_str_format_call (node : nodes .Call ) -> bool :
@@ -1081,5 +1103,7 @@ def _infer_str_format_call(
1081
1103
)
1082
1104
1083
1105
AstroidManager ().register_transform (
1084
- nodes .Call , inference_tip (_infer_str_format_call ), _is_str_format_call
1106
+ nodes .Call ,
1107
+ inference_tip (_infer_str_format_call ),
1108
+ _is_str_format_call ,
1085
1109
)
0 commit comments