1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
import re
from dataclasses import dataclass
from mypy.nodes import CallExpr, MemberExpr, StrExpr
from refurb.checks.pathlib.util import is_pathlike
from refurb.error import Error
@dataclass
class ErrorInfo(Error):
"""
When checking the file extension for a Path object don't call
`endswith()` on the `name` field, directly check against `suffix` instead.
Bad:
```
from pathlib import Path
def is_markdown_file(file: Path) -> bool:
return file.name.endswith(".md")
```
Good:
```
from pathlib import Path
def is_markdown_file(file: Path) -> bool:
return file.suffix == ".md"
```
Note: The `suffix` field will only contain the last file extension, so
don't use `suffix` if you are checking for an extension like `.tar.gz`.
Refurb won't warn in those cases, but it is good to remember in case you
plan to use this in other places.
"""
enabled = False
name = "use-suffix"
code = 172
categories = ("pathlib",)
FILE_EXTENSION = re.compile(r"^\.[a-zA-Z0-9_-]+$")
def check(node: CallExpr, errors: list[Error]) -> None:
match node:
case CallExpr(
callee=MemberExpr(
expr=MemberExpr(
expr=file,
name="name",
),
name="endswith",
),
args=[StrExpr(value=suffix)],
) if FILE_EXTENSION.match(suffix) and is_pathlike(file):
old = f'x.name.endswith("{suffix}")'
new = f'x.suffix == "{suffix}"'
errors.append(ErrorInfo.from_node(node, f"Replace `{old}` with `{new}`"))
|