Skip to content

Commit f0b41c0

Browse files
authored
Use match statement in checkers (7) (#10576)
1 parent 01f022d commit f0b41c0

File tree

5 files changed

+107
-123
lines changed

5 files changed

+107
-123
lines changed

pylint/checkers/base/basic_error_checker.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -542,26 +542,20 @@ def _check_redefinition(
542542

543543
# Exempt functions redefined on a condition.
544544
if isinstance(node.parent, nodes.If):
545-
# Exempt "if not <func>" cases
546-
if (
547-
isinstance(node.parent.test, nodes.UnaryOp)
548-
and node.parent.test.op == "not"
549-
and isinstance(node.parent.test.operand, nodes.Name)
550-
and node.parent.test.operand.name == node.name
551-
):
552-
return
553-
554-
# Exempt "if <func> is not None" cases
555-
# pylint: disable=too-many-boolean-expressions
556-
if (
557-
isinstance(node.parent.test, nodes.Compare)
558-
and isinstance(node.parent.test.left, nodes.Name)
559-
and node.parent.test.left.name == node.name
560-
and node.parent.test.ops[0][0] == "is"
561-
and isinstance(node.parent.test.ops[0][1], nodes.Const)
562-
and node.parent.test.ops[0][1].value is None
563-
):
564-
return
545+
match node.parent.test:
546+
case nodes.UnaryOp(op="not", operand=nodes.Name(name=name)) if (
547+
name == node.name
548+
):
549+
# Exempt "if not <func>" cases
550+
return
551+
case nodes.Compare(
552+
left=nodes.Name(name=name),
553+
ops=[["is", nodes.Const(value=None)]],
554+
) if (
555+
name == node.name
556+
):
557+
# Exempt "if <func> is not None" cases
558+
return
565559

566560
# Check if we have forward references for this node.
567561
try:

pylint/checkers/base/docstring_checker.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,15 @@ def _check_docstring(
178178
self.linter.stats.undocumented["klass"] += 1
179179
else:
180180
self.linter.stats.undocumented[node_type] += 1
181-
if (
182-
node.body
183-
and isinstance(node.body[0], nodes.Expr)
184-
and isinstance(node.body[0].value, nodes.Call)
185-
):
186-
# Most likely a string with a format call. Let's see.
187-
func = utils.safe_infer(node.body[0].value.func)
188-
if isinstance(func, astroid.BoundMethod) and isinstance(
189-
func.bound, astroid.Instance
190-
):
191-
# Strings.
192-
if func.bound.name in {"str", "unicode", "bytes"}:
193-
return
181+
match node.body:
182+
case [nodes.Expr(value=nodes.Call() as value), *_]:
183+
# Most likely a string with a format call. Let's see.
184+
match utils.safe_infer(value.func):
185+
case astroid.BoundMethod(
186+
bound=astroid.Instance(name="str" | "unicode" | "bytes")
187+
):
188+
# Strings.
189+
return
194190
match node_type:
195191
case "module":
196192
message = "missing-module-docstring"

pylint/checkers/classes/class_checker.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,16 +1653,16 @@ def _check_slots_elt(
16531653
continue
16541654

16551655
# Check if we have a conflict with a class variable.
1656-
class_variable = node.locals.get(inferred.value)
1657-
if class_variable:
1658-
# Skip annotated assignments which don't conflict at all with slots.
1659-
if len(class_variable) == 1:
1660-
parent = class_variable[0].parent
1661-
if isinstance(parent, nodes.AnnAssign) and parent.value is None:
1662-
return
1663-
self.add_message(
1664-
"class-variable-slots-conflict", args=(inferred.value,), node=elt
1665-
)
1656+
match class_variable := node.locals.get(inferred.value):
1657+
case [nodes.NodeNG(parent=nodes.AnnAssign(value=None))]:
1658+
# Skip annotated assignments which don't conflict at all with slots.
1659+
return
1660+
case _ if class_variable:
1661+
self.add_message(
1662+
"class-variable-slots-conflict",
1663+
args=(inferred.value,),
1664+
node=elt,
1665+
)
16661666

16671667
def leave_functiondef(self, node: nodes.FunctionDef) -> None:
16681668
"""On method node, check if this method couldn't be a function.
@@ -2221,7 +2221,6 @@ def _check_init(self, node: nodes.FunctionDef, klass_node: nodes.ClassDef) -> No
22212221
match expr.expr:
22222222
case nodes.Call(func=nodes.Name(name="super")):
22232223
return
2224-
# pylint: disable = too-many-try-statements
22252224
try:
22262225
for klass in expr.expr.infer():
22272226
if isinstance(klass, util.UninferableBase):
@@ -2233,15 +2232,13 @@ def _check_init(self, node: nodes.FunctionDef, klass_node: nodes.ClassDef) -> No
22332232
# base = super()
22342233
# base.__init__(...)
22352234

2236-
if (
2237-
isinstance(klass, astroid.Instance)
2238-
and isinstance(klass._proxied, nodes.ClassDef)
2239-
and is_builtin_object(klass._proxied)
2240-
and klass._proxied.name == "super"
2241-
):
2242-
return
2243-
if isinstance(klass, astroid.objects.Super):
2244-
return
2235+
match klass:
2236+
case astroid.Instance(
2237+
_proxied=nodes.ClassDef(name="super") as p
2238+
) if is_builtin_object(p):
2239+
return
2240+
case astroid.objects.Super():
2241+
return
22452242
try:
22462243
method = not_called_yet.pop(klass)
22472244
# Record that the class' init has been called

pylint/checkers/refactoring/refactoring_checker.py

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -881,19 +881,15 @@ def _is_dict_get_block(self, node: nodes.If) -> bool:
881881
return isinstance(utils.safe_infer(test.ops[0][1]), nodes.Dict)
882882

883883
def _check_consider_get(self, node: nodes.If) -> None:
884-
if_block_ok = self._is_dict_get_block(node)
885-
if if_block_ok and not node.orelse:
886-
self.add_message("consider-using-get", node=node)
887-
elif (
888-
if_block_ok
889-
and len(node.orelse) == 1
890-
and isinstance(node.orelse[0], nodes.Assign)
891-
and self._type_and_name_are_equal(
892-
node.orelse[0].targets[0], node.body[0].targets[0]
893-
)
894-
and len(node.orelse[0].targets) == 1
895-
):
896-
self.add_message("consider-using-get", node=node)
884+
if not self._is_dict_get_block(node):
885+
return
886+
match node:
887+
case nodes.If(orelse=[]):
888+
self.add_message("consider-using-get", node=node)
889+
case nodes.If(
890+
body=[nodes.Assign(targets=[t1])], orelse=[nodes.Assign(targets=[t2])]
891+
) if self._type_and_name_are_equal(t1, t2):
892+
self.add_message("consider-using-get", node=node)
897893

898894
@utils.only_required_for_messages(
899895
"too-many-nested-blocks",
@@ -1374,14 +1370,14 @@ def _check_consider_using_in(self, node: nodes.BoolOp) -> None:
13741370
return
13751371

13761372
for value in node.values:
1377-
if (
1378-
not isinstance(value, nodes.Compare)
1379-
or len(value.ops) != 1
1380-
or value.ops[0][0] not in allowed_ops[node.op]
1381-
):
1382-
return
1383-
for comparable in value.left, value.ops[0][1]:
1384-
if isinstance(comparable, nodes.Call):
1373+
match value:
1374+
case nodes.Compare(left=nodes.Call()) | nodes.Compare(
1375+
ops=[tuple((_, nodes.Call()))]
1376+
):
1377+
return
1378+
case nodes.Compare(ops=[tuple((op, _))]) if op in allowed_ops[node.op]:
1379+
pass
1380+
case _:
13851381
return
13861382

13871383
# Gather variables and values from comparisons
@@ -1822,42 +1818,43 @@ def _check_unnecessary_comprehension(self, node: nodes.Comprehension) -> None:
18221818
):
18231819
return
18241820

1825-
if (
1826-
isinstance(node.parent, nodes.DictComp)
1827-
and isinstance(node.parent.key, nodes.Name)
1828-
and isinstance(node.parent.value, nodes.Name)
1829-
and isinstance(node.target, nodes.Tuple)
1830-
and all(isinstance(elt, nodes.AssignName) for elt in node.target.elts)
1831-
):
1832-
expr_list = [node.parent.key.name, node.parent.value.name]
1833-
target_list = [elt.name for elt in node.target.elts]
1834-
1835-
elif isinstance(node.parent, (nodes.ListComp, nodes.SetComp)):
1836-
expr = node.parent.elt
1837-
if isinstance(expr, nodes.Name):
1838-
expr_list = expr.name
1839-
elif isinstance(expr, nodes.Tuple):
1840-
if any(not isinstance(elt, nodes.Name) for elt in expr.elts):
1841-
return
1842-
expr_list = [elt.name for elt in expr.elts]
1843-
else:
1844-
expr_list = []
1845-
target = node.parent.generators[0].target
1846-
target_list = (
1847-
target.name
1848-
if isinstance(target, nodes.AssignName)
1849-
else (
1850-
[
1851-
elt.name
1852-
for elt in target.elts
1853-
if isinstance(elt, nodes.AssignName)
1854-
]
1855-
if isinstance(target, nodes.Tuple)
1856-
else []
1857-
)
1858-
)
1859-
else:
1860-
return
1821+
match node:
1822+
case nodes.Comprehension(
1823+
target=nodes.Tuple(elts=elts),
1824+
parent=nodes.DictComp(
1825+
key=nodes.Name(name=key_name),
1826+
value=nodes.Name(name=value_name),
1827+
),
1828+
) if all(isinstance(elt, nodes.AssignName) for elt in elts):
1829+
expr_list = [key_name, value_name]
1830+
target_list = [elt.name for elt in elts]
1831+
1832+
case nodes.Comprehension(
1833+
parent=nodes.ListComp() | nodes.SetComp() as parent
1834+
):
1835+
match expr := parent.elt:
1836+
case nodes.Name(name=expr_list):
1837+
pass
1838+
case nodes.Tuple():
1839+
if not all(isinstance(elt, nodes.Name) for elt in expr.elts):
1840+
return
1841+
expr_list = [elt.name for elt in expr.elts]
1842+
case _:
1843+
expr_list = []
1844+
match target := parent.generators[0].target:
1845+
case nodes.AssignName(name=target_list):
1846+
pass
1847+
case nodes.Tuple():
1848+
target_list = [
1849+
elt.name
1850+
for elt in target.elts
1851+
if isinstance(elt, nodes.AssignName)
1852+
]
1853+
case _:
1854+
target_list = []
1855+
1856+
case _:
1857+
return
18611858
if expr_list == target_list and expr_list:
18621859
args: tuple[str] | None = None
18631860
inferred = utils.safe_infer(node.iter)

pylint/checkers/variables.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3402,19 +3402,19 @@ def _check_classdef_metaclasses(
34023402
consumed: list[tuple[Consumption, str]] = []
34033403
metaclass = klass.metaclass()
34043404
name = ""
3405-
if isinstance(klass._metaclass, nodes.Name):
3406-
name = klass._metaclass.name
3407-
elif isinstance(klass._metaclass, nodes.Attribute) and klass._metaclass.expr:
3408-
attr = klass._metaclass.expr
3409-
while not isinstance(attr, nodes.Name):
3410-
attr = attr.expr
3411-
name = attr.name
3412-
elif isinstance(klass._metaclass, nodes.Call) and isinstance(
3413-
klass._metaclass.func, nodes.Name
3414-
):
3415-
name = klass._metaclass.func.name
3416-
elif metaclass:
3417-
name = metaclass.root().name
3405+
match klass._metaclass:
3406+
case nodes.Name(name=name):
3407+
# bind name
3408+
pass
3409+
case nodes.Attribute(expr=attr):
3410+
while not isinstance(attr, nodes.Name):
3411+
attr = attr.expr
3412+
name = attr.name
3413+
case nodes.Call(func=nodes.Name(name=name)):
3414+
# bind name
3415+
pass
3416+
case _ if metaclass:
3417+
name = metaclass.root().name
34183418

34193419
found = False
34203420
name = METACLASS_NAME_TRANSFORMS.get(name, name)

0 commit comments

Comments
 (0)