Method: pylint.extensions.code_style.CodeStyleChecker._check_dict_consider_namedtuple_dataclass
Calls: 26, Exceptions: 7, Paths: 11Back
Path 1: 13 calls (0.5)
Dict (13)
None (13)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 2: 2 calls (0.08)
Dict (2)
None (2)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 3: 2 calls (0.08)
Dict (2)
None (2)
GeneratorExit (2)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 4: 2 calls (0.08)
Dict (2)
GeneratorExit (2)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 5: 1 calls (0.04)
Dict (1)
None (1)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 6: 1 calls (0.04)
Dict (1)
None (1)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 7: 1 calls (0.04)
Dict (1)
None (1)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 8: 1 calls (0.04)
Dict (1)
None (1)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 9: 1 calls (0.04)
Dict (1)
None (1)
GeneratorExit (1)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 10: 1 calls (0.04)
Dict (1)
None (1)
GeneratorExit (1)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return
Path 11: 1 calls (0.04)
Dict (1)
None (1)
GeneratorExit (1)
1def _check_dict_consider_namedtuple_dataclass(self, node: nodes.Dict) -> None:
2 """Check if dictionary values can be replaced by Namedtuple or Dataclass."""
3 if not (
4 isinstance(node.parent, (nodes.Assign, nodes.AnnAssign))
5 and isinstance(node.parent.parent, nodes.Module)
6 or isinstance(node.parent, nodes.AnnAssign)
7 and isinstance(node.parent.target, nodes.AssignName)
8 and utils.is_assign_name_annotated_with(node.parent.target, "Final")
9 ):
10 # If dict is not part of an 'Assign' or 'AnnAssign' node in
11 # a module context OR 'AnnAssign' with 'Final' annotation, skip check.
12 return
13
14 # All dict_values are itself dict nodes
15 if len(node.items) > 1 and all(
16 isinstance(dict_value, nodes.Dict) for _, dict_value in node.items
17 ):
18 KeyTupleT = Tuple[Type[nodes.NodeNG], str]
19
20 # Makes sure all keys are 'Const' string nodes
21 keys_checked: set[KeyTupleT] = set()
22 for _, dict_value in node.items:
23 dict_value = cast(nodes.Dict, dict_value)
24 for key, _ in dict_value.items:
25 key_tuple = (type(key), key.as_string())
26 if key_tuple in keys_checked:
27 continue
28 inferred = safe_infer(key)
29 if not (
30 isinstance(inferred, nodes.Const)
31 and inferred.pytype() == "builtins.str"
32 ):
33 return
34 keys_checked.add(key_tuple)
35
36 # Makes sure all subdicts have at least 1 common key
37 key_tuples: list[tuple[KeyTupleT, ...]] = []
38 for _, dict_value in node.items:
39 dict_value = cast(nodes.Dict, dict_value)
40 key_tuples.append(
41 tuple((type(key), key.as_string()) for key, _ in dict_value.items)
42 )
43 keys_intersection: set[KeyTupleT] = set(key_tuples[0])
44 for sub_key_tuples in key_tuples[1:]:
45 keys_intersection.intersection_update(sub_key_tuples)
46 if not keys_intersection:
47 return
48
49 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
50 return
51
52 # All dict_values are itself either list or tuple nodes
53 if len(node.items) > 1 and all(
54 isinstance(dict_value, (nodes.List, nodes.Tuple))
55 for _, dict_value in node.items
56 ):
57 # Make sure all sublists have the same length > 0
58 list_length = len(node.items[0][1].elts)
59 if list_length == 0:
60 return
61 for _, dict_value in node.items[1:]:
62 if len(dict_value.elts) != list_length:
63 return
64
65 # Make sure at least one list entry isn't a dict
66 for _, dict_value in node.items:
67 if all(isinstance(entry, nodes.Dict) for entry in dict_value.elts):
68 return
69
70 self.add_message("consider-using-namedtuple-or-dataclass", node=node)
71 return