From bdc347e28c88cf491436f5be26c574219fb15cdb Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sun, 12 Feb 2023 00:50:28 +0100 Subject: [PATCH] progress --- README.md | 32 +-- .../fixtures/flake8_use_pathlib/full_name.py | 10 +- .../flake8_use_pathlib/use_pathlib.py | 3 + crates/ruff/src/checkers/ast.rs | 1 + .../src/rules/flake8_use_pathlib/fixes.rs | 133 +++++++---- .../src/rules/flake8_use_pathlib/helpers.rs | 11 +- ...e_pathlib__tests__PTH124_py_path_1.py.snap | 4 +- ...e_pathlib__tests__PTH124_py_path_2.py.snap | 4 +- ...ake8_use_pathlib__tests__full_name.py.snap | 214 +++++++++++++----- ...flake8_use_pathlib__tests__guarded.py.snap | 52 ++--- ...ake8_use_pathlib__tests__import_as.py.snap | 194 ++++++++++++---- ...e8_use_pathlib__tests__import_from.py.snap | 198 ++++++++++++---- ...use_pathlib__tests__import_from_as.py.snap | 194 ++++++++++++---- ...s__flake8_use_pathlib__tests__stat.py.snap | 26 +-- ...e8_use_pathlib__tests__use_pathlib.py.snap | 55 ++--- .../rules/flake8_use_pathlib/violations.rs | 131 ++++++++++- docs/rules/pathlib-getcwd.md | 3 + docs/rules/pathlib-readlink.md | 32 +++ resources/test/popmon | 1 + 19 files changed, 975 insertions(+), 323 deletions(-) create mode 100644 docs/rules/pathlib-readlink.md create mode 160000 resources/test/popmon diff --git a/README.md b/README.md index 5eaaf116a40667..51dfebd8f9f0c5 100644 --- a/README.md +++ b/README.md @@ -1281,28 +1281,28 @@ For more, see [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/) | Code | Name | Message | Fix | | ---- | ---- | ------- | --- | -| PTH100 | pathlib-abspath | `os.path.abspath` should be replaced by `.resolve()` | | -| PTH101 | pathlib-chmod | `os.chmod` should be replaced by `.chmod()` | | -| PTH102 | pathlib-mkdir | `os.mkdir` should be replaced by `.mkdir()` | | +| PTH100 | pathlib-abspath | `os.path.abspath` should be replaced by `.resolve()` | 🛠 | +| PTH101 | pathlib-chmod | `os.chmod` should be replaced by `.chmod()` | 🛠 | +| PTH102 | pathlib-mkdir | `os.mkdir` should be replaced by `.mkdir()` | 🛠 | | PTH103 | pathlib-makedirs | `os.makedirs` should be replaced by `.mkdir(parents=True)` | | -| PTH104 | pathlib-rename | `os.rename` should be replaced by `.rename()` | | -| PTH105 | pathlib-replace | `os.replace`should be replaced by `.replace()` | | -| PTH106 | pathlib-rmdir | `os.rmdir` should be replaced by `.rmdir()` | | -| PTH107 | pathlib-remove | `os.remove` should be replaced by `.unlink()` | | -| PTH108 | pathlib-unlink | `os.unlink` should be replaced by `.unlink()` | | +| PTH104 | pathlib-rename | `os.rename` should be replaced by `.rename()` | 🛠 | +| PTH105 | pathlib-replace | `os.replace`should be replaced by `.replace()` | 🛠 | +| PTH106 | pathlib-rmdir | `os.rmdir` should be replaced by `.rmdir()` | 🛠 | +| PTH107 | pathlib-remove | `os.remove` should be replaced by `.unlink()` | 🛠 | +| PTH108 | pathlib-unlink | `os.unlink` should be replaced by `.unlink()` | 🛠 | | PTH109 | [pathlib-getcwd](https://github.com/charliermarsh/ruff/blob/main/docs/rules/pathlib-getcwd.md) | `os.getcwd` should be replaced by `Path.cwd()` | 🛠 | -| PTH110 | pathlib-exists | `os.path.exists` should be replaced by `.exists()` | | -| PTH111 | pathlib-expanduser | `os.path.expanduser` should be replaced by `.expanduser()` | | -| PTH112 | pathlib-is-dir | `os.path.isdir` should be replaced by `.is_dir()` | | -| PTH113 | pathlib-is-file | `os.path.isfile` should be replaced by `.is_file()` | | -| PTH114 | pathlib-is-link | `os.path.islink` should be replaced by `.is_symlink()` | | -| PTH115 | pathlib-readlink | `os.readlink` should be replaced by `.readlink()` | | +| PTH110 | pathlib-exists | `os.path.exists` should be replaced by `.exists()` | 🛠 | +| PTH111 | pathlib-expanduser | `os.path.expanduser` should be replaced by `.expanduser()` | 🛠 | +| PTH112 | pathlib-is-dir | `os.path.isdir` should be replaced by `.is_dir()` | 🛠 | +| PTH113 | pathlib-is-file | `os.path.isfile` should be replaced by `.is_file()` | 🛠 | +| PTH114 | pathlib-is-link | `os.path.islink` should be replaced by `.is_symlink()` | 🛠 | +| PTH115 | [pathlib-readlink](https://github.com/charliermarsh/ruff/blob/main/docs/rules/pathlib-readlink.md) | `os.readlink` should be replaced by `.readlink()` | 🛠 | | PTH116 | pathlib-stat | `os.stat` should be replaced by `.stat()` or `.owner()` or `.group()` | | -| PTH117 | pathlib-is-abs | `os.path.isabs` should be replaced by `.is_absolute()` | | +| PTH117 | pathlib-is-abs | `os.path.isabs` should be replaced by `.is_absolute()` | 🛠 | | PTH118 | pathlib-join | `os.path.join` should be replaced by `foo_path / "bar"` | | | PTH119 | pathlib-basename | `os.path.basename` should be replaced by `.name` | | | PTH120 | pathlib-dirname | `os.path.dirname` should be replaced by `.parent` | | -| PTH121 | pathlib-samefile | `os.path.samefile` should be replaced by `.samefile()` | | +| PTH121 | pathlib-samefile | `os.path.samefile` should be replaced by `.samefile()` | 🛠 | | PTH122 | pathlib-splitext | `os.path.splitext` should be replaced by `.suffix` | | | PTH123 | pathlib-open | `open("foo")` should be replaced by `Path("foo").open()` | | | PTH124 | pathlib-py-path | `py.path` is in maintenance mode, use `pathlib` instead | | diff --git a/crates/ruff/resources/test/fixtures/flake8_use_pathlib/full_name.py b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/full_name.py index 65064c8d57fc4b..4e45512a3ffe42 100644 --- a/crates/ruff/resources/test/fixtures/flake8_use_pathlib/full_name.py +++ b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/full_name.py @@ -5,15 +5,15 @@ p = "/foo" a = os.path.abspath(p) -aa = os.chmod(p) +aa = os.chmod(p, mode=511) aaa = os.mkdir(p) os.makedirs(p) -os.rename(p) -os.replace(p) +os.rename(p, q) +os.replace(p, q) os.rmdir(p) os.remove(p) os.unlink(p) -os.getcwd(p) +os.getcwd() b = os.path.exists(p) bb = os.path.expanduser(p) bbb = os.path.isdir(p) @@ -30,4 +30,4 @@ with open(p) as fp: fp.read() open(p).close() -os.getcwdb(p) +os.getcwdb() diff --git a/crates/ruff/resources/test/fixtures/flake8_use_pathlib/use_pathlib.py b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/use_pathlib.py index 8298db4b3aaaf2..462ad304cd8e6b 100644 --- a/crates/ruff/resources/test/fixtures/flake8_use_pathlib/use_pathlib.py +++ b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/use_pathlib.py @@ -16,3 +16,6 @@ # should not be unwrapped _ = Path(os.getcwd(), hello='world') + +# other cases +os.path.abspath("../../hello.py") diff --git a/crates/ruff/src/checkers/ast.rs b/crates/ruff/src/checkers/ast.rs index fb87b286690156..2030747047c17d 100644 --- a/crates/ruff/src/checkers/ast.rs +++ b/crates/ruff/src/checkers/ast.rs @@ -2758,6 +2758,7 @@ where { flake8_use_pathlib::helpers::replaceable_by_pathlib( self, + expr, func, self.current_expr_parent().map(Into::into), ); diff --git a/crates/ruff/src/rules/flake8_use_pathlib/fixes.rs b/crates/ruff/src/rules/flake8_use_pathlib/fixes.rs index 74e67a003715c0..fb093e95ed5a20 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/fixes.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/fixes.rs @@ -1,6 +1,6 @@ -use rustpython_parser::ast::{Expr, ExprKind}; +use rustpython_parser::ast::{Expr, ExprContext, ExprKind}; -use crate::ast::helpers; +use crate::ast::helpers::{self, create_expr, unparse_expr}; use crate::ast::types::Range; use crate::autofix::apply_fix; use crate::checkers::ast::Checker; @@ -11,56 +11,111 @@ use crate::source_code::Locator; pub fn pathlib_fix( checker: &mut Checker, diagnostic: &DiagnosticKind, + expr: &Expr, func: &Expr, parent: Option<&Expr>, ) -> Option { // Guard that Path is imported, `content` contains the name or aliaas if let Some(content) = helpers::get_member_import_name_alias(checker, "pathlib", "Path") { - let mut fix = match diagnostic { - DiagnosticKind::PathlibGetcwd(_) => Some(Fix::replacement( - format!("{content}.cwd"), - func.location, - func.end_location.unwrap(), - )), - _ => None, - }; + if let ExprKind::Call { args, keywords, .. } = &expr.node { + // TODO: validate args/keywords, possibly map + // TODO: add non-call replacements + let replacement = match diagnostic { + DiagnosticKind::PathlibAbspath(_) => "resolve", + DiagnosticKind::PathlibChmod(_) => "chmod", + DiagnosticKind::PathlibMkdir(_) => "mkdir", + // Makedirs + DiagnosticKind::PathlibRename(_) => "rename", + DiagnosticKind::PathlibReplace(_) => "replace", + DiagnosticKind::PathlibRmdir(_) => "rmdir", + DiagnosticKind::PathlibRemove(_) => "unlink", + DiagnosticKind::PathlibUnlink(_) => "unlink", + DiagnosticKind::PathlibGetcwd(_) => "cwd", + DiagnosticKind::PathlibExists(_) => "exists", + DiagnosticKind::PathlibExpanduser(_) => "expanduser", + DiagnosticKind::PathlibIsDir(_) => "is_dir", + DiagnosticKind::PathlibIsFile(_) => "is_file", + DiagnosticKind::PathlibIsLink(_) => "is_symlink", + DiagnosticKind::PathlibReadlink(_) => "readlink", + // Stat + DiagnosticKind::PathlibIsAbs(_) => "is_absolute", + // Join + // Basename + // Dirname + DiagnosticKind::PathlibSamefile(_) => "samefile", + // Splitext + // Open + _ => return None, + }; - // Wrapped in a `Path()` call - if let Some(fixme) = fix.clone() { - if let Some(parent) = parent { - if checker - .resolve_call_path(parent) - .map_or(false, |call_path| { - call_path.as_slice() == ["pathlib", "Path"] - }) - { - if let ExprKind::Call { args, keywords, .. } = &parent.node { - if args.len() == 1 && keywords.is_empty() { - // Reset the line index - let fixme = Fix::replacement( - fixme.content.to_string(), - helpers::to_relative(fixme.location, func.location), - helpers::to_relative(fixme.end_location, func.location), - ); + if let Some((head, tail)) = args.clone().split_first() { + let fix_str = unparse_expr( + &create_expr(ExprKind::Call { + func: Box::new(create_expr(ExprKind::Attribute { + value: Box::new(create_expr(ExprKind::Call { + func: Box::new(create_expr(ExprKind::Name { + id: content, + ctx: ExprContext::Load, + })), + args: vec![head.clone()], + keywords: vec![], + })), + attr: replacement.to_string(), + ctx: ExprContext::Load, + })), + args: tail.to_vec(), + keywords: keywords.clone(), + }), + checker.stylist, + ); - // Apply the fix - let arg = args.first().unwrap(); - let contents = checker.locator.slice_source_code_range(&Range::new( - arg.location, - arg.end_location.unwrap(), - )); + let mut fix = Some(Fix::replacement( + fix_str, + expr.location, + expr.end_location.unwrap(), + )); - fix = Some(Fix::replacement( - apply_fix(&fixme, &Locator::new(contents)), - parent.location, - parent.end_location.unwrap(), - )); + // Wrapped in a `Path()` call + if let Some(fixme) = fix.clone() { + if let Some(parent) = parent { + if checker + .resolve_call_path(parent) + .map_or(false, |call_path| { + call_path.as_slice() == ["pathlib", "Path"] + }) + { + if let ExprKind::Call { args, keywords, .. } = &parent.node { + if args.len() == 1 && keywords.is_empty() { + // Reset the line index + let fixme = Fix::replacement( + fixme.content.to_string(), + helpers::to_relative(fixme.location, func.location), + helpers::to_relative(fixme.end_location, func.location), + ); + + // Apply the fix + let arg = args.first().unwrap(); + let contents = checker.locator.slice_source_code_range( + &Range::new(arg.location, arg.end_location.unwrap()), + ); + + fix = Some(Fix::replacement( + apply_fix(&fixme, &Locator::new(contents)), + parent.location, + parent.end_location.unwrap(), + )); + } + } } } } + fix + } else { + None } + } else { + None } - fix } else { None } diff --git a/crates/ruff/src/rules/flake8_use_pathlib/helpers.rs b/crates/ruff/src/rules/flake8_use_pathlib/helpers.rs index eb6e9c22c5da33..f8aa328f9e1f6f 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/helpers.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/helpers.rs @@ -14,10 +14,15 @@ use crate::rules::flake8_use_pathlib::violations::{ }; use crate::settings::types::PythonVersion; -pub fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr, parent: Option<&Expr>) { +pub fn replaceable_by_pathlib( + checker: &mut Checker, + expr: &Expr, + func: &Expr, + parent: Option<&Expr>, +) { if let Some(diagnostic_kind) = checker - .resolve_call_path(expr) + .resolve_call_path(func) .and_then(|call_path| match call_path.as_slice() { ["os", "path", "abspath"] => Some(PathlibAbspath.into()), ["os", "chmod"] => Some(PathlibChmod.into()), @@ -58,7 +63,7 @@ pub fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr, parent: Option let mut diagnostic = Diagnostic::new::(diagnostic_kind, Range::from_located(expr)); if checker.patch(diagnostic.kind.rule()) { - if let Some(fix) = pathlib_fix(checker, &diagnostic.kind, expr, parent) { + if let Some(fix) = pathlib_fix(checker, &diagnostic.kind, expr, func, parent) { diagnostic.amend(fix); } } diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_1.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_1.py.snap index b27363952472b1..800fbbd4780737 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_1.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_1.py.snap @@ -1,5 +1,5 @@ --- -source: src/rules/flake8_use_pathlib/mod.rs +source: crates/ruff/src/rules/flake8_use_pathlib/mod.rs expression: diagnostics --- - kind: @@ -9,7 +9,7 @@ expression: diagnostics column: 4 end_location: row: 3 - column: 17 + column: 27 fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_2.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_2.py.snap index c5f6ad5501c67c..7a7a6f0440a543 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_2.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH124_py_path_2.py.snap @@ -1,5 +1,5 @@ --- -source: src/rules/flake8_use_pathlib/mod.rs +source: crates/ruff/src/rules/flake8_use_pathlib/mod.rs expression: diagnostics --- - kind: @@ -9,7 +9,7 @@ expression: diagnostics column: 4 end_location: row: 3 - column: 8 + column: 16 fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__full_name.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__full_name.py.snap index 2da1d596753c35..4af258a54f2b3b 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__full_name.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__full_name.py.snap @@ -9,8 +9,15 @@ expression: diagnostics column: 4 end_location: row: 7 - column: 19 - fix: ~ + column: 22 + fix: + content: pathlib.Path(p).resolve() + location: + row: 7 + column: 4 + end_location: + row: 7 + column: 22 parent: ~ - kind: PathlibChmod: ~ @@ -19,8 +26,15 @@ expression: diagnostics column: 5 end_location: row: 8 - column: 13 - fix: ~ + column: 26 + fix: + content: pathlib.Path(p).chmod(mode=511) + location: + row: 8 + column: 5 + end_location: + row: 8 + column: 26 parent: ~ - kind: PathlibMkdir: ~ @@ -29,8 +43,15 @@ expression: diagnostics column: 6 end_location: row: 9 - column: 14 - fix: ~ + column: 17 + fix: + content: pathlib.Path(p).mkdir() + location: + row: 9 + column: 6 + end_location: + row: 9 + column: 17 parent: ~ - kind: PathlibMakedirs: ~ @@ -39,7 +60,7 @@ expression: diagnostics column: 0 end_location: row: 10 - column: 11 + column: 14 fix: ~ parent: ~ - kind: @@ -49,8 +70,15 @@ expression: diagnostics column: 0 end_location: row: 11 - column: 9 - fix: ~ + column: 15 + fix: + content: pathlib.Path(p).rename(q) + location: + row: 11 + column: 0 + end_location: + row: 11 + column: 15 parent: ~ - kind: PathlibReplace: ~ @@ -59,8 +87,15 @@ expression: diagnostics column: 0 end_location: row: 12 - column: 10 - fix: ~ + column: 16 + fix: + content: pathlib.Path(p).replace(q) + location: + row: 12 + column: 0 + end_location: + row: 12 + column: 16 parent: ~ - kind: PathlibRmdir: ~ @@ -69,8 +104,15 @@ expression: diagnostics column: 0 end_location: row: 13 - column: 8 - fix: ~ + column: 11 + fix: + content: pathlib.Path(p).rmdir() + location: + row: 13 + column: 0 + end_location: + row: 13 + column: 11 parent: ~ - kind: PathlibRemove: ~ @@ -79,8 +121,15 @@ expression: diagnostics column: 0 end_location: row: 14 - column: 9 - fix: ~ + column: 12 + fix: + content: pathlib.Path(p).unlink() + location: + row: 14 + column: 0 + end_location: + row: 14 + column: 12 parent: ~ - kind: PathlibUnlink: ~ @@ -89,8 +138,15 @@ expression: diagnostics column: 0 end_location: row: 15 - column: 9 - fix: ~ + column: 12 + fix: + content: pathlib.Path(p).unlink() + location: + row: 15 + column: 0 + end_location: + row: 15 + column: 12 parent: ~ - kind: PathlibGetcwd: ~ @@ -99,15 +155,8 @@ expression: diagnostics column: 0 end_location: row: 16 - column: 9 - fix: - content: pathlib.Path.cwd - location: - row: 16 - column: 0 - end_location: - row: 16 - column: 9 + column: 11 + fix: ~ parent: ~ - kind: PathlibExists: ~ @@ -116,8 +165,15 @@ expression: diagnostics column: 4 end_location: row: 17 - column: 18 - fix: ~ + column: 21 + fix: + content: pathlib.Path(p).exists() + location: + row: 17 + column: 4 + end_location: + row: 17 + column: 21 parent: ~ - kind: PathlibExpanduser: ~ @@ -126,8 +182,15 @@ expression: diagnostics column: 5 end_location: row: 18 - column: 23 - fix: ~ + column: 26 + fix: + content: pathlib.Path(p).expanduser() + location: + row: 18 + column: 5 + end_location: + row: 18 + column: 26 parent: ~ - kind: PathlibIsDir: ~ @@ -136,8 +199,15 @@ expression: diagnostics column: 6 end_location: row: 19 - column: 19 - fix: ~ + column: 22 + fix: + content: pathlib.Path(p).is_dir() + location: + row: 19 + column: 6 + end_location: + row: 19 + column: 22 parent: ~ - kind: PathlibIsFile: ~ @@ -146,8 +216,15 @@ expression: diagnostics column: 7 end_location: row: 20 - column: 21 - fix: ~ + column: 24 + fix: + content: pathlib.Path(p).is_file() + location: + row: 20 + column: 7 + end_location: + row: 20 + column: 24 parent: ~ - kind: PathlibIsLink: ~ @@ -156,8 +233,15 @@ expression: diagnostics column: 8 end_location: row: 21 - column: 22 - fix: ~ + column: 25 + fix: + content: pathlib.Path(p).is_symlink() + location: + row: 21 + column: 8 + end_location: + row: 21 + column: 25 parent: ~ - kind: PathlibReadlink: ~ @@ -166,8 +250,15 @@ expression: diagnostics column: 0 end_location: row: 22 - column: 11 - fix: ~ + column: 14 + fix: + content: pathlib.Path(p).readlink() + location: + row: 22 + column: 0 + end_location: + row: 22 + column: 14 parent: ~ - kind: PathlibStat: ~ @@ -176,7 +267,7 @@ expression: diagnostics column: 0 end_location: row: 23 - column: 7 + column: 10 fix: ~ parent: ~ - kind: @@ -186,8 +277,15 @@ expression: diagnostics column: 0 end_location: row: 24 - column: 13 - fix: ~ + column: 16 + fix: + content: pathlib.Path(p).is_absolute() + location: + row: 24 + column: 0 + end_location: + row: 24 + column: 16 parent: ~ - kind: PathlibJoin: ~ @@ -196,7 +294,7 @@ expression: diagnostics column: 0 end_location: row: 25 - column: 12 + column: 15 fix: ~ parent: ~ - kind: @@ -206,7 +304,7 @@ expression: diagnostics column: 0 end_location: row: 26 - column: 16 + column: 19 fix: ~ parent: ~ - kind: @@ -216,7 +314,7 @@ expression: diagnostics column: 0 end_location: row: 27 - column: 15 + column: 18 fix: ~ parent: ~ - kind: @@ -226,8 +324,15 @@ expression: diagnostics column: 0 end_location: row: 28 - column: 16 - fix: ~ + column: 19 + fix: + content: pathlib.Path(p).samefile() + location: + row: 28 + column: 0 + end_location: + row: 28 + column: 19 parent: ~ - kind: PathlibSplitext: ~ @@ -236,7 +341,7 @@ expression: diagnostics column: 0 end_location: row: 29 - column: 16 + column: 19 fix: ~ parent: ~ - kind: @@ -246,7 +351,7 @@ expression: diagnostics column: 5 end_location: row: 30 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -256,7 +361,7 @@ expression: diagnostics column: 0 end_location: row: 32 - column: 4 + column: 7 fix: ~ parent: ~ - kind: @@ -266,14 +371,7 @@ expression: diagnostics column: 0 end_location: row: 33 - column: 10 - fix: - content: pathlib.Path.cwd - location: - row: 33 - column: 0 - end_location: - row: 33 - column: 10 + column: 12 + fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__guarded.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__guarded.py.snap index 9de06dabe88d09..1bebc9f83ae576 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__guarded.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__guarded.py.snap @@ -9,7 +9,7 @@ expression: diagnostics column: 4 end_location: row: 8 - column: 19 + column: 22 fix: ~ parent: ~ - kind: @@ -19,7 +19,7 @@ expression: diagnostics column: 5 end_location: row: 9 - column: 13 + column: 16 fix: ~ parent: ~ - kind: @@ -29,7 +29,7 @@ expression: diagnostics column: 6 end_location: row: 10 - column: 14 + column: 17 fix: ~ parent: ~ - kind: @@ -39,7 +39,7 @@ expression: diagnostics column: 0 end_location: row: 11 - column: 11 + column: 14 fix: ~ parent: ~ - kind: @@ -49,7 +49,7 @@ expression: diagnostics column: 0 end_location: row: 12 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -59,7 +59,7 @@ expression: diagnostics column: 0 end_location: row: 13 - column: 10 + column: 13 fix: ~ parent: ~ - kind: @@ -69,7 +69,7 @@ expression: diagnostics column: 0 end_location: row: 14 - column: 8 + column: 11 fix: ~ parent: ~ - kind: @@ -79,7 +79,7 @@ expression: diagnostics column: 0 end_location: row: 15 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -89,7 +89,7 @@ expression: diagnostics column: 0 end_location: row: 16 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -99,7 +99,7 @@ expression: diagnostics column: 0 end_location: row: 17 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -109,7 +109,7 @@ expression: diagnostics column: 4 end_location: row: 18 - column: 18 + column: 21 fix: ~ parent: ~ - kind: @@ -119,7 +119,7 @@ expression: diagnostics column: 5 end_location: row: 19 - column: 23 + column: 26 fix: ~ parent: ~ - kind: @@ -129,7 +129,7 @@ expression: diagnostics column: 6 end_location: row: 20 - column: 19 + column: 22 fix: ~ parent: ~ - kind: @@ -139,7 +139,7 @@ expression: diagnostics column: 7 end_location: row: 21 - column: 21 + column: 24 fix: ~ parent: ~ - kind: @@ -149,7 +149,7 @@ expression: diagnostics column: 8 end_location: row: 22 - column: 22 + column: 25 fix: ~ parent: ~ - kind: @@ -159,7 +159,7 @@ expression: diagnostics column: 0 end_location: row: 23 - column: 11 + column: 14 fix: ~ parent: ~ - kind: @@ -169,7 +169,7 @@ expression: diagnostics column: 0 end_location: row: 24 - column: 7 + column: 10 fix: ~ parent: ~ - kind: @@ -179,7 +179,7 @@ expression: diagnostics column: 0 end_location: row: 25 - column: 13 + column: 16 fix: ~ parent: ~ - kind: @@ -189,7 +189,7 @@ expression: diagnostics column: 0 end_location: row: 26 - column: 12 + column: 15 fix: ~ parent: ~ - kind: @@ -199,7 +199,7 @@ expression: diagnostics column: 0 end_location: row: 27 - column: 16 + column: 19 fix: ~ parent: ~ - kind: @@ -209,7 +209,7 @@ expression: diagnostics column: 0 end_location: row: 28 - column: 15 + column: 18 fix: ~ parent: ~ - kind: @@ -219,7 +219,7 @@ expression: diagnostics column: 0 end_location: row: 29 - column: 16 + column: 19 fix: ~ parent: ~ - kind: @@ -229,7 +229,7 @@ expression: diagnostics column: 0 end_location: row: 30 - column: 16 + column: 19 fix: ~ parent: ~ - kind: @@ -239,7 +239,7 @@ expression: diagnostics column: 5 end_location: row: 31 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -249,7 +249,7 @@ expression: diagnostics column: 0 end_location: row: 33 - column: 4 + column: 7 fix: ~ parent: ~ - kind: @@ -259,7 +259,7 @@ expression: diagnostics column: 0 end_location: row: 34 - column: 10 + column: 13 fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_as.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_as.py.snap index fc9ab5ab10abc3..32dfdc8abc43ae 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_as.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_as.py.snap @@ -9,8 +9,15 @@ expression: diagnostics column: 4 end_location: row: 7 - column: 17 - fix: ~ + column: 20 + fix: + content: pth.Path(p).resolve() + location: + row: 7 + column: 4 + end_location: + row: 7 + column: 20 parent: ~ - kind: PathlibChmod: ~ @@ -19,8 +26,15 @@ expression: diagnostics column: 5 end_location: row: 8 - column: 14 - fix: ~ + column: 17 + fix: + content: pth.Path(p).chmod() + location: + row: 8 + column: 5 + end_location: + row: 8 + column: 17 parent: ~ - kind: PathlibMkdir: ~ @@ -29,8 +43,15 @@ expression: diagnostics column: 6 end_location: row: 9 - column: 15 - fix: ~ + column: 18 + fix: + content: pth.Path(p).mkdir() + location: + row: 9 + column: 6 + end_location: + row: 9 + column: 18 parent: ~ - kind: PathlibMakedirs: ~ @@ -39,7 +60,7 @@ expression: diagnostics column: 0 end_location: row: 10 - column: 12 + column: 15 fix: ~ parent: ~ - kind: @@ -49,8 +70,15 @@ expression: diagnostics column: 0 end_location: row: 11 - column: 10 - fix: ~ + column: 13 + fix: + content: pth.Path(p).rename() + location: + row: 11 + column: 0 + end_location: + row: 11 + column: 13 parent: ~ - kind: PathlibReplace: ~ @@ -59,8 +87,15 @@ expression: diagnostics column: 0 end_location: row: 12 - column: 11 - fix: ~ + column: 14 + fix: + content: pth.Path(p).replace() + location: + row: 12 + column: 0 + end_location: + row: 12 + column: 14 parent: ~ - kind: PathlibRmdir: ~ @@ -69,8 +104,15 @@ expression: diagnostics column: 0 end_location: row: 13 - column: 9 - fix: ~ + column: 12 + fix: + content: pth.Path(p).rmdir() + location: + row: 13 + column: 0 + end_location: + row: 13 + column: 12 parent: ~ - kind: PathlibRemove: ~ @@ -79,8 +121,15 @@ expression: diagnostics column: 0 end_location: row: 14 - column: 10 - fix: ~ + column: 13 + fix: + content: pth.Path(p).unlink() + location: + row: 14 + column: 0 + end_location: + row: 14 + column: 13 parent: ~ - kind: PathlibUnlink: ~ @@ -89,8 +138,15 @@ expression: diagnostics column: 0 end_location: row: 15 - column: 10 - fix: ~ + column: 13 + fix: + content: pth.Path(p).unlink() + location: + row: 15 + column: 0 + end_location: + row: 15 + column: 13 parent: ~ - kind: PathlibGetcwd: ~ @@ -99,15 +155,15 @@ expression: diagnostics column: 0 end_location: row: 16 - column: 10 + column: 13 fix: - content: pth.Path.cwd + content: pth.Path(p).cwd() location: row: 16 column: 0 end_location: row: 16 - column: 10 + column: 13 parent: ~ - kind: PathlibExists: ~ @@ -116,8 +172,15 @@ expression: diagnostics column: 4 end_location: row: 17 - column: 16 - fix: ~ + column: 19 + fix: + content: pth.Path(p).exists() + location: + row: 17 + column: 4 + end_location: + row: 17 + column: 19 parent: ~ - kind: PathlibExpanduser: ~ @@ -126,8 +189,15 @@ expression: diagnostics column: 5 end_location: row: 18 - column: 21 - fix: ~ + column: 24 + fix: + content: pth.Path(p).expanduser() + location: + row: 18 + column: 5 + end_location: + row: 18 + column: 24 parent: ~ - kind: PathlibIsDir: ~ @@ -136,8 +206,15 @@ expression: diagnostics column: 6 end_location: row: 19 - column: 17 - fix: ~ + column: 20 + fix: + content: pth.Path(p).is_dir() + location: + row: 19 + column: 6 + end_location: + row: 19 + column: 20 parent: ~ - kind: PathlibIsFile: ~ @@ -146,8 +223,15 @@ expression: diagnostics column: 7 end_location: row: 20 - column: 19 - fix: ~ + column: 22 + fix: + content: pth.Path(p).is_file() + location: + row: 20 + column: 7 + end_location: + row: 20 + column: 22 parent: ~ - kind: PathlibIsLink: ~ @@ -156,8 +240,15 @@ expression: diagnostics column: 8 end_location: row: 21 - column: 20 - fix: ~ + column: 23 + fix: + content: pth.Path(p).is_symlink() + location: + row: 21 + column: 8 + end_location: + row: 21 + column: 23 parent: ~ - kind: PathlibReadlink: ~ @@ -166,8 +257,15 @@ expression: diagnostics column: 0 end_location: row: 22 - column: 12 - fix: ~ + column: 15 + fix: + content: pth.Path(p).readlink() + location: + row: 22 + column: 0 + end_location: + row: 22 + column: 15 parent: ~ - kind: PathlibStat: ~ @@ -176,7 +274,7 @@ expression: diagnostics column: 0 end_location: row: 23 - column: 8 + column: 11 fix: ~ parent: ~ - kind: @@ -186,8 +284,15 @@ expression: diagnostics column: 0 end_location: row: 24 - column: 11 - fix: ~ + column: 14 + fix: + content: pth.Path(p).is_absolute() + location: + row: 24 + column: 0 + end_location: + row: 24 + column: 14 parent: ~ - kind: PathlibJoin: ~ @@ -196,7 +301,7 @@ expression: diagnostics column: 0 end_location: row: 25 - column: 10 + column: 13 fix: ~ parent: ~ - kind: @@ -206,7 +311,7 @@ expression: diagnostics column: 0 end_location: row: 26 - column: 14 + column: 17 fix: ~ parent: ~ - kind: @@ -216,7 +321,7 @@ expression: diagnostics column: 0 end_location: row: 27 - column: 13 + column: 16 fix: ~ parent: ~ - kind: @@ -226,8 +331,15 @@ expression: diagnostics column: 0 end_location: row: 28 - column: 14 - fix: ~ + column: 17 + fix: + content: pth.Path(p).samefile() + location: + row: 28 + column: 0 + end_location: + row: 28 + column: 17 parent: ~ - kind: PathlibSplitext: ~ @@ -236,7 +348,7 @@ expression: diagnostics column: 0 end_location: row: 29 - column: 14 + column: 17 fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from.py.snap index 16d86722760afc..756aeaefdf9147 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from.py.snap @@ -9,8 +9,15 @@ expression: diagnostics column: 4 end_location: row: 9 - column: 11 - fix: ~ + column: 14 + fix: + content: Path(p).resolve() + location: + row: 9 + column: 4 + end_location: + row: 9 + column: 14 parent: ~ - kind: PathlibChmod: ~ @@ -19,8 +26,15 @@ expression: diagnostics column: 5 end_location: row: 10 - column: 10 - fix: ~ + column: 13 + fix: + content: Path(p).chmod() + location: + row: 10 + column: 5 + end_location: + row: 10 + column: 13 parent: ~ - kind: PathlibMkdir: ~ @@ -29,8 +43,15 @@ expression: diagnostics column: 6 end_location: row: 11 - column: 11 - fix: ~ + column: 14 + fix: + content: Path(p).mkdir() + location: + row: 11 + column: 6 + end_location: + row: 11 + column: 14 parent: ~ - kind: PathlibMakedirs: ~ @@ -39,7 +60,7 @@ expression: diagnostics column: 0 end_location: row: 12 - column: 8 + column: 11 fix: ~ parent: ~ - kind: @@ -49,8 +70,15 @@ expression: diagnostics column: 0 end_location: row: 13 - column: 6 - fix: ~ + column: 9 + fix: + content: Path(p).rename() + location: + row: 13 + column: 0 + end_location: + row: 13 + column: 9 parent: ~ - kind: PathlibReplace: ~ @@ -59,8 +87,15 @@ expression: diagnostics column: 0 end_location: row: 14 - column: 7 - fix: ~ + column: 10 + fix: + content: Path(p).replace() + location: + row: 14 + column: 0 + end_location: + row: 14 + column: 10 parent: ~ - kind: PathlibRmdir: ~ @@ -69,8 +104,15 @@ expression: diagnostics column: 0 end_location: row: 15 - column: 5 - fix: ~ + column: 8 + fix: + content: Path(p).rmdir() + location: + row: 15 + column: 0 + end_location: + row: 15 + column: 8 parent: ~ - kind: PathlibRemove: ~ @@ -79,8 +121,15 @@ expression: diagnostics column: 0 end_location: row: 16 - column: 6 - fix: ~ + column: 9 + fix: + content: Path(p).unlink() + location: + row: 16 + column: 0 + end_location: + row: 16 + column: 9 parent: ~ - kind: PathlibUnlink: ~ @@ -89,8 +138,15 @@ expression: diagnostics column: 0 end_location: row: 17 - column: 6 - fix: ~ + column: 9 + fix: + content: Path(p).unlink() + location: + row: 17 + column: 0 + end_location: + row: 17 + column: 9 parent: ~ - kind: PathlibGetcwd: ~ @@ -99,15 +155,15 @@ expression: diagnostics column: 0 end_location: row: 18 - column: 6 + column: 9 fix: - content: Path.cwd + content: Path(p).cwd() location: row: 18 column: 0 end_location: row: 18 - column: 6 + column: 9 parent: ~ - kind: PathlibExists: ~ @@ -116,8 +172,15 @@ expression: diagnostics column: 4 end_location: row: 19 - column: 10 - fix: ~ + column: 13 + fix: + content: Path(p).exists() + location: + row: 19 + column: 4 + end_location: + row: 19 + column: 13 parent: ~ - kind: PathlibExpanduser: ~ @@ -126,8 +189,15 @@ expression: diagnostics column: 5 end_location: row: 20 - column: 15 - fix: ~ + column: 18 + fix: + content: Path(p).expanduser() + location: + row: 20 + column: 5 + end_location: + row: 20 + column: 18 parent: ~ - kind: PathlibIsDir: ~ @@ -136,8 +206,15 @@ expression: diagnostics column: 6 end_location: row: 21 - column: 11 - fix: ~ + column: 14 + fix: + content: Path(p).is_dir() + location: + row: 21 + column: 6 + end_location: + row: 21 + column: 14 parent: ~ - kind: PathlibIsFile: ~ @@ -146,8 +223,15 @@ expression: diagnostics column: 7 end_location: row: 22 - column: 13 - fix: ~ + column: 16 + fix: + content: Path(p).is_file() + location: + row: 22 + column: 7 + end_location: + row: 22 + column: 16 parent: ~ - kind: PathlibIsLink: ~ @@ -156,8 +240,15 @@ expression: diagnostics column: 8 end_location: row: 23 - column: 14 - fix: ~ + column: 17 + fix: + content: Path(p).is_symlink() + location: + row: 23 + column: 8 + end_location: + row: 23 + column: 17 parent: ~ - kind: PathlibReadlink: ~ @@ -166,8 +257,15 @@ expression: diagnostics column: 0 end_location: row: 24 - column: 8 - fix: ~ + column: 11 + fix: + content: Path(p).readlink() + location: + row: 24 + column: 0 + end_location: + row: 24 + column: 11 parent: ~ - kind: PathlibStat: ~ @@ -176,7 +274,7 @@ expression: diagnostics column: 0 end_location: row: 25 - column: 4 + column: 7 fix: ~ parent: ~ - kind: @@ -186,8 +284,15 @@ expression: diagnostics column: 0 end_location: row: 26 - column: 5 - fix: ~ + column: 8 + fix: + content: Path(p).is_absolute() + location: + row: 26 + column: 0 + end_location: + row: 26 + column: 8 parent: ~ - kind: PathlibJoin: ~ @@ -196,7 +301,7 @@ expression: diagnostics column: 0 end_location: row: 27 - column: 4 + column: 7 fix: ~ parent: ~ - kind: @@ -206,7 +311,7 @@ expression: diagnostics column: 0 end_location: row: 28 - column: 8 + column: 11 fix: ~ parent: ~ - kind: @@ -216,7 +321,7 @@ expression: diagnostics column: 0 end_location: row: 29 - column: 7 + column: 10 fix: ~ parent: ~ - kind: @@ -226,8 +331,15 @@ expression: diagnostics column: 0 end_location: row: 30 - column: 8 - fix: ~ + column: 11 + fix: + content: Path(p).samefile() + location: + row: 30 + column: 0 + end_location: + row: 30 + column: 11 parent: ~ - kind: PathlibSplitext: ~ @@ -236,7 +348,7 @@ expression: diagnostics column: 0 end_location: row: 31 - column: 8 + column: 11 fix: ~ parent: ~ - kind: @@ -246,7 +358,7 @@ expression: diagnostics column: 5 end_location: row: 32 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -256,7 +368,7 @@ expression: diagnostics column: 0 end_location: row: 34 - column: 4 + column: 7 fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from_as.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from_as.py.snap index 0bdd522f746154..ecd6a2136ab43e 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from_as.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__import_from_as.py.snap @@ -9,8 +9,15 @@ expression: diagnostics column: 4 end_location: row: 14 - column: 12 - fix: ~ + column: 15 + fix: + content: pth(p).resolve() + location: + row: 14 + column: 4 + end_location: + row: 14 + column: 15 parent: ~ - kind: PathlibChmod: ~ @@ -19,8 +26,15 @@ expression: diagnostics column: 5 end_location: row: 15 - column: 11 - fix: ~ + column: 14 + fix: + content: pth(p).chmod() + location: + row: 15 + column: 5 + end_location: + row: 15 + column: 14 parent: ~ - kind: PathlibMkdir: ~ @@ -29,8 +43,15 @@ expression: diagnostics column: 6 end_location: row: 16 - column: 12 - fix: ~ + column: 15 + fix: + content: pth(p).mkdir() + location: + row: 16 + column: 6 + end_location: + row: 16 + column: 15 parent: ~ - kind: PathlibMakedirs: ~ @@ -39,7 +60,7 @@ expression: diagnostics column: 0 end_location: row: 17 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -49,8 +70,15 @@ expression: diagnostics column: 0 end_location: row: 18 - column: 7 - fix: ~ + column: 10 + fix: + content: pth(p).rename() + location: + row: 18 + column: 0 + end_location: + row: 18 + column: 10 parent: ~ - kind: PathlibReplace: ~ @@ -59,8 +87,15 @@ expression: diagnostics column: 0 end_location: row: 19 - column: 8 - fix: ~ + column: 11 + fix: + content: pth(p).replace() + location: + row: 19 + column: 0 + end_location: + row: 19 + column: 11 parent: ~ - kind: PathlibRmdir: ~ @@ -69,8 +104,15 @@ expression: diagnostics column: 0 end_location: row: 20 - column: 6 - fix: ~ + column: 9 + fix: + content: pth(p).rmdir() + location: + row: 20 + column: 0 + end_location: + row: 20 + column: 9 parent: ~ - kind: PathlibRemove: ~ @@ -79,8 +121,15 @@ expression: diagnostics column: 0 end_location: row: 21 - column: 7 - fix: ~ + column: 10 + fix: + content: pth(p).unlink() + location: + row: 21 + column: 0 + end_location: + row: 21 + column: 10 parent: ~ - kind: PathlibUnlink: ~ @@ -89,8 +138,15 @@ expression: diagnostics column: 0 end_location: row: 22 - column: 7 - fix: ~ + column: 10 + fix: + content: pth(p).unlink() + location: + row: 22 + column: 0 + end_location: + row: 22 + column: 10 parent: ~ - kind: PathlibGetcwd: ~ @@ -99,15 +155,15 @@ expression: diagnostics column: 0 end_location: row: 23 - column: 7 + column: 10 fix: - content: pth.cwd + content: pth(p).cwd() location: row: 23 column: 0 end_location: row: 23 - column: 7 + column: 10 parent: ~ - kind: PathlibExists: ~ @@ -116,8 +172,15 @@ expression: diagnostics column: 4 end_location: row: 24 - column: 11 - fix: ~ + column: 14 + fix: + content: pth(p).exists() + location: + row: 24 + column: 4 + end_location: + row: 24 + column: 14 parent: ~ - kind: PathlibExpanduser: ~ @@ -126,8 +189,15 @@ expression: diagnostics column: 5 end_location: row: 25 - column: 16 - fix: ~ + column: 19 + fix: + content: pth(p).expanduser() + location: + row: 25 + column: 5 + end_location: + row: 25 + column: 19 parent: ~ - kind: PathlibIsDir: ~ @@ -136,8 +206,15 @@ expression: diagnostics column: 6 end_location: row: 26 - column: 12 - fix: ~ + column: 15 + fix: + content: pth(p).is_dir() + location: + row: 26 + column: 6 + end_location: + row: 26 + column: 15 parent: ~ - kind: PathlibIsFile: ~ @@ -146,8 +223,15 @@ expression: diagnostics column: 7 end_location: row: 27 - column: 14 - fix: ~ + column: 17 + fix: + content: pth(p).is_file() + location: + row: 27 + column: 7 + end_location: + row: 27 + column: 17 parent: ~ - kind: PathlibIsLink: ~ @@ -156,8 +240,15 @@ expression: diagnostics column: 8 end_location: row: 28 - column: 15 - fix: ~ + column: 18 + fix: + content: pth(p).is_symlink() + location: + row: 28 + column: 8 + end_location: + row: 28 + column: 18 parent: ~ - kind: PathlibReadlink: ~ @@ -166,8 +257,15 @@ expression: diagnostics column: 0 end_location: row: 29 - column: 9 - fix: ~ + column: 12 + fix: + content: pth(p).readlink() + location: + row: 29 + column: 0 + end_location: + row: 29 + column: 12 parent: ~ - kind: PathlibStat: ~ @@ -176,7 +274,7 @@ expression: diagnostics column: 0 end_location: row: 30 - column: 5 + column: 8 fix: ~ parent: ~ - kind: @@ -186,8 +284,15 @@ expression: diagnostics column: 0 end_location: row: 31 - column: 6 - fix: ~ + column: 9 + fix: + content: pth(p).is_absolute() + location: + row: 31 + column: 0 + end_location: + row: 31 + column: 9 parent: ~ - kind: PathlibJoin: ~ @@ -196,7 +301,7 @@ expression: diagnostics column: 0 end_location: row: 32 - column: 5 + column: 8 fix: ~ parent: ~ - kind: @@ -206,7 +311,7 @@ expression: diagnostics column: 0 end_location: row: 33 - column: 9 + column: 12 fix: ~ parent: ~ - kind: @@ -216,7 +321,7 @@ expression: diagnostics column: 0 end_location: row: 34 - column: 8 + column: 11 fix: ~ parent: ~ - kind: @@ -226,8 +331,15 @@ expression: diagnostics column: 0 end_location: row: 35 - column: 9 - fix: ~ + column: 12 + fix: + content: pth(p).samefile() + location: + row: 35 + column: 0 + end_location: + row: 35 + column: 12 parent: ~ - kind: PathlibSplitext: ~ @@ -236,7 +348,7 @@ expression: diagnostics column: 0 end_location: row: 36 - column: 9 + column: 12 fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__stat.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__stat.py.snap index 908476ff1bc511..3e57c48a13eb9c 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__stat.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__stat.py.snap @@ -9,7 +9,7 @@ expression: diagnostics column: 0 end_location: row: 4 - column: 16 + column: 28 fix: ~ parent: ~ - kind: @@ -19,7 +19,7 @@ expression: diagnostics column: 0 end_location: row: 5 - column: 16 + column: 29 fix: ~ parent: ~ - kind: @@ -29,7 +29,7 @@ expression: diagnostics column: 0 end_location: row: 6 - column: 16 + column: 34 fix: ~ parent: ~ - kind: @@ -39,7 +39,7 @@ expression: diagnostics column: 0 end_location: row: 8 - column: 16 + column: 28 fix: ~ parent: ~ - kind: @@ -49,7 +49,7 @@ expression: diagnostics column: 0 end_location: row: 9 - column: 16 + column: 29 fix: ~ parent: ~ - kind: @@ -59,7 +59,7 @@ expression: diagnostics column: 0 end_location: row: 10 - column: 16 + column: 34 fix: ~ parent: ~ - kind: @@ -69,7 +69,7 @@ expression: diagnostics column: 0 end_location: row: 12 - column: 16 + column: 28 fix: ~ parent: ~ - kind: @@ -79,7 +79,7 @@ expression: diagnostics column: 0 end_location: row: 13 - column: 16 + column: 29 fix: ~ parent: ~ - kind: @@ -89,7 +89,7 @@ expression: diagnostics column: 0 end_location: row: 14 - column: 16 + column: 34 fix: ~ parent: ~ - kind: @@ -99,7 +99,7 @@ expression: diagnostics column: 0 end_location: row: 16 - column: 15 + column: 27 fix: ~ parent: ~ - kind: @@ -109,7 +109,7 @@ expression: diagnostics column: 0 end_location: row: 17 - column: 15 + column: 28 fix: ~ parent: ~ - kind: @@ -119,7 +119,7 @@ expression: diagnostics column: 0 end_location: row: 18 - column: 15 + column: 33 fix: ~ parent: ~ - kind: @@ -129,7 +129,7 @@ expression: diagnostics column: 0 end_location: row: 19 - column: 15 + column: 25 fix: ~ parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__use_pathlib.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__use_pathlib.py.snap index 5c13987c28ea2f..405d421abe7ab6 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__use_pathlib.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__use_pathlib.py.snap @@ -9,15 +9,8 @@ expression: diagnostics column: 9 end_location: row: 6 - column: 18 - fix: - content: Path.cwd - location: - row: 6 - column: 9 - end_location: - row: 6 - column: 18 + column: 20 + fix: ~ parent: ~ - kind: PathlibGetcwd: ~ @@ -26,15 +19,8 @@ expression: diagnostics column: 4 end_location: row: 10 - column: 14 - fix: - content: Path.cwd - location: - row: 9 - column: 4 - end_location: - row: 10 - column: 14 + column: 16 + fix: ~ parent: ~ - kind: PathlibGetcwd: ~ @@ -43,15 +29,8 @@ expression: diagnostics column: 4 end_location: row: 14 - column: 14 - fix: - content: Path.cwd - location: - row: 14 - column: 4 - end_location: - row: 14 - column: 14 + column: 16 + fix: ~ parent: ~ - kind: PathlibGetcwd: ~ @@ -60,14 +39,24 @@ expression: diagnostics column: 9 end_location: row: 18 - column: 18 + column: 20 + fix: ~ + parent: ~ +- kind: + PathlibAbspath: ~ + location: + row: 21 + column: 0 + end_location: + row: 21 + column: 33 fix: - content: Path.cwd + content: "Path(\"../../hello.py\").resolve()" location: - row: 18 - column: 9 + row: 21 + column: 0 end_location: - row: 18 - column: 18 + row: 21 + column: 33 parent: ~ diff --git a/crates/ruff/src/rules/flake8_use_pathlib/violations.rs b/crates/ruff/src/rules/flake8_use_pathlib/violations.rs index 42a8174a50a58f..dfd71179f469d4 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/violations.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/violations.rs @@ -7,10 +7,16 @@ define_violation!( pub struct PathlibAbspath; ); impl Violation for PathlibAbspath { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.abspath` should be replaced by `.resolve()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibAbspath| format!("Replace `os.path.abspath(x)` with `Path(x).resolve()`")) + } } // PTH101 @@ -18,10 +24,16 @@ define_violation!( pub struct PathlibChmod; ); impl Violation for PathlibChmod { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.chmod` should be replaced by `.chmod()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibChmod| format!("Replace `os.chmod(x, y)` with `Path(x).chmod(y)`")) + } } // PTH102 @@ -40,10 +52,16 @@ define_violation!( pub struct PathlibMkdir; ); impl Violation for PathlibMkdir { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.mkdir` should be replaced by `.mkdir()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibMkdir| format!("Replace `os.mkdir(x)` with `Path(x).mkdir()`")) + } } // PTH104 @@ -51,10 +69,16 @@ define_violation!( pub struct PathlibRename; ); impl Violation for PathlibRename { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.rename` should be replaced by `.rename()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibRename| format!("Replace `os.rename(x, y)` with `Path(x).rename(y)`")) + } } // PTH105 @@ -62,10 +86,16 @@ define_violation!( pub struct PathlibReplace; ); impl Violation for PathlibReplace { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.replace`should be replaced by `.replace()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibReplace| format!("Replace `os.replace(x, y)` with `Path(x).replace(y)`")) + } } // PTH106 @@ -73,10 +103,16 @@ define_violation!( pub struct PathlibRmdir; ); impl Violation for PathlibRmdir { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.rmdir` should be replaced by `.rmdir()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibRmdir| format!("Replace `os.rmdir(x)` with `Path(x).rmdir()`")) + } } // PTH107 @@ -84,10 +120,16 @@ define_violation!( pub struct PathlibRemove; ); impl Violation for PathlibRemove { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.remove` should be replaced by `.unlink()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibRemove| format!("Replace `os.remove(x)` with `Path(x).unlink()`")) + } } // PTH108 @@ -95,10 +137,16 @@ define_violation!( pub struct PathlibUnlink; ); impl Violation for PathlibUnlink { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.unlink` should be replaced by `.unlink()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibUnlink| format!("Replace `os.unlink(x)` with `Path(x).unlink()`")) + } } // PTH109 @@ -120,6 +168,9 @@ define_violation!( /// cwd = Path.cwd() /// ``` /// + /// ## Options + /// * `isort.required-imports` + /// /// ## References /// * [PEP 428](https://peps.python.org/pep-0428/) /// * [Correspondence between `os` and `pathlib`](https://docs.python.org/3/library/pathlib.html#correspondence-to-tools-in-the-os-module) @@ -146,10 +197,16 @@ define_violation!( pub struct PathlibExists; ); impl Violation for PathlibExists { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.exists` should be replaced by `.exists()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibExists| format!("Replace `os.path.exists(x)` with `Path(x).exists()`")) + } } // PTH111 @@ -157,10 +214,18 @@ define_violation!( pub struct PathlibExpanduser; ); impl Violation for PathlibExpanduser { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.expanduser` should be replaced by `.expanduser()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibExpanduser| { + format!("Replace `os.path.expanduser(x)` with `Path(x).expanduser()`") + }) + } } // PTH112 @@ -168,10 +233,16 @@ define_violation!( pub struct PathlibIsDir; ); impl Violation for PathlibIsDir { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.isdir` should be replaced by `.is_dir()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibIsDir| format!("Replace `os.path.isdir(x)` with `Path(x).is_dir()`")) + } } // PTH113 @@ -179,10 +250,16 @@ define_violation!( pub struct PathlibIsFile; ); impl Violation for PathlibIsFile { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.isfile` should be replaced by `.is_file()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibIsFile| format!("Replace `os.path.isfile(x)` with `Path(x).is_file()`")) + } } // PTH114 @@ -190,21 +267,60 @@ define_violation!( pub struct PathlibIsLink; ); impl Violation for PathlibIsLink { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.islink` should be replaced by `.is_symlink()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibIsLink| format!("Replace `os.path.islink(x)` with `Path(x).is_symlink()`")) + } } // PTH115 define_violation!( + /// ## What is does + /// Detects the use of `os.readline`. + /// Autofix is available when the `pathlib` module is imported. + /// + /// ## Why is this bad? + /// A modern alternative to `os.readlink(x)` is the `Path(x).readlink()` function + /// + /// ## Examples + /// ```python + /// link = os.readlink(x) + /// ``` + /// + /// Use instead: + /// ```python + /// link = Path(x).readlink() + /// ``` + /// + /// ## Options + /// * `target-version` + /// * `isort.required-imports` + /// + /// ## References + /// * [PEP 428](https://peps.python.org/pep-0428/) + /// * [Correspondence between `os` and `pathlib`](https://docs.python.org/3/library/pathlib.html#correspondence-to-tools-in-the-os-module) + /// * [Why you should be using pathlib](https://treyhunner.com/2018/12/why-you-should-be-using-pathlib/) + /// * [No really, pathlib is great](https://treyhunner.com/2019/01/no-really-pathlib-is-great/) + pub struct PathlibReadlink; ); impl Violation for PathlibReadlink { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.readlink` should be replaced by `.readlink()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibReadlink| format!("Replace `os.readlink(x)` with `Path(x).readlink()`")) + } } // PTH116 @@ -223,10 +339,16 @@ define_violation!( pub struct PathlibIsAbs; ); impl Violation for PathlibIsAbs { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.isabs` should be replaced by `.is_absolute()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibIsAbs| format!("Replace `os.path.isabs(x)` with `Path(x).is_absolute()`")) + } } // PTH118 @@ -267,10 +389,18 @@ define_violation!( pub struct PathlibSamefile; ); impl Violation for PathlibSamefile { + const AUTOFIX: Option = Some(AutofixKind::new(Availability::Sometimes)); + #[derive_message_formats] fn message(&self) -> String { format!("`os.path.samefile` should be replaced by `.samefile()`") } + + fn autofix_title_formatter(&self) -> Option String> { + Some(|PathlibSamefile| { + format!("Replace `os.path.samefile(x, y)` with `Path(x).samefile(y)`") + }) + } } // PTH122 @@ -306,7 +436,6 @@ impl Violation for PathlibPyPath { } } -// TODO: add documentation // PTH201 define_violation!( pub struct PathlibGetsize; diff --git a/docs/rules/pathlib-getcwd.md b/docs/rules/pathlib-getcwd.md index 37be84dd926b29..138202744e496c 100644 --- a/docs/rules/pathlib-getcwd.md +++ b/docs/rules/pathlib-getcwd.md @@ -21,6 +21,9 @@ Use instead: cwd = Path.cwd() ``` +## Options +* `isort.required-imports` + ## References * [PEP 428](https://peps.python.org/pep-0428/) * [Correspondence between `os` and `pathlib`](https://docs.python.org/3/library/pathlib.html#correspondence-to-tools-in-the-os-module) diff --git a/docs/rules/pathlib-readlink.md b/docs/rules/pathlib-readlink.md new file mode 100644 index 00000000000000..5bbac28aa6d6ae --- /dev/null +++ b/docs/rules/pathlib-readlink.md @@ -0,0 +1,32 @@ +# pathlib-readlink (PTH115) + +Derived from the **flake8-use-pathlib** linter. + +Autofix is sometimes available. + +## What is does +Detects the use of `os.readline`. +Autofix is available when the `pathlib` module is imported. + +## Why is this bad? +A modern alternative to `os.readlink(x)` is the `Path(x).readlink()` function + +## Examples +```python +link = os.readlink(x) +``` + +Use instead: +```python +link = Path(x).readlink() +``` + +## Options +* `target-version` +* `isort.required-imports` + +## References +* [PEP 428](https://peps.python.org/pep-0428/) +* [Correspondence between `os` and `pathlib`](https://docs.python.org/3/library/pathlib.html#correspondence-to-tools-in-the-os-module) +* [Why you should be using pathlib](https://treyhunner.com/2018/12/why-you-should-be-using-pathlib/) +* [No really, pathlib is great](https://treyhunner.com/2019/01/no-really-pathlib-is-great/) \ No newline at end of file diff --git a/resources/test/popmon b/resources/test/popmon new file mode 160000 index 00000000000000..0949e0fce92952 --- /dev/null +++ b/resources/test/popmon @@ -0,0 +1 @@ +Subproject commit 0949e0fce929528413ceeb29484db94d9a237d69