mirror of https://github.com/astral-sh/ruff
[`flake8-use-pathlib`] Add fix for `PTH123` (#20169)
## Summary Part of https://github.com/astral-sh/ruff/issues/2331 ## Test Plan `cargo nextest run flake8_use_pathlib` --------- Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
This commit is contained in:
parent
05622ae757
commit
bfb0902446
|
|
@ -0,0 +1,24 @@
|
|||
import builtins
|
||||
from pathlib import Path
|
||||
|
||||
_file = "file.txt"
|
||||
_x = ("r+", -1)
|
||||
r_plus = "r+"
|
||||
|
||||
builtins.open(file=_file)
|
||||
|
||||
open(_file, "r+ ", - 1)
|
||||
open(mode="wb", file=_file)
|
||||
open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
open(_file, "r+", - 1, None, None, None, True, None)
|
||||
open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
open(_file, f" {r_plus} ", - 1)
|
||||
open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
|
||||
# Only diagnostic
|
||||
open()
|
||||
open(_file, *_x)
|
||||
open(_file, "r+", unknown=True)
|
||||
open(_file, "r+", closefd=False)
|
||||
open(_file, "r+", None, None, None, None, None, None, None)
|
||||
|
|
@ -62,4 +62,4 @@ rename(
|
|||
|
||||
rename(file, "file_2.py", src_dir_fd=None, dst_dir_fd=None)
|
||||
|
||||
rename(file, "file_2.py", src_dir_fd=1)
|
||||
rename(file, "file_2.py", src_dir_fd=1)
|
||||
|
|
|
|||
|
|
@ -1051,7 +1051,6 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
Rule::OsStat,
|
||||
Rule::OsPathJoin,
|
||||
Rule::OsPathSplitext,
|
||||
Rule::BuiltinOpen,
|
||||
Rule::PyPath,
|
||||
Rule::Glob,
|
||||
Rule::OsListdir,
|
||||
|
|
@ -1135,6 +1134,9 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
|
|||
if checker.is_rule_enabled(Rule::OsSymlink) {
|
||||
flake8_use_pathlib::rules::os_symlink(checker, call, segments);
|
||||
}
|
||||
if checker.is_rule_enabled(Rule::BuiltinOpen) {
|
||||
flake8_use_pathlib::rules::builtin_open(checker, call, segments);
|
||||
}
|
||||
if checker.is_rule_enabled(Rule::PathConstructorCurrentDirectory) {
|
||||
flake8_use_pathlib::rules::path_constructor_current_directory(
|
||||
checker, call, segments,
|
||||
|
|
|
|||
|
|
@ -944,7 +944,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
(Flake8UsePathlib, "120") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathDirname),
|
||||
(Flake8UsePathlib, "121") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathSamefile),
|
||||
(Flake8UsePathlib, "122") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathSplitext),
|
||||
(Flake8UsePathlib, "123") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::BuiltinOpen),
|
||||
(Flake8UsePathlib, "123") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::BuiltinOpen),
|
||||
(Flake8UsePathlib, "124") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::PyPath),
|
||||
(Flake8UsePathlib, "201") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::PathConstructorCurrentDirectory),
|
||||
(Flake8UsePathlib, "202") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathGetsize),
|
||||
|
|
|
|||
|
|
@ -223,3 +223,8 @@ pub(crate) const fn is_unnecessary_default_type_args_stubs_enabled(
|
|||
pub(crate) const fn is_sim910_expanded_key_support_enabled(settings: &LinterSettings) -> bool {
|
||||
settings.preview.is_enabled()
|
||||
}
|
||||
|
||||
// https://github.com/astral-sh/ruff/pull/20169
|
||||
pub(crate) const fn is_fix_builtin_open_enabled(settings: &LinterSettings) -> bool {
|
||||
settings.preview.is_enabled()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,3 +205,14 @@ pub(crate) fn has_unknown_keywords_or_starred_expr(
|
|||
None => true,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns `true` if argument `name` is set to a non-default `None` value.
|
||||
pub(crate) fn is_argument_non_default(
|
||||
arguments: &ast::Arguments,
|
||||
name: &str,
|
||||
position: usize,
|
||||
) -> bool {
|
||||
arguments
|
||||
.find_argument_value(name, position)
|
||||
.is_some_and(|expr| !expr.is_none_literal_expr())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ mod tests {
|
|||
|
||||
#[test_case(Rule::PyPath, Path::new("py_path_1.py"))]
|
||||
#[test_case(Rule::PyPath, Path::new("py_path_2.py"))]
|
||||
#[test_case(Rule::BuiltinOpen, Path::new("PTH123.py"))]
|
||||
#[test_case(Rule::PathConstructorCurrentDirectory, Path::new("PTH201.py"))]
|
||||
#[test_case(Rule::OsPathGetsize, Path::new("PTH202.py"))]
|
||||
#[test_case(Rule::OsPathGetsize, Path::new("PTH202_2.py"))]
|
||||
|
|
@ -123,6 +124,7 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::BuiltinOpen, Path::new("PTH123.py"))]
|
||||
#[test_case(Rule::PathConstructorCurrentDirectory, Path::new("PTH201.py"))]
|
||||
#[test_case(Rule::OsPathGetsize, Path::new("PTH202.py"))]
|
||||
#[test_case(Rule::OsPathGetsize, Path::new("PTH202_2.py"))]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,191 @@
|
|||
use ruff_diagnostics::{Applicability, Edit, Fix};
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::{ArgOrKeyword, Expr, ExprBooleanLiteral, ExprCall};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::importer::ImportRequest;
|
||||
use crate::preview::is_fix_builtin_open_enabled;
|
||||
use crate::rules::flake8_use_pathlib::helpers::{
|
||||
has_unknown_keywords_or_starred_expr, is_argument_non_default, is_file_descriptor,
|
||||
is_pathlib_path_call,
|
||||
};
|
||||
use crate::{FixAvailability, Violation};
|
||||
|
||||
/// ## 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:
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// ## 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.
|
||||
///
|
||||
/// ## Fix Safety
|
||||
/// This rule's fix is marked as unsafe if the replacement would remove comments attached to the original expression.
|
||||
///
|
||||
/// ## 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 – 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#corresponding-tools)
|
||||
/// - [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 BuiltinOpen;
|
||||
|
||||
impl Violation for BuiltinOpen {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"`open()` should be replaced by `Path.open()`".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> Option<String> {
|
||||
Some("Replace with `Path.open()`".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
// PTH123
|
||||
pub(crate) fn builtin_open(checker: &Checker, call: &ExprCall, segments: &[&str]) {
|
||||
// `closefd` and `opener` are not supported by pathlib, so check if they
|
||||
// are set to non-default values.
|
||||
// https://github.com/astral-sh/ruff/issues/7620
|
||||
// Signature as of Python 3.11 (https://docs.python.org/3/library/functions.html#open):
|
||||
// ```text
|
||||
// builtins.open(
|
||||
// file, 0
|
||||
// mode='r', 1
|
||||
// buffering=-1, 2
|
||||
// encoding=None, 3
|
||||
// errors=None, 4
|
||||
// newline=None, 5
|
||||
// closefd=True, 6 <= not supported
|
||||
// opener=None 7 <= not supported
|
||||
// )
|
||||
// ```
|
||||
// For `pathlib` (https://docs.python.org/3/library/pathlib.html#pathlib.Path.open):
|
||||
// ```text
|
||||
// Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
|
||||
// ```
|
||||
let file_arg = call.arguments.find_argument_value("file", 0);
|
||||
|
||||
if call
|
||||
.arguments
|
||||
.find_argument_value("closefd", 6)
|
||||
.is_some_and(|expr| {
|
||||
!matches!(
|
||||
expr,
|
||||
Expr::BooleanLiteral(ExprBooleanLiteral { value: true, .. })
|
||||
)
|
||||
})
|
||||
|| is_argument_non_default(&call.arguments, "opener", 7)
|
||||
|| file_arg.is_some_and(|expr| is_file_descriptor(expr, checker.semantic()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if !matches!(segments, ["" | "builtins", "open"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = checker.report_diagnostic(BuiltinOpen, call.func.range());
|
||||
|
||||
if !is_fix_builtin_open_enabled(checker.settings()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(file) = file_arg else {
|
||||
return;
|
||||
};
|
||||
|
||||
if has_unknown_keywords_or_starred_expr(
|
||||
&call.arguments,
|
||||
&[
|
||||
"file",
|
||||
"mode",
|
||||
"buffering",
|
||||
"encoding",
|
||||
"errors",
|
||||
"newline",
|
||||
"closefd",
|
||||
"opener",
|
||||
],
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
diagnostic.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_symbol(
|
||||
&ImportRequest::import("pathlib", "Path"),
|
||||
call.start(),
|
||||
checker.semantic(),
|
||||
)?;
|
||||
|
||||
let locator = checker.locator();
|
||||
let file_code = locator.slice(file.range());
|
||||
|
||||
let args = |i: usize, arg: ArgOrKeyword| match arg {
|
||||
ArgOrKeyword::Arg(expr) => {
|
||||
if expr.range() == file.range() || i == 6 || i == 7 {
|
||||
None
|
||||
} else {
|
||||
Some(locator.slice(expr.range()))
|
||||
}
|
||||
}
|
||||
ArgOrKeyword::Keyword(kw) => match kw.arg.as_deref() {
|
||||
Some("mode" | "buffering" | "encoding" | "errors" | "newline") => {
|
||||
Some(locator.slice(kw))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
};
|
||||
|
||||
let open_args = itertools::join(
|
||||
call.arguments
|
||||
.arguments_source_order()
|
||||
.enumerate()
|
||||
.filter_map(|(i, arg)| args(i, arg)),
|
||||
", ",
|
||||
);
|
||||
|
||||
let replacement = if is_pathlib_path_call(checker, file) {
|
||||
format!("{file_code}.open({open_args})")
|
||||
} else {
|
||||
format!("{binding}({file_code}).open({open_args})")
|
||||
};
|
||||
|
||||
let range = call.range();
|
||||
|
||||
let applicability = if checker.comment_ranges().intersects(range) {
|
||||
Applicability::Unsafe
|
||||
} else {
|
||||
Applicability::Safe
|
||||
};
|
||||
|
||||
Ok(Fix::applicable_edits(
|
||||
Edit::range_replacement(replacement, range),
|
||||
[import_edit],
|
||||
applicability,
|
||||
))
|
||||
});
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pub(crate) use builtin_open::*;
|
||||
pub(crate) use glob_rule::*;
|
||||
pub(crate) use invalid_pathlib_with_suffix::*;
|
||||
pub(crate) use os_chmod::*;
|
||||
|
|
@ -29,6 +30,7 @@ pub(crate) use os_unlink::*;
|
|||
pub(crate) use path_constructor_current_directory::*;
|
||||
pub(crate) use replaceable_by_pathlib::*;
|
||||
|
||||
mod builtin_open;
|
||||
mod glob_rule;
|
||||
mod invalid_pathlib_with_suffix;
|
||||
mod os_chmod;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_python_ast::{self as ast, Expr, ExprBooleanLiteral, ExprCall};
|
||||
use ruff_python_ast::{Expr, ExprCall};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
|
@ -7,7 +7,7 @@ use crate::rules::flake8_use_pathlib::helpers::{
|
|||
};
|
||||
use crate::rules::flake8_use_pathlib::{
|
||||
rules::Glob,
|
||||
violations::{BuiltinOpen, Joiner, OsListdir, OsPathJoin, OsPathSplitext, OsStat, PyPath},
|
||||
violations::{Joiner, OsListdir, OsPathJoin, OsPathSplitext, OsStat, PyPath},
|
||||
};
|
||||
|
||||
pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
|
||||
|
|
@ -60,42 +60,6 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
|
|||
),
|
||||
// PTH122
|
||||
["os", "path", "splitext"] => checker.report_diagnostic_if_enabled(OsPathSplitext, range),
|
||||
// PTH123
|
||||
["" | "builtins", "open"] => {
|
||||
// `closefd` and `opener` are not supported by pathlib, so check if they
|
||||
// are set to non-default values.
|
||||
// https://github.com/astral-sh/ruff/issues/7620
|
||||
// Signature as of Python 3.11 (https://docs.python.org/3/library/functions.html#open):
|
||||
// ```text
|
||||
// 0 1 2 3 4 5
|
||||
// open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None,
|
||||
// 6 7
|
||||
// closefd=True, opener=None)
|
||||
// ^^^^ ^^^^
|
||||
// ```
|
||||
// For `pathlib` (https://docs.python.org/3/library/pathlib.html#pathlib.Path.open):
|
||||
// ```text
|
||||
// Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
|
||||
// ```
|
||||
if call
|
||||
.arguments
|
||||
.find_argument_value("closefd", 6)
|
||||
.is_some_and(|expr| {
|
||||
!matches!(
|
||||
expr,
|
||||
Expr::BooleanLiteral(ExprBooleanLiteral { value: true, .. })
|
||||
)
|
||||
})
|
||||
|| is_argument_non_default(&call.arguments, "opener", 7)
|
||||
|| call
|
||||
.arguments
|
||||
.find_argument_value("file", 0)
|
||||
.is_some_and(|expr| is_file_descriptor(expr, checker.semantic()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
checker.report_diagnostic_if_enabled(BuiltinOpen, range)
|
||||
}
|
||||
// PTH124
|
||||
["py", "path", "local"] => checker.report_diagnostic_if_enabled(PyPath, range),
|
||||
// PTH207
|
||||
|
|
@ -151,10 +115,3 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
|
|||
_ => return,
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns `true` if argument `name` is set to a non-default `None` value.
|
||||
fn is_argument_non_default(arguments: &ast::Arguments, name: &str, position: usize) -> bool {
|
||||
arguments
|
||||
.find_argument_value(name, position)
|
||||
.is_some_and(|expr| !expr.is_none_literal_expr())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
|
||||
---
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:8:1
|
||||
|
|
||||
6 | r_plus = "r+"
|
||||
7 |
|
||||
8 | builtins.open(file=_file)
|
||||
| ^^^^^^^^^^^^^
|
||||
9 |
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:10:1
|
||||
|
|
||||
8 | builtins.open(file=_file)
|
||||
9 |
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
| ^^^^
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:11:1
|
||||
|
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
| ^^^^
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:12:1
|
||||
|
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
| ^^^^
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:13:1
|
||||
|
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
| ^^^^
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:14:1
|
||||
|
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
| ^^^^
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:15:1
|
||||
|
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
| ^^^^
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:16:1
|
||||
|
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
| ^^^^
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:17:1
|
||||
|
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
| ^^^^
|
||||
18 |
|
||||
19 | # Only diagnostic
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:20:1
|
||||
|
|
||||
19 | # Only diagnostic
|
||||
20 | open()
|
||||
| ^^^^
|
||||
21 | open(_file, *_x)
|
||||
22 | open(_file, "r+", unknown=True)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:21:1
|
||||
|
|
||||
19 | # Only diagnostic
|
||||
20 | open()
|
||||
21 | open(_file, *_x)
|
||||
| ^^^^
|
||||
22 | open(_file, "r+", unknown=True)
|
||||
23 | open(_file, "r+", closefd=False)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:22:1
|
||||
|
|
||||
20 | open()
|
||||
21 | open(_file, *_x)
|
||||
22 | open(_file, "r+", unknown=True)
|
||||
| ^^^^
|
||||
23 | open(_file, "r+", closefd=False)
|
||||
24 | open(_file, "r+", None, None, None, None, None, None, None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
|
@ -305,6 +305,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
33 | fp.read()
|
||||
34 | open(p).close()
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:34:1
|
||||
|
|
@ -316,6 +317,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
35 | os.getcwdb(p)
|
||||
36 | os.path.join(p, *q)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
||||
--> full_name.py:35:1
|
||||
|
|
@ -360,6 +362,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
47 | open(p, 'r', - 1, None, None, None, True, None)
|
||||
48 | open(p, 'r', - 1, None, None, None, False, opener)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:47:1
|
||||
|
|
@ -370,6 +373,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
| ^^^^
|
||||
48 | open(p, 'r', - 1, None, None, None, False, opener)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:65:1
|
||||
|
|
@ -381,6 +385,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
66 | byte_str = b"bar"
|
||||
67 | open(byte_str)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:67:1
|
||||
|
|
@ -392,6 +397,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
68 |
|
||||
69 | def bytes_str_func() -> bytes:
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:71:1
|
||||
|
|
@ -403,6 +409,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
72 |
|
||||
73 | # https://github.com/astral-sh/ruff/issues/17693
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
||||
--> full_name.py:108:1
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
35 | fp.read()
|
||||
36 | open(p).close()
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> import_from.py:36:1
|
||||
|
|
@ -314,6 +315,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
36 | open(p).close()
|
||||
| ^^^^
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> import_from.py:43:10
|
||||
|
|
@ -323,6 +325,7 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
43 | with open(p) as _: ... # Error
|
||||
| ^^^^
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH104 `os.rename()` should be replaced by `Path.rename()`
|
||||
--> import_from.py:53:1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,215 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
|
||||
---
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:8:1
|
||||
|
|
||||
6 | r_plus = "r+"
|
||||
7 |
|
||||
8 | builtins.open(file=_file)
|
||||
| ^^^^^^^^^^^^^
|
||||
9 |
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
5 | _x = ("r+", -1)
|
||||
6 | r_plus = "r+"
|
||||
7 |
|
||||
- builtins.open(file=_file)
|
||||
8 + Path(_file).open()
|
||||
9 |
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:10:1
|
||||
|
|
||||
8 | builtins.open(file=_file)
|
||||
9 |
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
| ^^^^
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
7 |
|
||||
8 | builtins.open(file=_file)
|
||||
9 |
|
||||
- open(_file, "r+ ", - 1)
|
||||
10 + Path(_file).open("r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:11:1
|
||||
|
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
| ^^^^
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
8 | builtins.open(file=_file)
|
||||
9 |
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
- open(mode="wb", file=_file)
|
||||
11 + Path(_file).open(mode="wb")
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:12:1
|
||||
|
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
| ^^^^
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
9 |
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
- open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
12 + Path(_file).open(mode="r+", buffering=-1, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:13:1
|
||||
|
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
| ^^^^
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
10 | open(_file, "r+ ", - 1)
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
- open(_file, "r+", - 1, None, None, None, True, None)
|
||||
13 + Path(_file).open("r+", - 1, None, None, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:14:1
|
||||
|
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
| ^^^^
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
11 | open(mode="wb", file=_file)
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
- open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
14 + Path(_file).open("r+", -1, None, None, None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:15:1
|
||||
|
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
| ^^^^
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
12 | open(mode="r+", buffering=-1, file=_file, encoding="utf-8")
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
- open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
15 + Path(_file).open(mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
18 |
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:16:1
|
||||
|
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
| ^^^^
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
13 | open(_file, "r+", - 1, None, None, None, True, None)
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
- open(_file, f" {r_plus} ", - 1)
|
||||
16 + Path(_file).open(f" {r_plus} ", - 1)
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
18 |
|
||||
19 | # Only diagnostic
|
||||
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:17:1
|
||||
|
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
17 | open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
| ^^^^
|
||||
18 |
|
||||
19 | # Only diagnostic
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
14 | open(_file, "r+", -1, None, None, None, closefd=True, opener=None)
|
||||
15 | open(_file, mode="r+", buffering=-1, encoding=None, errors=None, newline=None)
|
||||
16 | open(_file, f" {r_plus} ", - 1)
|
||||
- open(buffering=- 1, file=_file, encoding= "utf-8")
|
||||
17 + Path(_file).open(buffering=- 1, encoding= "utf-8")
|
||||
18 |
|
||||
19 | # Only diagnostic
|
||||
20 | open()
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:20:1
|
||||
|
|
||||
19 | # Only diagnostic
|
||||
20 | open()
|
||||
| ^^^^
|
||||
21 | open(_file, *_x)
|
||||
22 | open(_file, "r+", unknown=True)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:21:1
|
||||
|
|
||||
19 | # Only diagnostic
|
||||
20 | open()
|
||||
21 | open(_file, *_x)
|
||||
| ^^^^
|
||||
22 | open(_file, "r+", unknown=True)
|
||||
23 | open(_file, "r+", closefd=False)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
--> PTH123.py:22:1
|
||||
|
|
||||
20 | open()
|
||||
21 | open(_file, *_x)
|
||||
22 | open(_file, "r+", unknown=True)
|
||||
| ^^^^
|
||||
23 | open(_file, "r+", closefd=False)
|
||||
24 | open(_file, "r+", None, None, None, None, None, None, None)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
|
|
@ -520,7 +520,7 @@ PTH122 `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, an
|
|||
33 | fp.read()
|
||||
|
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:32:6
|
||||
|
|
||||
30 | os.path.samefile(p)
|
||||
|
|
@ -530,8 +530,24 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
33 | fp.read()
|
||||
34 | open(p).close()
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
1 | import os
|
||||
2 | import os.path
|
||||
3 + import pathlib
|
||||
4 |
|
||||
5 | p = "/foo"
|
||||
6 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
30 | os.path.dirname(p)
|
||||
31 | os.path.samefile(p)
|
||||
32 | os.path.splitext(p)
|
||||
- with open(p) as fp:
|
||||
33 + with pathlib.Path(p).open() as fp:
|
||||
34 | fp.read()
|
||||
35 | open(p).close()
|
||||
36 | os.getcwdb(p)
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:34:1
|
||||
|
|
||||
32 | with open(p) as fp:
|
||||
|
|
@ -541,6 +557,22 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
35 | os.getcwdb(p)
|
||||
36 | os.path.join(p, *q)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
1 | import os
|
||||
2 | import os.path
|
||||
3 + import pathlib
|
||||
4 |
|
||||
5 | p = "/foo"
|
||||
6 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
32 | os.path.splitext(p)
|
||||
33 | with open(p) as fp:
|
||||
34 | fp.read()
|
||||
- open(p).close()
|
||||
35 + pathlib.Path(p).open().close()
|
||||
36 | os.getcwdb(p)
|
||||
37 | os.path.join(p, *q)
|
||||
38 | os.sep.join(p, *q)
|
||||
|
||||
PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
||||
--> full_name.py:35:1
|
||||
|
|
@ -575,7 +607,7 @@ PTH118 `os.sep.join()` should be replaced by `Path.joinpath()`
|
|||
39 | # https://github.com/astral-sh/ruff/issues/7620
|
||||
|
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:46:1
|
||||
|
|
||||
44 | open(p, closefd=False)
|
||||
|
|
@ -585,8 +617,24 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
47 | open(p, 'r', - 1, None, None, None, True, None)
|
||||
48 | open(p, 'r', - 1, None, None, None, False, opener)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
1 | import os
|
||||
2 | import os.path
|
||||
3 + import pathlib
|
||||
4 |
|
||||
5 | p = "/foo"
|
||||
6 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
44 |
|
||||
45 | open(p, closefd=False)
|
||||
46 | open(p, opener=opener)
|
||||
- open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
47 + pathlib.Path(p).open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
|
||||
48 | open(p, 'r', - 1, None, None, None, True, None)
|
||||
49 | open(p, 'r', - 1, None, None, None, False, opener)
|
||||
50 |
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:47:1
|
||||
|
|
||||
45 | open(p, opener=opener)
|
||||
|
|
@ -595,8 +643,24 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
| ^^^^
|
||||
48 | open(p, 'r', - 1, None, None, None, False, opener)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
1 | import os
|
||||
2 | import os.path
|
||||
3 + import pathlib
|
||||
4 |
|
||||
5 | p = "/foo"
|
||||
6 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
45 | open(p, closefd=False)
|
||||
46 | open(p, opener=opener)
|
||||
47 | open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
|
||||
- open(p, 'r', - 1, None, None, None, True, None)
|
||||
48 + pathlib.Path(p).open('r', - 1, None, None, None)
|
||||
49 | open(p, 'r', - 1, None, None, None, False, opener)
|
||||
50 |
|
||||
51 | # Cannot be upgraded `pathlib.Open` does not support fds
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:65:1
|
||||
|
|
||||
63 | open(f())
|
||||
|
|
@ -606,8 +670,24 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
66 | byte_str = b"bar"
|
||||
67 | open(byte_str)
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
1 | import os
|
||||
2 | import os.path
|
||||
3 + import pathlib
|
||||
4 |
|
||||
5 | p = "/foo"
|
||||
6 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
63 | return 1
|
||||
64 | open(f())
|
||||
65 |
|
||||
- open(b"foo")
|
||||
66 + pathlib.Path(b"foo").open()
|
||||
67 | byte_str = b"bar"
|
||||
68 | open(byte_str)
|
||||
69 |
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:67:1
|
||||
|
|
||||
65 | open(b"foo")
|
||||
|
|
@ -617,8 +697,24 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
68 |
|
||||
69 | def bytes_str_func() -> bytes:
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
1 | import os
|
||||
2 | import os.path
|
||||
3 + import pathlib
|
||||
4 |
|
||||
5 | p = "/foo"
|
||||
6 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
65 |
|
||||
66 | open(b"foo")
|
||||
67 | byte_str = b"bar"
|
||||
- open(byte_str)
|
||||
68 + pathlib.Path(byte_str).open()
|
||||
69 |
|
||||
70 | def bytes_str_func() -> bytes:
|
||||
71 | return b"foo"
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> full_name.py:71:1
|
||||
|
|
||||
69 | def bytes_str_func() -> bytes:
|
||||
|
|
@ -628,6 +724,22 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
72 |
|
||||
73 | # https://github.com/astral-sh/ruff/issues/17693
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
1 | import os
|
||||
2 | import os.path
|
||||
3 + import pathlib
|
||||
4 |
|
||||
5 | p = "/foo"
|
||||
6 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
69 |
|
||||
70 | def bytes_str_func() -> bytes:
|
||||
71 | return b"foo"
|
||||
- open(bytes_str_func())
|
||||
72 + pathlib.Path(bytes_str_func()).open()
|
||||
73 |
|
||||
74 | # https://github.com/astral-sh/ruff/issues/17693
|
||||
75 | os.stat(1)
|
||||
|
||||
PTH109 [*] `os.getcwd()` should be replaced by `Path.cwd()`
|
||||
--> full_name.py:108:1
|
||||
|
|
|
|||
|
|
@ -535,7 +535,7 @@ PTH122 `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, an
|
|||
35 | fp.read()
|
||||
|
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> import_from.py:34:6
|
||||
|
|
||||
32 | samefile(p)
|
||||
|
|
@ -545,8 +545,25 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
35 | fp.read()
|
||||
36 | open(p).close()
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
2 | from os import remove, unlink, getcwd, readlink, stat
|
||||
3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
|
||||
4 | from os.path import isabs, join, basename, dirname, samefile, splitext
|
||||
5 + import pathlib
|
||||
6 |
|
||||
7 | p = "/foo"
|
||||
8 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
32 | dirname(p)
|
||||
33 | samefile(p)
|
||||
34 | splitext(p)
|
||||
- with open(p) as fp:
|
||||
35 + with pathlib.Path(p).open() as fp:
|
||||
36 | fp.read()
|
||||
37 | open(p).close()
|
||||
38 |
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> import_from.py:36:1
|
||||
|
|
||||
34 | with open(p) as fp:
|
||||
|
|
@ -554,8 +571,25 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
36 | open(p).close()
|
||||
| ^^^^
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
2 | from os import remove, unlink, getcwd, readlink, stat
|
||||
3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
|
||||
4 | from os.path import isabs, join, basename, dirname, samefile, splitext
|
||||
5 + import pathlib
|
||||
6 |
|
||||
7 | p = "/foo"
|
||||
8 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
34 | splitext(p)
|
||||
35 | with open(p) as fp:
|
||||
36 | fp.read()
|
||||
- open(p).close()
|
||||
37 + pathlib.Path(p).open().close()
|
||||
38 |
|
||||
39 |
|
||||
40 | # https://github.com/astral-sh/ruff/issues/15442
|
||||
|
||||
PTH123 `open()` should be replaced by `Path.open()`
|
||||
PTH123 [*] `open()` should be replaced by `Path.open()`
|
||||
--> import_from.py:43:10
|
||||
|
|
||||
41 | from builtins import open
|
||||
|
|
@ -563,6 +597,23 @@ PTH123 `open()` should be replaced by `Path.open()`
|
|||
43 | with open(p) as _: ... # Error
|
||||
| ^^^^
|
||||
|
|
||||
help: Replace with `Path.open()`
|
||||
2 | from os import remove, unlink, getcwd, readlink, stat
|
||||
3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
|
||||
4 | from os.path import isabs, join, basename, dirname, samefile, splitext
|
||||
5 + import pathlib
|
||||
6 |
|
||||
7 | p = "/foo"
|
||||
8 | q = "bar"
|
||||
--------------------------------------------------------------------------------
|
||||
41 | def _():
|
||||
42 | from builtins import open
|
||||
43 |
|
||||
- with open(p) as _: ... # Error
|
||||
44 + with pathlib.Path(p).open() as _: ... # Error
|
||||
45 |
|
||||
46 |
|
||||
47 | def _():
|
||||
|
||||
PTH104 [*] `os.rename()` should be replaced by `Path.rename()`
|
||||
--> import_from.py:53:1
|
||||
|
|
|
|||
|
|
@ -174,50 +174,6 @@ impl Violation for OsPathSplitext {
|
|||
}
|
||||
}
|
||||
|
||||
/// ## 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:
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// ## 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)
|
||||
/// - [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#corresponding-tools)
|
||||
/// - [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 BuiltinOpen;
|
||||
|
||||
impl Violation for BuiltinOpen {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"`open()` should be replaced by `Path.open()`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for uses of the `py.path` library.
|
||||
///
|
||||
|
|
|
|||
Loading…
Reference in New Issue