diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/glob_rule.rs index 487cc1c294..be4fb8988e 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -2,7 +2,7 @@ use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, ViolationMetadata}; /// ## What it does -/// Checks for the use of `glob` and `iglob`. +/// Checks for the use of `glob.glob()` and `glob.iglob()`. /// /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation, as compared to @@ -12,35 +12,43 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// improve readability over their low-level counterparts (e.g., /// `glob.glob()`). /// -/// Note that `glob.glob` and `Path.glob` are not exact equivalents: +/// Note that `glob.glob()` and `Path.glob()` are not exact equivalents: /// -/// | | `glob` | `Path.glob` | -/// |-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| -/// | Hidden files | Excludes hidden files by default. From Python 3.11 onwards, the `include_hidden` keyword can be used to include hidden directories. | Includes hidden files by default. | -/// | Iterator | `iglob` returns an iterator. Under the hood, `glob` simply converts the iterator to a list. | `Path.glob` returns an iterator. | -/// | Working directory | `glob` takes a `root_dir` keyword to set the current working directory. | `Path.rglob` can be used to return the relative path. | -/// | Globstar (`**`) | `glob` requires the `recursive` flag to be set to `True` for the `**` pattern to match any files and zero or more directories, subdirectories, and symbolic links. | The `**` pattern in `Path.glob` means "this directory and all subdirectories, recursively". In other words, it enables recursive globbing. | +/// | | `glob`-module functions | `Path.glob()` | +/// |-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------| +/// | Hidden files | Hidden files are excluded by default. On Python 3.11+, the `include_hidden` keyword can be used to include hidden directories. | Includes hidden files by default. | +/// | Eagerness | `glob.iglob()` returns a lazy iterator. Under the hood, `glob.glob()` simply converts the iterator to a list. | `Path.glob()` returns a lazy iterator. | +/// | Working directory | `glob.glob()` and `glob.iglob()` take a `root_dir` keyword to set the current working directory. | `Path.rglob()` can be used to return the relative path. | +/// | Globstar (`**`) | The `recursive` flag must be set to `True` for the `**` pattern to match any files and zero or more directories, subdirectories, and symbolic links. | The `**` pattern in `Path.glob()` means "this directory and all subdirectories, recursively". In other words, it enables recursive globbing. | /// /// ## Example /// ```python /// import glob /// import os /// -/// glob.glob(os.path.join(path, "requirements*.txt")) +/// glob.glob(os.path.join("my_path", "requirements*.txt")) /// ``` /// /// Use instead: /// ```python /// from pathlib import Path /// -/// Path(path).glob("requirements*.txt") +/// Path("my_path").glob("requirements*.txt") /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## References /// - [Python documentation: `Path.glob`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob) /// - [Python documentation: `Path.rglob`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.rglob) /// - [Python documentation: `glob.glob`](https://docs.python.org/3/library/glob.html#glob.glob) /// - [Python documentation: `glob.iglob`](https://docs.python.org/3/library/glob.html#glob.iglob) +/// - [PEP 428 – The pathlib module – object-oriented filesystem paths](https://peps.python.org/pep-0428/) +/// - [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/) #[derive(ViolationMetadata)] pub(crate) struct Glob { pub function: String, diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs index 5feaf9c08e..15da2eb416 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getatime.rs @@ -6,15 +6,12 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation, as compared to -/// the lower-level API offered by `os`. +/// the lower-level API offered by `os.path`. /// /// When possible, using `Path` object methods such as `Path.stat()` can -/// improve readability over the `os` module's counterparts (e.g., +/// improve readability over the `os.path` module's counterparts (e.g., /// `os.path.getatime()`). /// -/// Note that `os` functions may be preferable if performance is a concern, -/// e.g., in hot loops. -/// /// ## Examples /// ```python /// import os @@ -29,6 +26,11 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// Path(__file__).stat().st_atime /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## References /// - [Python documentation: `Path.stat`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.stat) /// - [Python documentation: `os.path.getatime`](https://docs.python.org/3/library/os.path.html#os.path.getatime) diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs index 2ad1532087..0eae426b35 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getctime.rs @@ -6,15 +6,12 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation, as compared to -/// the lower-level API offered by `os`. +/// the lower-level API offered by `os.path`. /// /// When possible, using `Path` object methods such as `Path.stat()` can -/// improve readability over the `os` module's counterparts (e.g., +/// improve readability over the `os.path` module's counterparts (e.g., /// `os.path.getctime()`). /// -/// Note that `os` functions may be preferable if performance is a concern, -/// e.g., in hot loops. -/// /// ## Examples /// ```python /// import os @@ -29,6 +26,11 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// Path(__file__).stat().st_ctime /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## References /// - [Python documentation: `Path.stat`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.stat) /// - [Python documentation: `os.path.getctime`](https://docs.python.org/3/library/os.path.html#os.path.getctime) diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs index eef65f31a4..dbc1f1d500 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getmtime.rs @@ -6,15 +6,12 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation, as compared to -/// the lower-level API offered by `os`. +/// the lower-level API offered by `os.path`. /// /// When possible, using `Path` object methods such as `Path.stat()` can -/// improve readability over the `os` module's counterparts (e.g., +/// improve readability over the `os.path` module's counterparts (e.g., /// `os.path.getmtime()`). /// -/// Note that `os` functions may be preferable if performance is a concern, -/// e.g., in hot loops. -/// /// ## Examples /// ```python /// import os @@ -29,6 +26,11 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// Path(__file__).stat().st_mtime /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## References /// - [Python documentation: `Path.stat`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.stat) /// - [Python documentation: `os.path.getmtime`](https://docs.python.org/3/library/os.path.html#os.path.getmtime) diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs index d6f9db0718..94b5b793ee 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_getsize.rs @@ -6,15 +6,12 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation, as compared to -/// the lower-level API offered by `os`. +/// the lower-level API offered by `os.path`. /// /// When possible, using `Path` object methods such as `Path.stat()` can -/// improve readability over the `os` module's counterparts (e.g., +/// improve readability over the `os.path` module's counterparts (e.g., /// `os.path.getsize()`). /// -/// Note that `os` functions may be preferable if performance is a concern, -/// e.g., in hot loops. -/// /// ## Examples /// ```python /// import os @@ -29,6 +26,11 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// Path(__file__).stat().st_size /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## References /// - [Python documentation: `Path.stat`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.stat) /// - [Python documentation: `os.path.getsize`](https://docs.python.org/3/library/os.path.html#os.path.getsize) diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_sep_split.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_sep_split.rs index b4e0390c86..ef226675f1 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_sep_split.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_sep_split.rs @@ -42,6 +42,16 @@ use crate::checkers::ast::Checker; /// if any(part in blocklist for part in Path("my/file/path").parts): /// ... /// ``` +/// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than working directly with strings, +/// especially on older versions of Python. +/// +/// ## References +/// - [PEP 428 – The pathlib module – object-oriented filesystem paths](https://peps.python.org/pep-0428/) +/// - [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/) #[derive(ViolationMetadata)] pub(crate) struct OsSepSplit; diff --git a/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs b/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs index 12dd004476..28b9aa6bcc 100644 --- a/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs +++ b/crates/ruff_linter/src/rules/flake8_use_pathlib/violations.rs @@ -6,13 +6,10 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.resolve()` can improve readability over the `os.path` /// 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 @@ -27,6 +24,11 @@ use ruff_macros::{derive_message_formats, ViolationMetadata}; /// file_path = Path("../path/to/file").resolve() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -53,9 +55,6 @@ impl Violation for OsPathAbspath { /// 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 @@ -70,6 +69,11 @@ impl Violation for OsPathAbspath { /// Path("file.py").chmod(0o444) /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -96,9 +100,6 @@ impl Violation for OsChmod { /// 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 @@ -113,6 +114,11 @@ impl Violation for OsChmod { /// Path("./nested/directory/").mkdir(parents=True) /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -139,9 +145,6 @@ impl Violation for OsMakedirs { /// 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 @@ -156,6 +159,11 @@ impl Violation for OsMakedirs { /// Path("./directory/").mkdir() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -182,9 +190,6 @@ impl Violation for OsMkdir { /// 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 @@ -199,6 +204,11 @@ impl Violation for OsMkdir { /// Path("old.py").rename("new.py") /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -242,6 +252,11 @@ impl Violation for OsRename { /// Path("old.py").replace("new.py") /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -268,9 +283,6 @@ impl Violation for OsReplace { /// 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 @@ -285,6 +297,11 @@ impl Violation for OsReplace { /// Path("folder/").rmdir() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -311,9 +328,6 @@ impl Violation for OsRmdir { /// 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 @@ -328,6 +342,11 @@ impl Violation for OsRmdir { /// Path("file.py").unlink() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -354,9 +373,6 @@ impl Violation for OsRemove { /// 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 @@ -371,6 +387,11 @@ impl Violation for OsRemove { /// Path("file.py").unlink() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -397,9 +418,6 @@ impl Violation for OsUnlink { /// 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 @@ -414,6 +432,11 @@ impl Violation for OsUnlink { /// cwd = Path.cwd() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -437,13 +460,10 @@ impl Violation for OsGetcwd { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.exists()` can improve readability over the `os.path` /// 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 @@ -458,6 +478,11 @@ impl Violation for OsGetcwd { /// Path("file.py").exists() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -480,13 +505,10 @@ impl Violation for OsPathExists { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.expanduser()` can improve readability over the `os.path` /// 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 @@ -501,6 +523,11 @@ impl Violation for OsPathExists { /// Path("~/films/Monty Python").expanduser() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -523,13 +550,10 @@ impl Violation for OsPathExpanduser { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.is_dir()` can improve readability over the `os.path` /// 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 @@ -544,6 +568,11 @@ impl Violation for OsPathExpanduser { /// Path("docs").is_dir() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -566,13 +595,10 @@ impl Violation for OsPathIsdir { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.is_file()` can improve readability over the `os.path` /// 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 @@ -587,6 +613,11 @@ impl Violation for OsPathIsdir { /// Path("docs").is_file() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -609,13 +640,10 @@ impl Violation for OsPathIsfile { /// /// ## 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_symlink()` can improve readability over the `os` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.is_symlink()` can improve readability over the `os.path` /// 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 @@ -630,6 +658,11 @@ impl Violation for OsPathIsfile { /// Path("docs").is_symlink() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## References /// - [Python documentation: `Path.is_symlink`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_symlink) /// - [Python documentation: `os.path.islink`](https://docs.python.org/3/library/os.path.html#os.path.islink) @@ -656,9 +689,6 @@ impl Violation for OsPathIslink { /// 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 @@ -673,6 +703,11 @@ impl Violation for OsPathIslink { /// Path(file_name).readlink() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -699,9 +734,6 @@ impl Violation for OsReadlink { /// 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 @@ -723,6 +755,11 @@ impl Violation for OsReadlink { /// group_name = file_path.group() /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## References /// - [Python documentation: `Path.stat`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.stat) /// - [Python documentation: `Path.group`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.group) @@ -748,13 +785,10 @@ impl Violation for OsStat { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.is_absolute()` can improve readability over the `os.path` /// 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 @@ -771,6 +805,11 @@ impl Violation for OsStat { /// print("Absolute path!") /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -793,12 +832,9 @@ impl Violation for OsPathIsabs { /// /// ## 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 +/// the lower-level API offered by `os.path`. When possible, using `Path` object /// methods such as `Path.joinpath()` or the `/` operator 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. +/// readability over the `os.path` module's counterparts (e.g., `os.path.join()`). /// /// ## Examples /// ```python @@ -814,6 +850,11 @@ impl Violation for OsPathIsabs { /// Path(ROOT_PATH) / "folder" / "file.py" /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -853,13 +894,10 @@ pub(crate) enum Joiner { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.name` can improve readability over the `os.path` /// 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 @@ -874,6 +912,11 @@ pub(crate) enum Joiner { /// Path(__file__).name /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -896,13 +939,10 @@ impl Violation for OsPathBasename { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.parent` can improve readability over the `os.path` /// 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 @@ -917,6 +957,11 @@ impl Violation for OsPathBasename { /// Path(__file__).parent /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -939,13 +984,10 @@ impl Violation for OsPathDirname { /// /// ## 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` +/// the lower-level API offered by `os.path`. When possible, using `Path` object +/// methods such as `Path.samefile()` can improve readability over the `os.path` /// 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 @@ -960,6 +1002,11 @@ impl Violation for OsPathDirname { /// Path("f1.py").samefile("f2.py") /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -982,9 +1029,9 @@ impl Violation for OsPathSamefile { /// /// ## 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 +/// the lower-level API offered by `os.path`. When possible, using `Path` object /// methods such as `Path.suffix` and `Path.stem` can improve readability over -/// the `os` module's counterparts (e.g., `os.path.splitext()`). +/// the `os.path` module's counterparts (e.g., `os.path.splitext()`). /// /// `os.path.splitext()` specifically returns a tuple of the file root and /// extension (e.g., given `splitext('/foo/bar.py')`, `os.path.splitext()` @@ -992,9 +1039,6 @@ impl Violation for OsPathSamefile { /// combination of `Path.suffix` (`".py"`), `Path.stem` (`"bar"`), and /// `Path.parent` (`"foo"`). /// -/// Note that `os` functions may be preferable if performance is a concern, -/// e.g., in hot loops. -/// /// ## Examples /// ```python /// import os @@ -1011,6 +1055,11 @@ impl Violation for OsPathSamefile { /// ext = path.suffix /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -1031,7 +1080,7 @@ impl Violation for OsPathSplitext { } /// ## What it does -/// Checks for uses of the `open` builtin. +/// Checks for uses of the `open()` builtin. /// /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation. When possible, @@ -1052,6 +1101,11 @@ impl Violation for OsPathSplitext { /// ... /// ``` /// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than working directly with strings, +/// especially on older versions of Python. +/// /// ## 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) @@ -1139,6 +1193,19 @@ impl Violation for PyPath { /// if (p / "file").exists(): /// ... /// ``` +/// +/// ## Known issues +/// While using `pathlib` can improve the readability and type safety of your code, +/// it can be less performant than the lower-level alternatives that work directly with strings, +/// especially on older versions of Python. +/// +/// ## References +/// - [Python documentation: `Path.iterdir`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.iterdir) +/// - [Python documentation: `os.listdir`](https://docs.python.org/3/library/os.html#os.listdir) +/// - [PEP 428 – The pathlib module – object-oriented filesystem paths](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/) #[derive(ViolationMetadata)] pub(crate) struct OsListdir;