From f75a68a1daf6e6deee72bc7b7a639c23c5130d51 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Fri, 21 Jul 2023 04:46:53 +0200 Subject: [PATCH 01/15] [`flake8-use-pathlib`] Implement `glob` (`PTH207`) --- .../fixtures/flake8_use_pathlib/PTH207.py | 10 +++++ crates/ruff/src/checkers/ast/mod.rs | 1 + crates/ruff/src/codes.rs | 1 + .../ruff/src/rules/flake8_use_pathlib/mod.rs | 1 + .../flake8_use_pathlib/rules/glob_rule.rs | 41 +++++++++++++++++++ .../src/rules/flake8_use_pathlib/rules/mod.rs | 2 + .../rules/replaceable_by_pathlib.rs | 4 +- ..._use_pathlib__tests__PTH207_PTH207.py.snap | 20 +++++++++ ruff.schema.json | 1 + 9 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py create mode 100644 crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs create mode 100644 crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap diff --git a/crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py new file mode 100644 index 0000000000000..aa3b45dd77df3 --- /dev/null +++ b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py @@ -0,0 +1,10 @@ +import os +import glob +from glob import glob as search + + +extensions_dir = "./extensions" + +# PTH207 +glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")) +search("*.png") diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index c48dcb59f4b3b..d0ea5dd6f016e 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -3004,6 +3004,7 @@ where Rule::OsPathGetatime, Rule::OsPathGetmtime, Rule::OsPathGetctime, + Rule::Glob, ]) { flake8_use_pathlib::rules::replaceable_by_pathlib(self, func); } diff --git a/crates/ruff/src/codes.rs b/crates/ruff/src/codes.rs index 38f97cf14857f..c1d8a0d39f33b 100644 --- a/crates/ruff/src/codes.rs +++ b/crates/ruff/src/codes.rs @@ -755,6 +755,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8UsePathlib, "203") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetatime), (Flake8UsePathlib, "204") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetmtime), (Flake8UsePathlib, "205") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetctime), + (Flake8UsePathlib, "207") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::Glob), // flake8-logging-format (Flake8LoggingFormat, "001") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingStringFormat), diff --git a/crates/ruff/src/rules/flake8_use_pathlib/mod.rs b/crates/ruff/src/rules/flake8_use_pathlib/mod.rs index 49787956292a4..095df3eb581c4 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/mod.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/mod.rs @@ -61,6 +61,7 @@ mod tests { #[test_case(Rule::OsPathGetatime, Path::new("PTH203.py"))] #[test_case(Rule::OsPathGetmtime, Path::new("PTH204.py"))] #[test_case(Rule::OsPathGetctime, Path::new("PTH205.py"))] + #[test_case(Rule::Glob, Path::new("PTH207.py"))] fn rules_pypath(rule_code: Rule, path: &Path) -> Result<()> { let snapshot = format!("{}_{}", rule_code.noqa_code(), path.to_string_lossy()); let diagnostics = test_path( diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs new file mode 100644 index 0000000000000..3b5fa0dcdaf63 --- /dev/null +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -0,0 +1,41 @@ +use ruff_diagnostics::Violation; +use ruff_macros::{derive_message_formats, violation}; + +/// ## What it does +/// Checks for the use of `glob`. +/// +/// ## Why is this bad? +/// `pathlib` offers a high-level API for path manipulation, as compared to +/// the lower-level API offered by `os` and `glob`. +/// +/// When possible, using `Path` object methods such as `Path.stat()` can +/// improve readability over their low-level counterparts (e.g., +/// `glob.glob()`). +/// +/// ## Example +/// ```python +/// import glob +/// import os +/// +/// glob.glob(os.path.join(path, "requirements*.txt")) +/// ``` +/// +/// Use instead: +/// ```python +/// from pathlib import Path +/// +/// Path(path).glob("requirements*.txt") +/// +/// ## References +/// - [Python documentation: `Path.glob`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob) +/// - [Python documentation: `glob.glob`](https://docs.python.org/3/library/glob.html#glob.glob) +/// ``` +#[violation] +pub struct Glob; + +impl Violation for Glob { + #[derive_message_formats] + fn message(&self) -> String { + format!("Replace `glob` with `Path.glob`") + } +} diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/mod.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/mod.rs index 07966ab00acbb..6c79be7a9c82a 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/mod.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/mod.rs @@ -1,3 +1,4 @@ +pub(crate) use glob_rule::*; pub(crate) use os_path_getatime::*; pub(crate) use os_path_getctime::*; pub(crate) use os_path_getmtime::*; @@ -5,6 +6,7 @@ pub(crate) use os_path_getsize::*; pub(crate) use path_constructor_current_directory::*; pub(crate) use replaceable_by_pathlib::*; +mod glob_rule; mod os_path_getatime; mod os_path_getctime; mod os_path_getmtime; 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 c884d3a3e6e8d..86cd202ce879b 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 @@ -5,7 +5,7 @@ use ruff_diagnostics::{Diagnostic, DiagnosticKind}; use crate::checkers::ast::Checker; use crate::registry::AsRule; use crate::rules::flake8_use_pathlib::rules::{ - OsPathGetatime, OsPathGetctime, OsPathGetmtime, OsPathGetsize, + Glob, OsPathGetatime, OsPathGetctime, OsPathGetmtime, OsPathGetsize, }; use crate::rules::flake8_use_pathlib::violations::{ BuiltinOpen, OsChmod, OsGetcwd, OsMakedirs, OsMkdir, OsPathAbspath, OsPathBasename, @@ -89,6 +89,8 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { ["" | "builtin", "open"] => Some(BuiltinOpen.into()), // PTH124 ["py", "path", "local"] => Some(PyPath.into()), + // PTH207 + ["glob", "glob"] => Some(Glob.into()), // PTH115 // Python 3.9+ ["os", "readlink"] if checker.settings.target_version >= PythonVersion::Py39 => { diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap new file mode 100644 index 0000000000000..c8a21e5d8884b --- /dev/null +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap @@ -0,0 +1,20 @@ +--- +source: crates/ruff/src/rules/flake8_use_pathlib/mod.rs +--- +PTH207.py:9:1: PTH207 Replace `glob` with `Path.glob` + | + 8 | # PTH207 + 9 | glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")) + | ^^^^^^^^^ PTH207 +10 | search("*.png") + | + +PTH207.py:10:1: PTH207 Replace `glob` with `Path.glob` + | + 8 | # PTH207 + 9 | glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")) +10 | search("*.png") + | ^^^^^^ PTH207 + | + + diff --git a/ruff.schema.json b/ruff.schema.json index 66a99e5a56802..249df2e49db88 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2333,6 +2333,7 @@ "PTH203", "PTH204", "PTH205", + "PTH207", "PYI", "PYI0", "PYI00", From e2be1fe535c1d91699d7a451d7229bc841cebea9 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Fri, 21 Jul 2023 05:15:25 +0200 Subject: [PATCH 02/15] fix docs --- crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index 3b5fa0dcdaf63..b9f5700e94676 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -25,6 +25,7 @@ use ruff_macros::{derive_message_formats, violation}; /// from pathlib import Path /// /// Path(path).glob("requirements*.txt") +/// ``` /// /// ## References /// - [Python documentation: `Path.glob`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob) From 0d683b498e2bf3b04bf158b97491766606ac81bd Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:39:53 +0200 Subject: [PATCH 03/15] Document difference between `(i)glob` and `Path.(r)glob` --- .../rules/flake8_use_pathlib/rules/glob_rule.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index b9f5700e94676..a1a0182057813 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -2,16 +2,25 @@ use ruff_diagnostics::Violation; use ruff_macros::{derive_message_formats, violation}; /// ## What it does -/// Checks for the use of `glob`. +/// Checks for the use of `glob` and `iglob`. /// /// ## Why is this bad? /// `pathlib` offers a high-level API for path manipulation, as compared to /// the lower-level API offered by `os` and `glob`. /// -/// When possible, using `Path` object methods such as `Path.stat()` can +/// When possible, using `Path` object methods such as `Path.glob()` can /// improve readability over their low-level counterparts (e.g., /// `glob.glob()`). /// +/// Note that `glob.glob` and `Path.glob` are not equivalent: +/// +/// | | `glob` | `Path.glob` | +/// |-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +/// | Hidden files | Excludes hidden files by default. From python 3.11, the `include_hidden` keyword can used. | Includes hidden files by default. | +/// | Iterator | `iglob` returns an interator. `glob` under the hood is simply converts the iterator into a list. | `Path.glob` returns an iterator. | +/// | Working directory | `glob` takes a `root_dir` keyword to set the current working dir. | `Path.rglob` can be used to return the relative path. | +/// | Globstar (`**`) | `glob` requires the `recursive` flag to be set to `True` for the `**` pattern tomatch any files and zero or more directories, subdirectories and symbolic links to directories. | The `**` pattern in `Path.glob` means “this directory and all subdirectories, recursively”. In other words, it enables recursive globbing. | +/// /// ## Example /// ```python /// import glob @@ -29,7 +38,9 @@ use ruff_macros::{derive_message_formats, violation}; /// /// ## 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.glob) /// ``` #[violation] pub struct Glob; @@ -37,6 +48,6 @@ pub struct Glob; impl Violation for Glob { #[derive_message_formats] fn message(&self) -> String { - format!("Replace `glob` with `Path.glob`") + format!("Replace `(i)glob` with `Path.(r)glob`") } } From 96a6f6d57e2e7e3a1d0c89a812109967a31d78fa Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:40:38 +0200 Subject: [PATCH 04/15] Include `iglob` --- .../src/rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs | 1 + 1 file changed, 1 insertion(+) 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 86cd202ce879b..bef80ab23c59f 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 @@ -91,6 +91,7 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { ["py", "path", "local"] => Some(PyPath.into()), // PTH207 ["glob", "glob"] => Some(Glob.into()), + ["glob", "iglob"] => Some(Glob.into()), // PTH115 // Python 3.9+ ["os", "readlink"] if checker.settings.target_version >= PythonVersion::Py39 => { From 645e451397869f4786283215c886a3f1c48c33f3 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:43:40 +0200 Subject: [PATCH 05/15] Fix typo --- crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index a1a0182057813..b4a938a6db606 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -17,7 +17,7 @@ use ruff_macros::{derive_message_formats, violation}; /// | | `glob` | `Path.glob` | /// |-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| /// | Hidden files | Excludes hidden files by default. From python 3.11, the `include_hidden` keyword can used. | Includes hidden files by default. | -/// | Iterator | `iglob` returns an interator. `glob` under the hood is simply converts the iterator into a list. | `Path.glob` returns an iterator. | +/// | Iterator | `iglob` returns an iterator. `glob` under the hood is simply converts the iterator into a list. | `Path.glob` returns an iterator. | /// | Working directory | `glob` takes a `root_dir` keyword to set the current working dir. | `Path.rglob` can be used to return the relative path. | /// | Globstar (`**`) | `glob` requires the `recursive` flag to be set to `True` for the `**` pattern tomatch any files and zero or more directories, subdirectories and symbolic links to directories. | The `**` pattern in `Path.glob` means “this directory and all subdirectories, recursively”. In other words, it enables recursive globbing. | /// From 265fa70ba74e0a904dacf99b08fcf3a5327318a0 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:44:09 +0200 Subject: [PATCH 06/15] Add test case --- crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py index aa3b45dd77df3..752e924b8bfd2 100644 --- a/crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py +++ b/crates/ruff/resources/test/fixtures/flake8_use_pathlib/PTH207.py @@ -7,4 +7,5 @@ # PTH207 glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")) +list(glob.iglob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp"))) search("*.png") From 33f63e9faa845e283ac236d5dfa1ab95ee58a856 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:45:19 +0200 Subject: [PATCH 07/15] Update replaceable_by_pathlib.rs --- .../rules/replaceable_by_pathlib.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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 bef80ab23c59f..ee9b94f9a3e69 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 @@ -90,8 +90,18 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { // PTH124 ["py", "path", "local"] => Some(PyPath.into()), // PTH207 - ["glob", "glob"] => Some(Glob.into()), - ["glob", "iglob"] => Some(Glob.into()), + ["glob", "glob"] => Some( + Glob{ + function: "glob".to_string(), + } + .into(), + ), + ["glob", "glob"] => Some( + Glob{ + function: "iglob".to_string(), + } + .into(), + ), // PTH115 // Python 3.9+ ["os", "readlink"] if checker.settings.target_version >= PythonVersion::Py39 => { From 23b46bfc2141d4a1597493e167d355bbfa441515 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:48:06 +0200 Subject: [PATCH 08/15] Violation message --- .../ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index b4a938a6db606..c1a5ce3c9aba6 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -43,11 +43,14 @@ use ruff_macros::{derive_message_formats, violation}; /// - [Python documentation: `glob.iglob`](https://docs.python.org/3/library/glob.html#glob.glob) /// ``` #[violation] -pub struct Glob; +pub struct Glob { + pub function: String, +} impl Violation for Glob { #[derive_message_formats] fn message(&self) -> String { - format!("Replace `(i)glob` with `Path.(r)glob`") + let Glob { function } = self; + format!("Replace `{function}` with `Path.glob` or `Path.rglob`") } } From a9d43d93205d11ef2345fdfa7e70346570e80464 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:48:50 +0200 Subject: [PATCH 09/15] Fix link --- crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index c1a5ce3c9aba6..17fd916ddd95e 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -40,7 +40,7 @@ use ruff_macros::{derive_message_formats, violation}; /// - [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.glob) +/// - [Python documentation: `glob.iglob`](https://docs.python.org/3/library/glob.html#glob.iglob) /// ``` #[violation] pub struct Glob { From 215a48b3c18be44a6e898cf38941797962173bf8 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:49:26 +0200 Subject: [PATCH 10/15] Typo detection --- .../rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ee9b94f9a3e69..7c39685319e6f 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 @@ -96,7 +96,7 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { } .into(), ), - ["glob", "glob"] => Some( + ["glob", "iglob"] => Some( Glob{ function: "iglob".to_string(), } From 22b02eaabeaa3d03ee57c34a58e15a07f10cb02b Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:50:29 +0200 Subject: [PATCH 11/15] fmt --- .../rules/flake8_use_pathlib/rules/replaceable_by_pathlib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 7c39685319e6f..dd8f2f742fc3e 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 @@ -91,13 +91,13 @@ pub(crate) fn replaceable_by_pathlib(checker: &mut Checker, expr: &Expr) { ["py", "path", "local"] => Some(PyPath.into()), // PTH207 ["glob", "glob"] => Some( - Glob{ + Glob { function: "glob".to_string(), } .into(), ), ["glob", "iglob"] => Some( - Glob{ + Glob { function: "iglob".to_string(), } .into(), From 32e52937dfb83d6ac9b730f4b49775fde417a589 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sat, 22 Jul 2023 14:54:46 +0200 Subject: [PATCH 12/15] update snap file --- ...8_use_pathlib__tests__PTH207_PTH207.py.snap | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap index c8a21e5d8884b..99cebbcb7066c 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap +++ b/crates/ruff/src/rules/flake8_use_pathlib/snapshots/ruff__rules__flake8_use_pathlib__tests__PTH207_PTH207.py.snap @@ -1,19 +1,29 @@ --- source: crates/ruff/src/rules/flake8_use_pathlib/mod.rs --- -PTH207.py:9:1: PTH207 Replace `glob` with `Path.glob` +PTH207.py:9:1: PTH207 Replace `glob` with `Path.glob` or `Path.rglob` | 8 | # PTH207 9 | glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")) | ^^^^^^^^^ PTH207 -10 | search("*.png") +10 | list(glob.iglob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp"))) +11 | search("*.png") | -PTH207.py:10:1: PTH207 Replace `glob` with `Path.glob` +PTH207.py:10:6: PTH207 Replace `iglob` with `Path.glob` or `Path.rglob` | 8 | # PTH207 9 | glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")) -10 | search("*.png") +10 | list(glob.iglob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp"))) + | ^^^^^^^^^^ PTH207 +11 | search("*.png") + | + +PTH207.py:11:1: PTH207 Replace `glob` with `Path.glob` or `Path.rglob` + | + 9 | glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")) +10 | list(glob.iglob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp"))) +11 | search("*.png") | ^^^^^^ PTH207 | From d69e1392fe0cda7a6de783b11101d89980098e84 Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sun, 23 Jul 2023 14:31:40 +0200 Subject: [PATCH 13/15] Update crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs Co-authored-by: konsti --- crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index 17fd916ddd95e..d52793bd07659 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -16,7 +16,7 @@ use ruff_macros::{derive_message_formats, violation}; /// /// | | `glob` | `Path.glob` | /// |-------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| -/// | Hidden files | Excludes hidden files by default. From python 3.11, the `include_hidden` keyword can used. | Includes hidden files by default. | +/// | Hidden files | Excludes hidden files by default. From Python 3.11, the `include_hidden` keyword can used. | Includes hidden files by default. | /// | Iterator | `iglob` returns an iterator. `glob` under the hood is simply converts the iterator into a list. | `Path.glob` returns an iterator. | /// | Working directory | `glob` takes a `root_dir` keyword to set the current working dir. | `Path.rglob` can be used to return the relative path. | /// | Globstar (`**`) | `glob` requires the `recursive` flag to be set to `True` for the `**` pattern tomatch any files and zero or more directories, subdirectories and symbolic links to directories. | The `**` pattern in `Path.glob` means “this directory and all subdirectories, recursively”. In other words, it enables recursive globbing. | From 9c8e367d4019e7ec6a96fb53f767b73482b2470f Mon Sep 17 00:00:00 2001 From: Simon Brugman Date: Sun, 23 Jul 2023 14:31:46 +0200 Subject: [PATCH 14/15] Update crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs Co-authored-by: konsti --- crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index d52793bd07659..0523a9dbdcbe5 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -19,7 +19,7 @@ use ruff_macros::{derive_message_formats, violation}; /// | Hidden files | Excludes hidden files by default. From Python 3.11, the `include_hidden` keyword can used. | Includes hidden files by default. | /// | Iterator | `iglob` returns an iterator. `glob` under the hood is simply converts the iterator into a list. | `Path.glob` returns an iterator. | /// | Working directory | `glob` takes a `root_dir` keyword to set the current working dir. | `Path.rglob` can be used to return the relative path. | -/// | Globstar (`**`) | `glob` requires the `recursive` flag to be set to `True` for the `**` pattern tomatch any files and zero or more directories, subdirectories and symbolic links to directories. | The `**` pattern in `Path.glob` means “this directory and all subdirectories, recursively”. In other words, it enables recursive globbing. | +/// | 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 to directories. | The `**` pattern in `Path.glob` means “this directory and all subdirectories, recursively”. In other words, it enables recursive globbing. | /// /// ## Example /// ```python From 689181ea6f077992f39c3a7824e380dbb8b7ef45 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 26 Jul 2023 19:01:56 -0400 Subject: [PATCH 15/15] Tweak table --- .../rules/flake8_use_pathlib/rules/glob_rule.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs index 0523a9dbdcbe5..6a318a6aeea5c 100644 --- a/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs +++ b/crates/ruff/src/rules/flake8_use_pathlib/rules/glob_rule.rs @@ -12,14 +12,14 @@ use ruff_macros::{derive_message_formats, violation}; /// improve readability over their low-level counterparts (e.g., /// `glob.glob()`). /// -/// Note that `glob.glob` and `Path.glob` are not equivalent: +/// 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, the `include_hidden` keyword can used. | Includes hidden files by default. | -/// | Iterator | `iglob` returns an iterator. `glob` under the hood is simply converts the iterator into a list. | `Path.glob` returns an iterator. | -/// | Working directory | `glob` takes a `root_dir` keyword to set the current working dir. | `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 to directories. | The `**` pattern in `Path.glob` means “this directory and all subdirectories, recursively”. In other words, it enables recursive globbing. | +/// | | `glob` | `Path.glob` | +/// |-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +/// | Hidden files | Excludes hidden files by default. From Python 3.11 onwards, the `include_hidden` keyword can 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. | /// /// ## Example /// ```python @@ -41,7 +41,6 @@ use ruff_macros::{derive_message_formats, violation}; /// - [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) -/// ``` #[violation] pub struct Glob { pub function: String,