diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs index c3ed9e13f7a27..77f0c14925d3d 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs @@ -17,11 +17,15 @@ use ruff_macros::{derive_message_formats, violation}; /// /// ## Examples /// ```python +/// import os +/// /// os.path.getsize(__file__) /// ``` /// /// Use instead: /// ```python +/// from pathlib import Path +/// /// Path(__file__).stat().st_size /// ``` /// diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs index 4c178f92865c7..ec9c3fffab0c5 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs @@ -17,11 +17,15 @@ use ruff_macros::{derive_message_formats, violation}; /// /// ## Examples /// ```python +/// import os +/// /// os.path.getsize(__file__) /// ``` /// /// Use instead: /// ```python +/// from pathlib import Path +/// /// Path(__file__).stat().st_size /// ``` /// diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs index 855becdd036d4..ae3249af6f0aa 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs @@ -17,11 +17,15 @@ use ruff_macros::{derive_message_formats, violation}; /// /// ## Examples /// ```python +/// import os +/// /// os.path.getsize(__file__) /// ``` /// /// Use instead: /// ```python +/// from pathlib import Path +/// /// Path(__file__).stat().st_size /// ``` /// diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs index 71d5edfa72273..52721011d3f0c 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs @@ -17,11 +17,15 @@ use ruff_macros::{derive_message_formats, violation}; /// /// ## Examples /// ```python +/// import os +/// /// os.path.getsize(__file__) /// ``` /// /// Use instead: /// ```python +/// from pathlib import Path +/// /// Path(__file__).stat().st_size /// ``` /// diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs index b30eee13e3a57..e4f908d6384c7 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs @@ -21,28 +21,50 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { .semantic() .resolve_call_path(expr) .and_then(|call_path| match call_path.as_slice() { + // PTH100 ["os", "path", "abspath"] => Some(OsPathAbspath.into()), + // PTH101 ["os", "chmod"] => Some(OsChmod.into()), - ["os", "mkdir"] => Some(OsMkdir.into()), + // PTH102 ["os", "makedirs"] => Some(OsMakedirs.into()), + // PTH103 + ["os", "mkdir"] => Some(OsMkdir.into()), + // PTH104 ["os", "rename"] => Some(OsRename.into()), + // PTH105 ["os", "replace"] => Some(OsReplace.into()), + // PTH106 ["os", "rmdir"] => Some(OsRmdir.into()), + // PTH107 ["os", "remove"] => Some(OsRemove.into()), + // PTH108 ["os", "unlink"] => Some(OsUnlink.into()), + // PTH109 ["os", "getcwd"] => Some(OsGetcwd.into()), ["os", "getcwdb"] => Some(OsGetcwd.into()), + // PTH110 ["os", "path", "exists"] => Some(OsPathExists.into()), + // PTH111 ["os", "path", "expanduser"] => Some(OsPathExpanduser.into()), + // PTH112 ["os", "path", "isdir"] => Some(OsPathIsdir.into()), + // PTH113 ["os", "path", "isfile"] => Some(OsPathIsfile.into()), + // PTH114 ["os", "path", "islink"] => Some(OsPathIslink.into()), + // PTH116 ["os", "stat"] => Some(OsStat.into()), + // PTH117 ["os", "path", "isabs"] => Some(OsPathIsabs.into()), + // PTH118 ["os", "path", "join"] => Some(OsPathJoin.into()), + // PTH119 ["os", "path", "basename"] => Some(OsPathBasename.into()), + // PTH120 ["os", "path", "dirname"] => Some(OsPathDirname.into()), + // PTH121 ["os", "path", "samefile"] => Some(OsPathSamefile.into()), + // PTH122 ["os", "path", "splitext"] => Some(OsPathSplitext.into()), // PTH202 ["os", "path", "getsize"] => Some(OsPathGetsize.into()), @@ -52,8 +74,11 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { ["os", "path", "getmtime"] => Some(OsPathGetmtime.into()), // PTH205 ["os", "path", "getctime"] => Some(OsPathGetctime.into()), - ["", "open"] => Some(BuiltinOpen.into()), + // PTH123 + ["" | "builtin", "open"] => Some(BuiltinOpen.into()), + // PTH124 ["py", "path", "local"] => Some(PyPath.into()), + // PTH115 // Python 3.9+ ["os", "readlink"] if checker.settings.target_version >= PythonVersion::Py39 => { Some(OsReadlink.into()) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/violations.rs b/crates/ruff/src/rules/flake8_use_pathlib/violations.rs index 738bffb76d77d..9b35d783b39b4 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/violations.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/violations.rs @@ -1,7 +1,39 @@ use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; -// PTH100 +/// ## What it does +/// Checks for uses of `os.path.abspath`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.resolve()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.abspath()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// file_path = os.path.abspath("../path/to/file") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// file_path = Path("../path/to/file").resolve() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.resolve`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve) +/// - [Python documentation: `os.path.abspath`](https://docs.python.org/3/library/os.path.html#os.path.abspath) +/// - [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/) #[violation] pub struct OsPathAbspath; @@ -12,7 +44,39 @@ impl Violation for OsPathAbspath { } } -// PTH101 +/// ## What it does +/// Checks for uses of `os.chmod`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.chmod()` can improve readability over the `os` +/// module's counterparts (e.g., `os.chmod()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.chmod("file.py", 0o444) +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("file.py").chmod(0o444) +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.chmod`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.chmod) +/// - [Python documentation: `os.chmod`](https://docs.python.org/3/library/os.html#os.chmod) +/// - [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/) #[violation] pub struct OsChmod; @@ -23,7 +87,39 @@ impl Violation for OsChmod { } } -// PTH102 +/// ## What it does +/// Checks for uses of `os.makedirs`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.mkdir(parents=True)` can improve readability over the +/// `os` module's counterparts (e.g., `os.makedirs()`. +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.makedirs("./nested/directory/") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("./nested/directory/").mkdir(parents=True) +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.mkdir`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir) +/// - [Python documentation: `os.makedirs`](https://docs.python.org/3/library/os.html#os.makedirs) +/// - [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/) #[violation] pub struct OsMakedirs; @@ -34,7 +130,39 @@ impl Violation for OsMakedirs { } } -// PTH103 +/// ## What it does +/// Checks for uses of `os.mkdir`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.mkdir()` can improve readability over the `os` +/// module's counterparts (e.g., `os.mkdir()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.mkdir("./directory/") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("./directory/").mkdir() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.mkdir`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.mkdir) +/// - [Python documentation: `os.mkdir`](https://docs.python.org/3/library/os.html#os.mkdir) +/// - [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/) #[violation] pub struct OsMkdir; @@ -45,7 +173,39 @@ impl Violation for OsMkdir { } } -// PTH104 +/// ## What it does +/// Checks for uses of `os.rename`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.rename()` can improve readability over the `os` +/// module's counterparts (e.g., `os.rename()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.rename("old.py", "new.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("old.py").rename("new.py") +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.rename`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.rename) +/// - [Python documentation: `os.rename`](https://docs.python.org/3/library/os.html#os.rename) +/// - [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/) #[violation] pub struct OsRename; @@ -56,7 +216,39 @@ impl Violation for OsRename { } } -// PTH105 +/// ## What it does +/// Checks for uses of `os.replace`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.replace()` can improve readability over the `os` +/// module's counterparts (e.g., `os.replace()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.replace("old.py", "new.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("old.py").replace("new.py") +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.replace`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.replace) +/// - [Python documentation: `os.replace`](https://docs.python.org/3/library/os.html#os.replace) +/// - [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/) #[violation] pub struct OsReplace; @@ -67,7 +259,39 @@ impl Violation for OsReplace { } } -// PTH106 +/// ## What it does +/// Checks for uses of `os.rmdir`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.rmdir()` can improve readability over the `os` +/// module's counterparts (e.g., `os.rmdir()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.rmdir("folder/") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("folder/").rmdir() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.rmdir`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.rmdir) +/// - [Python documentation: `os.rmdir`](https://docs.python.org/3/library/os.html#os.rmdir) +/// - [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/) #[violation] pub struct OsRmdir; @@ -78,7 +302,39 @@ impl Violation for OsRmdir { } } -// PTH107 +/// ## What it does +/// Checks for uses of `os.remove`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.unlink()` can improve readability over the `os` +/// module's counterparts (e.g., `os.remove()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.remove("file.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("file.py").unlink() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.unlink`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.unlink) +/// - [Python documentation: `os.remove`](https://docs.python.org/3/library/os.html#os.remove) +/// - [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/) #[violation] pub struct OsRemove; @@ -89,7 +345,39 @@ impl Violation for OsRemove { } } -// PTH108 +/// ## What it does +/// Checks for uses of `os.unlink`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.unlink()` can improve readability over the `os` +/// module's counterparts (e.g., `os.unlink()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.unlink("file.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("file.py").unlink() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.unlink`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.unlink) +/// - [Python documentation: `os.unlink`](https://docs.python.org/3/library/os.html#os.unlink) +/// - [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/) #[violation] pub struct OsUnlink; @@ -100,7 +388,40 @@ impl Violation for OsUnlink { } } -// PTH109 +/// ## What it does +/// Checks for uses of `os.getcwd` and `os.getcwdb`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.cwd()` can improve readability over the `os` +/// module's counterparts (e.g., `os.getcwd()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// cwd = os.getcwd() +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// cwd = Path.cwd() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.cwd`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.cwd) +/// - [Python documentation: `os.getcwd`](https://docs.python.org/3/library/os.html#os.getcwd) +/// - [Python documentation: `os.getcwdb`](https://docs.python.org/3/library/os.html#os.getcwdb) +/// - [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/) #[violation] pub struct OsGetcwd; @@ -111,7 +432,39 @@ impl Violation for OsGetcwd { } } -// PTH110 +/// ## What it does +/// Checks for uses of `os.path.exists`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.exists()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.exists()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.exists("file.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("file.py").exists() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.exists`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.exists) +/// - [Python documentation: `os.path.exists`](https://docs.python.org/3/library/os.path.html#os.path.exists) +/// - [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/) #[violation] pub struct OsPathExists; @@ -122,7 +475,39 @@ impl Violation for OsPathExists { } } -// PTH111 +/// ## What it does +/// Checks for uses of `os.path.expanduser`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.expanduser()` can improve readability over the `os` +/// module's counterparts (e.g., as `os.path.expanduser()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.expanduser("~/films/Monty Python") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("~/films/Monty Python").expanduser() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.expanduser`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.expanduser) +/// - [Python documentation: `os.path.expanduser`](https://docs.python.org/3/library/os.path.html#os.path.expanduser) +/// - [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/) #[violation] pub struct OsPathExpanduser; @@ -133,7 +518,39 @@ impl Violation for OsPathExpanduser { } } -// PTH112 +/// ## What it does +/// Checks for uses of `os.path.isdir`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.is_dir()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.isdir()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.isdir("docs") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("docs").is_dir() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.is_dir`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_dir) +/// - [Python documentation: `os.path.isdir`](https://docs.python.org/3/library/os.path.html#os.path.isdir) +/// - [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/) #[violation] pub struct OsPathIsdir; @@ -144,7 +561,39 @@ impl Violation for OsPathIsdir { } } -// PTH113 +/// ## What it does +/// Checks for uses of `os.path.isfile`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.is_file()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.isfile()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.isfile("docs") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("docs").is_file() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.is_file`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_file) +/// - [Python documentation: `os.path.isfile`](https://docs.python.org/3/library/os.path.html#os.path.isfile) +/// - [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/) #[violation] pub struct OsPathIsfile; @@ -155,7 +604,39 @@ impl Violation for OsPathIsfile { } } -// PTH114 +/// ## What it does +/// Checks for uses of `os.path.islink`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.is_link()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.islink()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.islink("docs") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("docs").is_link() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.is_link`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_link) +/// - [Python documentation: `os.path.islink`](https://docs.python.org/3/library/os.path.html#os.path.islink) +/// - [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/) #[violation] pub struct OsPathIslink; @@ -166,7 +647,39 @@ impl Violation for OsPathIslink { } } -// PTH115 +/// ## What it does +/// Checks for uses of `os.readlink`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.readlink()` can improve readability over the `os` +/// module's counterparts (e.g., `os.readlink()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.readlink(file_name) +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path(file_name).readlink() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.readlink`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.readline) +/// - [Python documentation: `os.readlink`](https://docs.python.org/3/library/os.html#os.readlink) +/// - [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/) #[violation] pub struct OsReadlink; @@ -177,7 +690,52 @@ impl Violation for OsReadlink { } } -// PTH116 +/// ## What it does +/// Checks for uses of `os.stat`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.stat()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.stat()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// import os +/// from pwd import getpwuid +/// from grp import getgrgid +/// +/// stat = os.stat(file_name) +/// owner_name = getpwuid(stat.st_uid).pw_name +/// group_name = getgrgid(stat.st_gid).gr_name +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// from pathlib import Path +/// +/// file_path = Path(file_name) +/// stat = file_path.stat() +/// owner_name = file_path.owner() +/// group_name = file_path.group() +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.stat`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.group) +/// - [Python documentation: `Path.group`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.group) +/// - [Python documentation: `Path.owner`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.owner) +/// - [Python documentation: `os.stat`](https://docs.python.org/3/library/os.html#os.stat) +/// - [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/) #[violation] pub struct OsStat; @@ -190,7 +748,41 @@ impl Violation for OsStat { } } -// PTH117 +/// ## What it does +/// Checks for uses of `os.path.isabs`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.is_absolute()` can improve readability over the `os` +/// module's counterparts (e.g., as `os.path.isabs()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// if os.path.isabs(file_name): +/// print("Absolute path!") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// if Path(file_name).is_absolute(): +/// print("Absolute path!") +/// ``` +/// +/// ## References +/// - [Python documentation: `PurePath.is_absolute`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.is_absolute) +/// - [Python documentation: `os.path.isabs`](https://docs.python.org/3/library/os.path.html#os.path.isabs) +/// - [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/) #[violation] pub struct OsPathIsabs; @@ -201,7 +793,39 @@ impl Violation for OsPathIsabs { } } -// PTH118 +/// ## What it does +/// Checks for uses of `os.path.join`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.joinpath()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.join()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.join(os.path.join(ROOT_PATH, "folder"), "file.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path(ROOT_PATH) / "folder" / "file.py" +/// ``` +/// +/// ## References +/// - [Python documentation: `PurePath.joinpath`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.joinpath) +/// - [Python documentation: `os.path.join`](https://docs.python.org/3/library/os.path.html#os.path.join) +/// - [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/) #[violation] pub struct OsPathJoin; @@ -212,7 +836,39 @@ impl Violation for OsPathJoin { } } -// PTH119 +/// ## What it does +/// Checks for uses of `os.path.basename`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.name` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.basename()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.basename(__file__) +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path(__file__).name +/// ``` +/// +/// ## References +/// - [Python documentation: `PurePath.name`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.name) +/// - [Python documentation: `os.path.basename`](https://docs.python.org/3/library/os.path.html#os.path.basename) +/// - [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/) #[violation] pub struct OsPathBasename; @@ -223,7 +879,39 @@ impl Violation for OsPathBasename { } } -// PTH120 +/// ## What it does +/// Checks for uses of `os.path.dirname`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.parent` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.dirname()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.dirname(__file__) +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path(__file__).parent +/// ``` +/// +/// ## References +/// - [Python documentation: `PurePath.parent`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent) +/// - [Python documentation: `os.path.dirname`](https://docs.python.org/3/library/os.path.html#os.path.dirname) +/// - [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/) #[violation] pub struct OsPathDirname; @@ -234,7 +922,39 @@ impl Violation for OsPathDirname { } } -// PTH121 +/// ## What it does +/// Checks for uses of `os.path.samefile`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.samefile()` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.samefile()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.samefile("f1.py", "f2.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("f1.py").samefile("f2.py") +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.samefile`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.samefile) +/// - [Python documentation: `os.path.samefile`](https://docs.python.org/3/library/os.path.html#os.path.samefile) +/// - [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/) #[violation] pub struct OsPathSamefile; @@ -245,7 +965,40 @@ impl Violation for OsPathSamefile { } } -// PTH122 +/// ## What it does +/// Checks for uses of `os.path.splitext`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os`. When possible, using `Path` object +/// methods such as `Path.suffix` can improve readability over the `os` +/// module's counterparts (e.g., `os.path.splitext()`). +/// +/// Note that `os` functions may be preferable if performance is a concern, +/// e.g., in hot loops. +/// +/// ## Examples +/// ```python +/// import os +/// +/// os.path.splitext("f1.py") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path("f1.py").suffix +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.suffix`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.suffix) +/// - [Python documentation: `Path.suffixes`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.suffixes) +/// - [Python documentation: `os.path.splitext`](https://docs.python.org/3/library/os.path.html#os.path.splitext) +/// - [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/) #[violation] pub struct OsPathSplitext; @@ -256,7 +1009,35 @@ impl Violation for OsPathSplitext { } } -// PTH123 +/// ## What it does +/// Checks for uses of the `open` builtin. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation. When possible, +/// using `Path` object methods such as `Path.open()` can improve readability +/// over the `open` builtin. +/// +/// ## Examples +/// ```python +/// with open("f1.py", "wb") as fp: +/// ... +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// with Path("f1.py").open("wb") as fp: +/// ... +/// ``` +/// +/// ## References +/// - [Python documentation: `Path.open`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.open) +/// - [Python documentation: `open`](https://docs.python.org/3/library/functions.html#open) +/// - [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/) #[violation] pub struct BuiltinOpen; @@ -267,7 +1048,31 @@ impl Violation for BuiltinOpen { } } -// PTH124 +/// ## What it does +/// Checks for uses of the `py.path` library. +/// +/// ## Why is this bad? +/// The `py.path` library is in maintenance mode. Instead, prefer the standard +/// library's `pathlib` module, or third-party modules like `path` (formerly +/// `py.path`). +/// +/// ## Examples +/// ```python +/// import py.path +/// +/// p = py.path.local("/foo/bar").join("baz/qux") +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// p = Path("/foo/bar") / "bar" / "qux" +/// ``` +/// +/// ## References +/// - [Python documentation: `Pathlib`](https://docs.python.org/3/library/pathlib.html) +/// - [Path repository](https://github.com/jaraco/path) #[violation] pub struct PyPath;