Skip to content

Commit edad7ba

Browse files
authored
Use match statement in checkers (5) (#10544)
1 parent c708b6a commit edad7ba

File tree

9 files changed

+89
-121
lines changed

9 files changed

+89
-121
lines changed

pylint/checkers/base/comparison_checker.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,19 @@ def _check_nan_comparison(
145145
) -> None:
146146
def _is_float_nan(node: nodes.NodeNG) -> bool:
147147
try:
148-
if isinstance(node, nodes.Call) and len(node.args) == 1:
149-
if (
150-
node.args[0].value.lower() == "nan"
151-
and node.inferred()[0].pytype() == "builtins.float"
148+
match node:
149+
case nodes.Call(args=[nodes.Const(value=str(value))]) if (
150+
value.lower() == "nan"
152151
):
153-
return True
152+
return node.inferred()[0].pytype() == "builtins.float" # type: ignore[no-any-return]
154153
return False
155154
except AttributeError:
156155
return False
157156

158157
def _is_numpy_nan(node: nodes.NodeNG) -> bool:
159-
if isinstance(node, nodes.Attribute) and node.attrname == "NaN":
160-
if isinstance(node.expr, nodes.Name):
161-
return node.expr.name in {"numpy", "nmp", "np"}
158+
match node:
159+
case nodes.Attribute(attrname="NaN", expr=nodes.Name(name=name)):
160+
return name in {"numpy", "nmp", "np"}
162161
return False
163162

164163
def _is_nan(node: nodes.NodeNG) -> bool:

pylint/checkers/classes/class_checker.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,13 +1980,10 @@ def _is_called_inside_special_method(node: nodes.NodeNG) -> bool:
19801980
return frame_name and frame_name in PYMETHODS
19811981

19821982
def _is_type_self_call(self, expr: nodes.NodeNG) -> bool:
1983-
return (
1984-
isinstance(expr, nodes.Call)
1985-
and isinstance(expr.func, nodes.Name)
1986-
and expr.func.name == "type"
1987-
and len(expr.args) == 1
1988-
and self._is_mandatory_method_param(expr.args[0])
1989-
)
1983+
match expr:
1984+
case nodes.Call(func=nodes.Name(name="type"), args=[arg]):
1985+
return self._is_mandatory_method_param(arg)
1986+
return False
19901987

19911988
@staticmethod
19921989
def _is_classmethod(func: LocalsDictNodeNG) -> bool:

pylint/checkers/logging.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,10 @@ def visit_call(self, node: nodes.Call) -> None:
192192
"""Checks calls to logging methods."""
193193

194194
def is_logging_name() -> bool:
195-
return (
196-
isinstance(node.func, nodes.Attribute)
197-
and isinstance(node.func.expr, nodes.Name)
198-
and node.func.expr.name in self._logging_names
199-
)
195+
match node.func:
196+
case nodes.Attribute(expr=nodes.Name(name=name)):
197+
return name in self._logging_names
198+
return False
200199

201200
def is_logger_class() -> tuple[bool, str | None]:
202201
for inferred in infer_all(node.func):

pylint/checkers/modified_iterating_checker.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,10 @@ def _modified_iterating_check(
9999

100100
@staticmethod
101101
def _is_node_expr_that_calls_attribute_name(node: nodes.NodeNG) -> bool:
102-
return (
103-
isinstance(node, nodes.Expr)
104-
and isinstance(node.value, nodes.Call)
105-
and isinstance(node.value.func, nodes.Attribute)
106-
and isinstance(node.value.func.expr, nodes.Name)
107-
)
102+
match node:
103+
case nodes.Expr(value=nodes.Call(func=nodes.Attribute(expr=nodes.Name()))):
104+
return True
105+
return False
108106

109107
@staticmethod
110108
def _common_cond_list_set(
@@ -123,10 +121,10 @@ def _common_cond_list_set(
123121

124122
@staticmethod
125123
def _is_node_assigns_subscript_name(node: nodes.NodeNG) -> bool:
126-
return isinstance(node, nodes.Assign) and (
127-
isinstance(node.targets[0], nodes.Subscript)
128-
and (isinstance(node.targets[0].value, nodes.Name))
129-
)
124+
match node:
125+
case nodes.Assign(targets=[nodes.Subscript(value=nodes.Name()), *_]):
126+
return True
127+
return False
130128

131129
def _modified_iterating_list_cond(
132130
self, node: nodes.NodeNG, iter_obj: nodes.Name | nodes.Attribute

pylint/checkers/refactoring/refactoring_checker.py

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -826,14 +826,13 @@ def _check_superfluous_else_continue(self, node: nodes.If) -> None:
826826

827827
@staticmethod
828828
def _type_and_name_are_equal(node_a: Any, node_b: Any) -> bool:
829-
if isinstance(node_a, nodes.Name) and isinstance(node_b, nodes.Name):
830-
return node_a.name == node_b.name # type: ignore[no-any-return]
831-
if isinstance(node_a, nodes.AssignName) and isinstance(
832-
node_b, nodes.AssignName
833-
):
834-
return node_a.name == node_b.name # type: ignore[no-any-return]
835-
if isinstance(node_a, nodes.Const) and isinstance(node_b, nodes.Const):
836-
return node_a.value == node_b.value # type: ignore[no-any-return]
829+
match (node_a, node_b):
830+
case (
831+
[nodes.Name(name=a), nodes.Name(name=b)]
832+
| [nodes.AssignName(name=a), nodes.AssignName(name=b)]
833+
| [nodes.Const(value=a), nodes.Const(value=b)]
834+
):
835+
return a == b # type: ignore[no-any-return]
837836
return False
838837

839838
def _is_dict_get_block(self, node: nodes.If) -> bool:
@@ -1568,12 +1567,10 @@ def visit_boolop(self, node: nodes.BoolOp) -> None:
15681567

15691568
@staticmethod
15701569
def _is_simple_assignment(node: nodes.NodeNG | None) -> bool:
1571-
return (
1572-
isinstance(node, nodes.Assign)
1573-
and len(node.targets) == 1
1574-
and isinstance(node.targets[0], nodes.AssignName)
1575-
and isinstance(node.value, nodes.Name)
1576-
)
1570+
match node:
1571+
case nodes.Assign(targets=[nodes.AssignName()], value=nodes.Name()):
1572+
return True
1573+
return False
15771574

15781575
def _check_swap_variables(self, node: nodes.Return | nodes.Assign) -> None:
15791576
if not node.next_sibling() or not node.next_sibling().next_sibling():
@@ -1901,16 +1898,12 @@ def _is_and_or_ternary(node: nodes.NodeNG | None) -> bool:
19011898
19021899
All of: condition, true_value and false_value should not be a complex boolean expression
19031900
"""
1904-
return (
1905-
isinstance(node, nodes.BoolOp)
1906-
and node.op == "or"
1907-
and len(node.values) == 2
1908-
and isinstance(node.values[0], nodes.BoolOp)
1909-
and not isinstance(node.values[1], nodes.BoolOp)
1910-
and node.values[0].op == "and"
1911-
and not isinstance(node.values[0].values[1], nodes.BoolOp)
1912-
and len(node.values[0].values) == 2
1913-
)
1901+
match node:
1902+
case nodes.BoolOp(
1903+
op="or", values=[nodes.BoolOp(op="and", values=[_, v1]), v2]
1904+
) if not (isinstance(v2, nodes.BoolOp) or isinstance(v1, nodes.BoolOp)):
1905+
return True
1906+
return False
19141907

19151908
@staticmethod
19161909
def _and_or_ternary_arguments(
@@ -2093,10 +2086,10 @@ def _is_function_def_never_returning(
20932086
except AttributeError:
20942087
return False # the BoundMethod proxy may be a lambda without a returns
20952088

2096-
return (
2097-
isinstance(returns, nodes.Attribute)
2098-
and returns.attrname in {"NoReturn", "Never"}
2099-
) or (isinstance(returns, nodes.Name) and returns.name in {"NoReturn", "Never"})
2089+
match returns:
2090+
case nodes.Attribute(attrname=name) | nodes.Name(name=name):
2091+
return name in {"NoReturn", "Never"}
2092+
return False
21002093

21012094
def _check_return_at_the_end(self, node: nodes.FunctionDef) -> None:
21022095
"""Check for presence of a *single* return statement at the end of a

pylint/checkers/typecheck.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,14 +1291,14 @@ def _is_ignored_function(
12911291

12921292
@staticmethod
12931293
def _is_builtin_no_return(node: nodes.Assign) -> bool:
1294-
return (
1295-
isinstance(node.value, nodes.Call)
1296-
and isinstance(node.value.func, nodes.Attribute)
1297-
and bool(inferred := utils.safe_infer(node.value.func.expr))
1298-
and isinstance(inferred, bases.Instance)
1299-
and node.value.func.attrname
1300-
in BUILTINS_IMPLICIT_RETURN_NONE.get(inferred.pytype(), ())
1301-
)
1294+
match node.value:
1295+
case nodes.Call(func=nodes.Attribute(expr=expr, attrname=attr)):
1296+
return (
1297+
bool(inferred := utils.safe_infer(expr))
1298+
and isinstance(inferred, bases.Instance)
1299+
and attr in BUILTINS_IMPLICIT_RETURN_NONE.get(inferred.pytype(), ())
1300+
)
1301+
return False
13021302

13031303
def _check_dundername_is_string(self, node: nodes.Assign) -> None:
13041304
"""Check a string is assigned to self.__name__."""

pylint/checkers/utils.py

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,11 +1479,10 @@ def has_known_bases(
14791479

14801480

14811481
def is_none(node: nodes.NodeNG) -> bool:
1482-
return (
1483-
node is None
1484-
or (isinstance(node, nodes.Const) and node.value is None)
1485-
or (isinstance(node, nodes.Name) and node.name == "None")
1486-
)
1482+
match node:
1483+
case None | nodes.Const(value=None) | nodes.Name(value="None"):
1484+
return True
1485+
return False
14871486

14881487

14891488
def node_type(node: nodes.NodeNG) -> SuccessfulInferenceResult | None:
@@ -1696,11 +1695,10 @@ def is_protocol_class(cls: nodes.NodeNG) -> bool:
16961695

16971696
def is_call_of_name(node: nodes.NodeNG, name: str) -> bool:
16981697
"""Checks if node is a function call with the given name."""
1699-
return (
1700-
isinstance(node, nodes.Call)
1701-
and isinstance(node.func, nodes.Name)
1702-
and node.func.name == name
1703-
)
1698+
match node:
1699+
case nodes.Call(func=nodes.Name(name=func_name)):
1700+
return func_name == name # type: ignore[no-any-return]
1701+
return False
17041702

17051703

17061704
def is_test_condition(
@@ -1885,12 +1883,10 @@ def is_deleted_after_current(node: nodes.NodeNG, varname: str) -> bool:
18851883

18861884
def is_function_body_ellipsis(node: nodes.FunctionDef) -> bool:
18871885
"""Checks whether a function body only consists of a single Ellipsis."""
1888-
return (
1889-
len(node.body) == 1
1890-
and isinstance(node.body[0], nodes.Expr)
1891-
and isinstance(node.body[0].value, nodes.Const)
1892-
and node.body[0].value.value == Ellipsis
1893-
)
1886+
match node.body:
1887+
case [nodes.Expr(value=nodes.Const(value=value))]:
1888+
return value is Ellipsis
1889+
return False
18941890

18951891

18961892
def is_base_container(node: nodes.NodeNG | None) -> bool:
@@ -1909,20 +1905,18 @@ def is_empty_str_literal(node: nodes.NodeNG | None) -> bool:
19091905

19101906
def returns_bool(node: nodes.NodeNG) -> bool:
19111907
"""Returns true if a node is a nodes.Return that returns a constant boolean."""
1912-
return (
1913-
isinstance(node, nodes.Return)
1914-
and isinstance(node.value, nodes.Const)
1915-
and isinstance(node.value.value, bool)
1916-
)
1908+
match node:
1909+
case nodes.Return(value=nodes.Const(value=bool())):
1910+
return True
1911+
return False
19171912

19181913

19191914
def assigned_bool(node: nodes.NodeNG) -> bool:
19201915
"""Returns true if a node is a nodes.Assign that returns a constant boolean."""
1921-
return (
1922-
isinstance(node, nodes.Assign)
1923-
and isinstance(node.value, nodes.Const)
1924-
and isinstance(node.value.value, bool)
1925-
)
1916+
match node:
1917+
case nodes.Assign(value=nodes.Const(value=bool())):
1918+
return True
1919+
return False
19261920

19271921

19281922
def get_node_first_ancestor_of_type(
@@ -1993,18 +1987,15 @@ def is_typing_member(node: nodes.NodeNG, names_to_check: tuple[str, ...]) -> boo
19931987
except IndexError:
19941988
return False
19951989

1996-
if isinstance(import_from, nodes.ImportFrom):
1997-
return (
1998-
import_from.modname == "typing"
1999-
and import_from.real_name(node.name) in names_to_check
2000-
)
1990+
match import_from:
1991+
case nodes.ImportFrom(modname="typing"):
1992+
return import_from.real_name(node.name) in names_to_check
1993+
return False
20011994
case nodes.Attribute():
2002-
inferred_module = safe_infer(node.expr)
2003-
return (
2004-
isinstance(inferred_module, nodes.Module)
2005-
and inferred_module.name == "typing"
2006-
and node.attrname in names_to_check
2007-
)
1995+
match safe_infer(node.expr):
1996+
case nodes.Module(name="typing"):
1997+
return node.attrname in names_to_check
1998+
return False
20081999
return False
20092000

20102001

pylint/extensions/code_style.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -282,19 +282,11 @@ def _check_prev_sibling_to_if_stmt(
282282
if prev_sibling is None or prev_sibling.tolineno - prev_sibling.fromlineno != 0:
283283
return False
284284

285-
if (
286-
isinstance(prev_sibling, nodes.Assign)
287-
and len(prev_sibling.targets) == 1
288-
and isinstance(prev_sibling.targets[0], nodes.AssignName)
289-
and prev_sibling.targets[0].name == name
290-
):
291-
return True
292-
if (
293-
isinstance(prev_sibling, nodes.AnnAssign)
294-
and isinstance(prev_sibling.target, nodes.AssignName)
295-
and prev_sibling.target.name == name
296-
):
297-
return True
285+
match prev_sibling:
286+
case nodes.Assign(
287+
targets=[nodes.AssignName(name=target_name)]
288+
) | nodes.AnnAssign(target=nodes.AssignName(name=target_name)):
289+
return target_name == name # type: ignore[no-any-return]
298290
return False
299291

300292
@staticmethod

pylint/extensions/typing.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,10 @@ def visit_subscript(self, node: nodes.Subscript) -> None:
300300
def _is_deprecated_union_annotation(
301301
annotation: nodes.NodeNG, union_name: str
302302
) -> bool:
303-
return (
304-
isinstance(annotation, nodes.Subscript)
305-
and isinstance(annotation.value, nodes.Name)
306-
and annotation.value.name == union_name
307-
)
303+
match annotation:
304+
case nodes.Subscript(value=nodes.Name(name=name)):
305+
return name == union_name # type: ignore[no-any-return]
306+
return False
308307

309308
def _is_binop_union_annotation(self, annotation: nodes.NodeNG) -> bool:
310309
return self._should_check_alternative_union_syntax and isinstance(

0 commit comments

Comments
 (0)