[flake8-use-pathlib] Add autofixes for PTH100, PTH106, PTH107, PTH108, PTH110, PTH111, PTH112, PTH113, PTH114, PTH115, PTH117, PTH119, PTH120 (#19213)

## Summary

Part of #2331

## Test Plan

update snapshots for preview mode
This commit is contained in:
chiri 2025-07-09 21:54:33 +03:00 committed by GitHub
parent 05b1b788a0
commit beb98dae7c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 3401 additions and 757 deletions

View file

@ -1039,27 +1039,14 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
flake8_simplify::rules::zip_dict_keys_and_values(checker, call);
}
if checker.any_rule_enabled(&[
Rule::OsPathAbspath,
Rule::OsChmod,
Rule::OsMkdir,
Rule::OsMakedirs,
Rule::OsRename,
Rule::OsReplace,
Rule::OsRmdir,
Rule::OsRemove,
Rule::OsUnlink,
Rule::OsGetcwd,
Rule::OsPathExists,
Rule::OsPathExpanduser,
Rule::OsPathIsdir,
Rule::OsPathIsfile,
Rule::OsPathIslink,
Rule::OsReadlink,
Rule::OsStat,
Rule::OsPathIsabs,
Rule::OsPathJoin,
Rule::OsPathBasename,
Rule::OsPathDirname,
Rule::OsPathSamefile,
Rule::OsPathSplitext,
Rule::BuiltinOpen,
@ -1070,21 +1057,66 @@ pub(crate) fn expression(expr: &Expr, checker: &Checker) {
]) {
flake8_use_pathlib::rules::replaceable_by_pathlib(checker, call);
}
if let Some(qualified_name) = checker.semantic().resolve_qualified_name(&call.func) {
let segments = qualified_name.segments();
if checker.is_rule_enabled(Rule::OsPathGetsize) {
flake8_use_pathlib::rules::os_path_getsize(checker, call);
flake8_use_pathlib::rules::os_path_getsize(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathGetatime) {
flake8_use_pathlib::rules::os_path_getatime(checker, call);
flake8_use_pathlib::rules::os_path_getatime(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathGetctime) {
flake8_use_pathlib::rules::os_path_getctime(checker, call);
flake8_use_pathlib::rules::os_path_getctime(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathGetmtime) {
flake8_use_pathlib::rules::os_path_getmtime(checker, call);
flake8_use_pathlib::rules::os_path_getmtime(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathAbspath) {
flake8_use_pathlib::rules::os_path_abspath(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsRmdir) {
flake8_use_pathlib::rules::os_rmdir(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsRemove) {
flake8_use_pathlib::rules::os_remove(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsUnlink) {
flake8_use_pathlib::rules::os_unlink(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathExists) {
flake8_use_pathlib::rules::os_path_exists(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathExpanduser) {
flake8_use_pathlib::rules::os_path_expanduser(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathBasename) {
flake8_use_pathlib::rules::os_path_basename(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathDirname) {
flake8_use_pathlib::rules::os_path_dirname(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathIsabs) {
flake8_use_pathlib::rules::os_path_isabs(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathIsdir) {
flake8_use_pathlib::rules::os_path_isdir(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathIsfile) {
flake8_use_pathlib::rules::os_path_isfile(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsPathIslink) {
flake8_use_pathlib::rules::os_path_islink(checker, call, segments);
}
if checker.is_rule_enabled(Rule::OsReadlink) {
flake8_use_pathlib::rules::os_readlink(checker, call, segments);
}
if checker.is_rule_enabled(Rule::PathConstructorCurrentDirectory) {
flake8_use_pathlib::rules::path_constructor_current_directory(checker, call);
flake8_use_pathlib::rules::path_constructor_current_directory(
checker, call, segments,
);
}
}
if checker.is_rule_enabled(Rule::OsSepSplit) {
flake8_use_pathlib::rules::os_sep_split(checker, call);
}

View file

@ -919,27 +919,27 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Tryceratops, "401") => (RuleGroup::Stable, rules::tryceratops::rules::VerboseLogMessage),
// flake8-use-pathlib
(Flake8UsePathlib, "100") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathAbspath),
(Flake8UsePathlib, "100") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathAbspath),
(Flake8UsePathlib, "101") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsChmod),
(Flake8UsePathlib, "102") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsMkdir),
(Flake8UsePathlib, "103") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsMakedirs),
(Flake8UsePathlib, "104") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsRename),
(Flake8UsePathlib, "105") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsReplace),
(Flake8UsePathlib, "106") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsRmdir),
(Flake8UsePathlib, "107") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsRemove),
(Flake8UsePathlib, "108") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsUnlink),
(Flake8UsePathlib, "106") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsRmdir),
(Flake8UsePathlib, "107") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsRemove),
(Flake8UsePathlib, "108") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsUnlink),
(Flake8UsePathlib, "109") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsGetcwd),
(Flake8UsePathlib, "110") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathExists),
(Flake8UsePathlib, "111") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathExpanduser),
(Flake8UsePathlib, "112") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIsdir),
(Flake8UsePathlib, "113") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIsfile),
(Flake8UsePathlib, "114") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIslink),
(Flake8UsePathlib, "115") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsReadlink),
(Flake8UsePathlib, "110") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathExists),
(Flake8UsePathlib, "111") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathExpanduser),
(Flake8UsePathlib, "112") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathIsdir),
(Flake8UsePathlib, "113") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathIsfile),
(Flake8UsePathlib, "114") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathIslink),
(Flake8UsePathlib, "115") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsReadlink),
(Flake8UsePathlib, "116") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsStat),
(Flake8UsePathlib, "117") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathIsabs),
(Flake8UsePathlib, "117") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathIsabs),
(Flake8UsePathlib, "118") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathJoin),
(Flake8UsePathlib, "119") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathBasename),
(Flake8UsePathlib, "120") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathDirname),
(Flake8UsePathlib, "119") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathBasename),
(Flake8UsePathlib, "120") => (RuleGroup::Stable, rules::flake8_use_pathlib::rules::OsPathDirname),
(Flake8UsePathlib, "121") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathSamefile),
(Flake8UsePathlib, "122") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::OsPathSplitext),
(Flake8UsePathlib, "123") => (RuleGroup::Stable, rules::flake8_use_pathlib::violations::BuiltinOpen),

View file

@ -69,6 +69,71 @@ pub(crate) const fn is_fix_os_path_getctime_enabled(settings: &LinterSettings) -
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_abspath_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_rmdir_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_unlink_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_remove_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_exists_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_expanduser_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_isdir_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_isfile_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_islink_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_isabs_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_readlink_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_basename_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/19213
pub(crate) const fn is_fix_os_path_dirname_enabled(settings: &LinterSettings) -> bool {
settings.preview.is_enabled()
}
// https://github.com/astral-sh/ruff/pull/11436
// https://github.com/astral-sh/ruff/pull/11168
pub(crate) const fn is_dunder_init_fix_unused_import_enabled(settings: &LinterSettings) -> bool {

View file

@ -1,10 +1,17 @@
use crate::checkers::ast::Checker;
use crate::importer::ImportRequest;
use crate::{Applicability, Edit, Fix, Violation};
use ruff_python_ast::{self as ast};
use ruff_python_ast::{Expr, ExprCall};
use ruff_text_size::Ranged;
pub(crate) fn is_path_call(checker: &Checker, expr: &Expr) -> bool {
pub(crate) fn is_keyword_only_argument_non_default(arguments: &ast::Arguments, name: &str) -> bool {
arguments
.find_keyword(name)
.is_some_and(|keyword| !keyword.value.is_none_literal_expr())
}
pub(crate) fn is_pathlib_path_call(checker: &Checker, expr: &Expr) -> bool {
expr.as_call_expr().is_some_and(|expr_call| {
checker
.semantic()
@ -13,27 +20,22 @@ pub(crate) fn is_path_call(checker: &Checker, expr: &Expr) -> bool {
})
}
pub(crate) fn check_os_path_get_calls(
/// We check functions that take only 1 argument, this does not apply to functions
/// with `dir_fd` argument, because `dir_fd` is not supported by pathlib,
/// so check if it's set to non-default values
pub(crate) fn check_os_pathlib_single_arg_calls(
checker: &Checker,
call: &ExprCall,
fn_name: &str,
attr: &str,
fn_argument: &str,
fix_enabled: bool,
violation: impl Violation,
) {
if checker
.semantic()
.resolve_qualified_name(&call.func)
.is_none_or(|qualified_name| qualified_name.segments() != ["os", "path", fn_name])
{
return;
}
if call.arguments.len() != 1 {
return;
}
let Some(arg) = call.arguments.find_argument_value("filename", 0) else {
let Some(arg) = call.arguments.find_argument_value(fn_argument, 0) else {
return;
};
@ -56,10 +58,10 @@ pub(crate) fn check_os_path_get_calls(
Applicability::Safe
};
let replacement = if is_path_call(checker, arg) {
format!("{arg_code}.stat().{attr}")
let replacement = if is_pathlib_path_call(checker, arg) {
format!("{arg_code}.{attr}")
} else {
format!("{binding}({arg_code}).stat().{attr}")
format!("{binding}({arg_code}).{attr}")
};
Ok(Fix::applicable_edits(

View file

@ -80,6 +80,48 @@ mod tests {
Ok(())
}
#[test_case(Path::new("full_name.py"))]
#[test_case(Path::new("import_as.py"))]
#[test_case(Path::new("import_from_as.py"))]
#[test_case(Path::new("import_from.py"))]
fn preview_rules(path: &Path) -> Result<()> {
let snapshot = format!("preview_{}", path.to_string_lossy());
let diagnostics = test_path(
Path::new("flake8_use_pathlib").join(path).as_path(),
&settings::LinterSettings {
preview: PreviewMode::Enabled,
..settings::LinterSettings::for_rules(vec![
Rule::OsPathAbspath,
Rule::OsChmod,
Rule::OsMkdir,
Rule::OsMakedirs,
Rule::OsRename,
Rule::OsReplace,
Rule::OsRmdir,
Rule::OsRemove,
Rule::OsUnlink,
Rule::OsGetcwd,
Rule::OsPathExists,
Rule::OsPathExpanduser,
Rule::OsPathIsdir,
Rule::OsPathIsfile,
Rule::OsPathIslink,
Rule::OsReadlink,
Rule::OsStat,
Rule::OsPathIsabs,
Rule::OsPathJoin,
Rule::OsPathBasename,
Rule::OsPathDirname,
Rule::OsPathSamefile,
Rule::OsPathSplitext,
Rule::BuiltinOpen,
])
},
)?;
assert_diagnostics!(snapshot, diagnostics);
Ok(())
}
#[test_case(Rule::OsPathGetsize, Path::new("PTH202.py"))]
#[test_case(Rule::OsPathGetsize, Path::new("PTH202_2.py"))]
#[test_case(Rule::OsPathGetatime, Path::new("PTH203.py"))]

View file

@ -1,19 +1,45 @@
pub(crate) use glob_rule::*;
pub(crate) use invalid_pathlib_with_suffix::*;
pub(crate) use os_path_abspath::*;
pub(crate) use os_path_basename::*;
pub(crate) use os_path_dirname::*;
pub(crate) use os_path_exists::*;
pub(crate) use os_path_expanduser::*;
pub(crate) use os_path_getatime::*;
pub(crate) use os_path_getctime::*;
pub(crate) use os_path_getmtime::*;
pub(crate) use os_path_getsize::*;
pub(crate) use os_path_isabs::*;
pub(crate) use os_path_isdir::*;
pub(crate) use os_path_isfile::*;
pub(crate) use os_path_islink::*;
pub(crate) use os_readlink::*;
pub(crate) use os_remove::*;
pub(crate) use os_rmdir::*;
pub(crate) use os_sep_split::*;
pub(crate) use os_unlink::*;
pub(crate) use path_constructor_current_directory::*;
pub(crate) use replaceable_by_pathlib::*;
mod glob_rule;
mod invalid_pathlib_with_suffix;
mod os_path_abspath;
mod os_path_basename;
mod os_path_dirname;
mod os_path_exists;
mod os_path_expanduser;
mod os_path_getatime;
mod os_path_getctime;
mod os_path_getmtime;
mod os_path_getsize;
mod os_path_isabs;
mod os_path_isdir;
mod os_path_isfile;
mod os_path_islink;
mod os_readlink;
mod os_remove;
mod os_rmdir;
mod os_sep_split;
mod os_unlink;
mod path_constructor_current_directory;
mod replaceable_by_pathlib;

View file

@ -0,0 +1,74 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_abspath_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.abspath`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// file_path = os.path.abspath("../path/to/file")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// file_path = Path("../path/to/file").resolve()
/// ```
///
/// ## 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.
///
/// ## 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.resolve`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve)
/// - [Python documentation: `os.path.abspath`](https://docs.python.org/3/library/os.path.html#os.path.abspath)
/// - [PEP 428 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 OsPathAbspath;
impl Violation for OsPathAbspath {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.abspath()` should be replaced by `Path.resolve()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).resolve()`".to_string())
}
}
/// PTH100
pub(crate) fn os_path_abspath(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "abspath"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"resolve()",
"path",
is_fix_os_path_abspath_enabled(checker.settings()),
OsPathAbspath,
);
}

View file

@ -0,0 +1,73 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_basename_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.basename`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.basename(__file__)
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## Fix Safety
/// This rule's fix is marked as unsafe if the replacement would remove comments attached to the original expression.
///
/// ## References
/// - [Python documentation: `PurePath.name`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.name)
/// - [Python documentation: `os.path.basename`](https://docs.python.org/3/library/os.path.html#os.path.basename)
/// - [PEP 428 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 OsPathBasename;
impl Violation for OsPathBasename {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.basename()` should be replaced by `Path.name`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).name`".to_string())
}
}
/// PTH119
pub(crate) fn os_path_basename(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "basename"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"name",
"p",
is_fix_os_path_basename_enabled(checker.settings()),
OsPathBasename,
);
}

View file

@ -0,0 +1,73 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_dirname_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.dirname`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.dirname(__file__)
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// Path(__file__).parent
/// ```
///
/// ## Fix Safety
/// This rule's fix is marked as unsafe if the replacement would remove comments attached to the original expression.
///
/// ## 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)
/// - [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 OsPathDirname;
impl Violation for OsPathDirname {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.dirname()` should be replaced by `Path.parent`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).parent`".to_string())
}
}
/// PTH120
pub(crate) fn os_path_dirname(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "dirname"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"parent",
"p",
is_fix_os_path_dirname_enabled(checker.settings()),
OsPathDirname,
);
}

View file

@ -0,0 +1,73 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_exists_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.exists`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.exists("file.py")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.exists`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.exists)
/// - [Python documentation: `os.path.exists`](https://docs.python.org/3/library/os.path.html#os.path.exists)
/// - [PEP 428 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 OsPathExists;
impl Violation for OsPathExists {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.exists()` should be replaced by `Path.exists()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).exists()`".to_string())
}
}
/// PTH110
pub(crate) fn os_path_exists(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "exists"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"exists()",
"path",
is_fix_os_path_exists_enabled(checker.settings()),
OsPathExists,
);
}

View file

@ -0,0 +1,73 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_expanduser_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.expanduser`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.expanduser("~/films/Monty Python")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.expanduser`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.expanduser)
/// - [Python documentation: `os.path.expanduser`](https://docs.python.org/3/library/os.path.html#os.path.expanduser)
/// - [PEP 428 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 OsPathExpanduser;
impl Violation for OsPathExpanduser {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.expanduser()` should be replaced by `Path.expanduser()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).expanduser()`".to_string())
}
}
/// PTH111
pub(crate) fn os_path_expanduser(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "expanduser"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"expanduser()",
"path",
is_fix_os_path_expanduser_enabled(checker.settings()),
OsPathExpanduser,
);
}

View file

@ -1,6 +1,6 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_getatime_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_path_get_calls;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
@ -61,12 +61,15 @@ impl Violation for OsPathGetatime {
}
/// PTH203
pub(crate) fn os_path_getatime(checker: &Checker, call: &ExprCall) {
check_os_path_get_calls(
pub(crate) fn os_path_getatime(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "getatime"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"getatime",
"st_atime",
"stat().st_atime",
"filename",
is_fix_os_path_getatime_enabled(checker.settings()),
OsPathGetatime,
);

View file

@ -1,6 +1,6 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_getctime_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_path_get_calls;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
@ -62,12 +62,15 @@ impl Violation for OsPathGetctime {
}
/// PTH205
pub(crate) fn os_path_getctime(checker: &Checker, call: &ExprCall) {
check_os_path_get_calls(
pub(crate) fn os_path_getctime(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "getctime"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"getctime",
"st_ctime",
"stat().st_ctime",
"filename",
is_fix_os_path_getctime_enabled(checker.settings()),
OsPathGetctime,
);

View file

@ -1,6 +1,6 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_getmtime_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_path_get_calls;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
@ -62,12 +62,15 @@ impl Violation for OsPathGetmtime {
}
/// PTH204
pub(crate) fn os_path_getmtime(checker: &Checker, call: &ExprCall) {
check_os_path_get_calls(
pub(crate) fn os_path_getmtime(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "getmtime"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"getmtime",
"st_mtime",
"stat().st_mtime",
"filename",
is_fix_os_path_getmtime_enabled(checker.settings()),
OsPathGetmtime,
);

View file

@ -1,6 +1,6 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_getsize_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_path_get_calls;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
@ -62,12 +62,15 @@ impl Violation for OsPathGetsize {
}
/// PTH202
pub(crate) fn os_path_getsize(checker: &Checker, call: &ExprCall) {
check_os_path_get_calls(
pub(crate) fn os_path_getsize(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "getsize"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"getsize",
"st_size",
"stat().st_size",
"filename",
is_fix_os_path_getsize_enabled(checker.settings()),
OsPathGetsize,
);

View file

@ -0,0 +1,72 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_isabs_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.isabs`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// if os.path.isabs(file_name):
/// print("Absolute path!")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// if Path(file_name).is_absolute():
/// print("Absolute path!")
/// ```
///
/// ## 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)
/// - [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 OsPathIsabs;
impl Violation for OsPathIsabs {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.isabs()` should be replaced by `Path.is_absolute()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).is_absolute()`".to_string())
}
}
/// PTH117
pub(crate) fn os_path_isabs(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "isabs"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"is_absolute()",
"s",
is_fix_os_path_isabs_enabled(checker.settings()),
OsPathIsabs,
);
}

View file

@ -0,0 +1,75 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_isdir_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.isdir`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.isdir("docs")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.is_dir`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_dir)
/// - [Python documentation: `os.path.isdir`](https://docs.python.org/3/library/os.path.html#os.path.isdir)
/// - [PEP 428 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 OsPathIsdir;
impl Violation for OsPathIsdir {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.isdir()` should be replaced by `Path.is_dir()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).is_dir()`".to_string())
}
}
/// PTH112
pub(crate) fn os_path_isdir(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "isdir"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"is_dir()",
"s",
is_fix_os_path_isdir_enabled(checker.settings()),
OsPathIsdir,
);
}

View file

@ -0,0 +1,75 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_isfile_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.isfile`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.isfile("docs")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.is_file`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_file)
/// - [Python documentation: `os.path.isfile`](https://docs.python.org/3/library/os.path.html#os.path.isfile)
/// - [PEP 428 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 OsPathIsfile;
impl Violation for OsPathIsfile {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.isfile()` should be replaced by `Path.is_file()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).is_file()`".to_string())
}
}
/// PTH113
pub(crate) fn os_path_isfile(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "isfile"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"is_file()",
"path",
is_fix_os_path_isfile_enabled(checker.settings()),
OsPathIsfile,
);
}

View file

@ -0,0 +1,75 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_path_islink_enabled;
use crate::rules::flake8_use_pathlib::helpers::check_os_pathlib_single_arg_calls;
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.path.islink`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.islink("docs")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.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)
/// - [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 OsPathIslink;
impl Violation for OsPathIslink {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.islink()` should be replaced by `Path.is_symlink()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).is_symlink()`".to_string())
}
}
/// PTH114
pub(crate) fn os_path_islink(checker: &Checker, call: &ExprCall, segments: &[&str]) {
if segments != ["os", "path", "islink"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"is_symlink()",
"path",
is_fix_os_path_islink_enabled(checker.settings()),
OsPathIslink,
);
}

View file

@ -0,0 +1,91 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_readlink_enabled;
use crate::rules::flake8_use_pathlib::helpers::{
check_os_pathlib_single_arg_calls, is_keyword_only_argument_non_default,
};
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::{ExprCall, PythonVersion};
/// ## What it does
/// Checks for uses of `os.readlink`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.readlink()` can improve readability over the `os`
/// module's counterparts (e.g., `os.readlink()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.readlink(file_name)
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.readlink`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.readline)
/// - [Python documentation: `os.readlink`](https://docs.python.org/3/library/os.html#os.readlink)
/// - [PEP 428 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 OsReadlink;
impl Violation for OsReadlink {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.readlink()` should be replaced by `Path.readlink()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).readlink()`".to_string())
}
}
/// PTH115
pub(crate) fn os_readlink(checker: &Checker, call: &ExprCall, segments: &[&str]) {
// Python 3.9+
if checker.target_version() < PythonVersion::PY39 {
return;
}
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.readlink)
// ```text
// 0 1
// os.readlink(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
if segments != ["os", "readlink"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"readlink()",
"path",
is_fix_os_readlink_enabled(checker.settings()),
OsReadlink,
);
}

View file

@ -0,0 +1,86 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_remove_enabled;
use crate::rules::flake8_use_pathlib::helpers::{
check_os_pathlib_single_arg_calls, is_keyword_only_argument_non_default,
};
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.remove`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.unlink()` can improve readability over the `os`
/// module's counterparts (e.g., `os.remove()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.remove("file.py")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.unlink`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.unlink)
/// - [Python documentation: `os.remove`](https://docs.python.org/3/library/os.html#os.remove)
/// - [PEP 428 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 OsRemove;
impl Violation for OsRemove {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.remove()` should be replaced by `Path.unlink()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).unlink()`".to_string())
}
}
/// PTH107
pub(crate) fn os_remove(checker: &Checker, call: &ExprCall, segments: &[&str]) {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.remove)
// ```text
// 0 1
// os.remove(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
if segments != ["os", "remove"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"unlink()",
"path",
is_fix_os_remove_enabled(checker.settings()),
OsRemove,
);
}

View file

@ -0,0 +1,86 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_rmdir_enabled;
use crate::rules::flake8_use_pathlib::helpers::{
check_os_pathlib_single_arg_calls, is_keyword_only_argument_non_default,
};
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.rmdir`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.rmdir()` can improve readability over the `os`
/// module's counterparts (e.g., `os.rmdir()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.rmdir("folder/")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.rmdir`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.rmdir)
/// - [Python documentation: `os.rmdir`](https://docs.python.org/3/library/os.html#os.rmdir)
/// - [PEP 428 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 OsRmdir;
impl Violation for OsRmdir {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.rmdir()` should be replaced by `Path.rmdir()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).rmdir()`".to_string())
}
}
/// PTH106
pub(crate) fn os_rmdir(checker: &Checker, call: &ExprCall, segments: &[&str]) {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.rmdir)
// ```text
// 0 1
// os.rmdir(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
if segments != ["os", "rmdir"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"rmdir()",
"path",
is_fix_os_rmdir_enabled(checker.settings()),
OsRmdir,
);
}

View file

@ -0,0 +1,86 @@
use crate::checkers::ast::Checker;
use crate::preview::is_fix_os_unlink_enabled;
use crate::rules::flake8_use_pathlib::helpers::{
check_os_pathlib_single_arg_calls, is_keyword_only_argument_non_default,
};
use crate::{FixAvailability, Violation};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::ExprCall;
/// ## What it does
/// Checks for uses of `os.unlink`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.unlink()` can improve readability over the `os`
/// module's counterparts (e.g., `os.unlink()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.unlink("file.py")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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.
///
/// ## 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.unlink`](https://docs.python.org/3/library/pathlib.html#pathlib.Path.unlink)
/// - [Python documentation: `os.unlink`](https://docs.python.org/3/library/os.html#os.unlink)
/// - [PEP 428 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 OsUnlink;
impl Violation for OsUnlink {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
"`os.unlink()` should be replaced by `Path.unlink()`".to_string()
}
fn fix_title(&self) -> Option<String> {
Some("Replace with `Path(...).unlink()`".to_string())
}
}
/// PTH108
pub(crate) fn os_unlink(checker: &Checker, call: &ExprCall, segments: &[&str]) {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.unlink)
// ```text
// 0 1
// os.unlink(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
if segments != ["os", "unlink"] {
return;
}
check_os_pathlib_single_arg_calls(
checker,
call,
"unlink()",
"path",
is_fix_os_unlink_enabled(checker.settings()),
OsUnlink,
);
}

View file

@ -54,7 +54,11 @@ impl AlwaysFixableViolation for PathConstructorCurrentDirectory {
}
/// PTH201
pub(crate) fn path_constructor_current_directory(checker: &Checker, call: &ExprCall) {
pub(crate) fn path_constructor_current_directory(
checker: &Checker,
call: &ExprCall,
segments: &[&str],
) {
let applicability = |range| {
if checker.comment_ranges().intersects(range) {
Applicability::Unsafe
@ -63,15 +67,9 @@ pub(crate) fn path_constructor_current_directory(checker: &Checker, call: &ExprC
}
};
let (func, arguments) = (&call.func, &call.arguments);
let arguments = &call.arguments;
if !checker
.semantic()
.resolve_qualified_name(func)
.is_some_and(|qualified_name| {
matches!(qualified_name.segments(), ["pathlib", "Path" | "PurePath"])
})
{
if !matches!(segments, ["pathlib", "Path" | "PurePath"]) {
return;
}

View file

@ -4,14 +4,12 @@ use ruff_python_semantic::analyze::typing;
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
use crate::rules::flake8_use_pathlib::helpers::is_keyword_only_argument_non_default;
use crate::rules::flake8_use_pathlib::rules::Glob;
use crate::rules::flake8_use_pathlib::violations::{
BuiltinOpen, Joiner, OsChmod, OsGetcwd, OsListdir, OsMakedirs, OsMkdir, OsPathAbspath,
OsPathBasename, OsPathDirname, OsPathExists, OsPathExpanduser, OsPathIsabs, OsPathIsdir,
OsPathIsfile, OsPathIslink, OsPathJoin, OsPathSamefile, OsPathSplitext, OsReadlink, OsRemove,
OsRename, OsReplace, OsRmdir, OsStat, OsSymlink, OsUnlink, PyPath,
BuiltinOpen, Joiner, OsChmod, OsGetcwd, OsListdir, OsMakedirs, OsMkdir, OsPathJoin,
OsPathSamefile, OsPathSplitext, OsRename, OsReplace, OsStat, OsSymlink, PyPath,
};
use ruff_python_ast::PythonVersion;
pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
let Some(qualified_name) = checker.semantic().resolve_qualified_name(&call.func) else {
@ -20,8 +18,6 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
let range = call.func.range();
match qualified_name.segments() {
// PTH100
["os", "path", "abspath"] => checker.report_diagnostic_if_enabled(OsPathAbspath, range),
// PTH101
["os", "chmod"] => {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
@ -87,60 +83,10 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
}
checker.report_diagnostic_if_enabled(OsReplace, range)
}
// PTH106
["os", "rmdir"] => {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.rmdir)
// ```text
// 0 1
// os.rmdir(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
checker.report_diagnostic_if_enabled(OsRmdir, range)
}
// PTH107
["os", "remove"] => {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.remove)
// ```text
// 0 1
// os.remove(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
checker.report_diagnostic_if_enabled(OsRemove, range)
}
// PTH108
["os", "unlink"] => {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.unlink)
// ```text
// 0 1
// os.unlink(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
checker.report_diagnostic_if_enabled(OsUnlink, range)
}
// PTH109
["os", "getcwd"] => checker.report_diagnostic_if_enabled(OsGetcwd, range),
["os", "getcwdb"] => checker.report_diagnostic_if_enabled(OsGetcwd, range),
// PTH110
["os", "path", "exists"] => checker.report_diagnostic_if_enabled(OsPathExists, range),
// PTH111
["os", "path", "expanduser"] => {
checker.report_diagnostic_if_enabled(OsPathExpanduser, range)
}
// PTH112
["os", "path", "isdir"] => checker.report_diagnostic_if_enabled(OsPathIsdir, range),
// PTH113
["os", "path", "isfile"] => checker.report_diagnostic_if_enabled(OsPathIsfile, range),
// PTH114
["os", "path", "islink"] => checker.report_diagnostic_if_enabled(OsPathIslink, range),
// PTH116
["os", "stat"] => {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
@ -159,8 +105,6 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
}
checker.report_diagnostic_if_enabled(OsStat, range)
}
// PTH117
["os", "path", "isabs"] => checker.report_diagnostic_if_enabled(OsPathIsabs, range),
// PTH118
["os", "path", "join"] => checker.report_diagnostic_if_enabled(
OsPathJoin {
@ -184,10 +128,6 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
},
range,
),
// PTH119
["os", "path", "basename"] => checker.report_diagnostic_if_enabled(OsPathBasename, range),
// PTH120
["os", "path", "dirname"] => checker.report_diagnostic_if_enabled(OsPathDirname, range),
// PTH121
["os", "path", "samefile"] => checker.report_diagnostic_if_enabled(OsPathSamefile, range),
// PTH122
@ -208,7 +148,7 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
// PTH123
["" | "builtins", "open"] => {
// `closefd` and `opener` are not supported by pathlib, so check if they are
// `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):
@ -282,20 +222,6 @@ pub(crate) fn replaceable_by_pathlib(checker: &Checker, call: &ExprCall) {
range,
)
}
// PTH115
// Python 3.9+
["os", "readlink"] if checker.target_version() >= PythonVersion::PY39 => {
// `dir_fd` is not supported by pathlib, so check if it's set to non-default values.
// Signature as of Python 3.13 (https://docs.python.org/3/library/os.html#os.readlink)
// ```text
// 0 1
// os.readlink(path, *, dir_fd=None)
// ```
if is_keyword_only_argument_non_default(&call.arguments, "dir_fd") {
return;
}
checker.report_diagnostic_if_enabled(OsReadlink, range)
}
// PTH208
["os", "listdir"] => {
if call
@ -338,7 +264,7 @@ fn is_file_descriptor(expr: &Expr, semantic: &SemanticModel) -> bool {
fn get_name_expr(expr: &Expr) -> Option<&ast::ExprName> {
match expr {
Expr::Name(name) => Some(name),
Expr::Call(ast::ExprCall { func, .. }) => get_name_expr(func),
Expr::Call(ExprCall { func, .. }) => get_name_expr(func),
_ => None,
}
}
@ -349,9 +275,3 @@ fn is_argument_non_default(arguments: &ast::Arguments, name: &str, position: usi
.find_argument_value(name, position)
.is_some_and(|expr| !expr.is_none_literal_expr())
}
fn is_keyword_only_argument_non_default(arguments: &ast::Arguments, name: &str) -> bool {
arguments
.find_keyword(name)
.is_some_and(|keyword| !keyword.value.is_none_literal_expr())
}

View file

@ -10,6 +10,7 @@ full_name.py:7:5: PTH100 `os.path.abspath()` should be replaced by `Path.resolve
8 | aa = os.chmod(p)
9 | aaa = os.mkdir(p)
|
= help: Replace with `Path(...).resolve()`
full_name.py:8:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
@ -69,6 +70,7 @@ full_name.py:13:1: PTH106 `os.rmdir()` should be replaced by `Path.rmdir()`
14 | os.remove(p)
15 | os.unlink(p)
|
= help: Replace with `Path(...).rmdir()`
full_name.py:14:1: PTH107 `os.remove()` should be replaced by `Path.unlink()`
|
@ -79,6 +81,7 @@ full_name.py:14:1: PTH107 `os.remove()` should be replaced by `Path.unlink()`
15 | os.unlink(p)
16 | os.getcwd(p)
|
= help: Replace with `Path(...).unlink()`
full_name.py:15:1: PTH108 `os.unlink()` should be replaced by `Path.unlink()`
|
@ -89,6 +92,7 @@ full_name.py:15:1: PTH108 `os.unlink()` should be replaced by `Path.unlink()`
16 | os.getcwd(p)
17 | b = os.path.exists(p)
|
= help: Replace with `Path(...).unlink()`
full_name.py:16:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
@ -109,6 +113,7 @@ full_name.py:17:5: PTH110 `os.path.exists()` should be replaced by `Path.exists(
18 | bb = os.path.expanduser(p)
19 | bbb = os.path.isdir(p)
|
= help: Replace with `Path(...).exists()`
full_name.py:18:6: PTH111 `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
@ -119,6 +124,7 @@ full_name.py:18:6: PTH111 `os.path.expanduser()` should be replaced by `Path.exp
19 | bbb = os.path.isdir(p)
20 | bbbb = os.path.isfile(p)
|
= help: Replace with `Path(...).expanduser()`
full_name.py:19:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_dir()`
|
@ -129,6 +135,7 @@ full_name.py:19:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_dir()
20 | bbbb = os.path.isfile(p)
21 | bbbbb = os.path.islink(p)
|
= help: Replace with `Path(...).is_dir()`
full_name.py:20:8: PTH113 `os.path.isfile()` should be replaced by `Path.is_file()`
|
@ -139,6 +146,7 @@ full_name.py:20:8: PTH113 `os.path.isfile()` should be replaced by `Path.is_file
21 | bbbbb = os.path.islink(p)
22 | os.readlink(p)
|
= help: Replace with `Path(...).is_file()`
full_name.py:21:9: PTH114 `os.path.islink()` should be replaced by `Path.is_symlink()`
|
@ -149,6 +157,7 @@ full_name.py:21:9: PTH114 `os.path.islink()` should be replaced by `Path.is_syml
22 | os.readlink(p)
23 | os.stat(p)
|
= help: Replace with `Path(...).is_symlink()`
full_name.py:22:1: PTH115 `os.readlink()` should be replaced by `Path.readlink()`
|
@ -159,6 +168,7 @@ full_name.py:22:1: PTH115 `os.readlink()` should be replaced by `Path.readlink()
23 | os.stat(p)
24 | os.path.isabs(p)
|
= help: Replace with `Path(...).readlink()`
full_name.py:23:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
@ -179,6 +189,7 @@ full_name.py:24:1: PTH117 `os.path.isabs()` should be replaced by `Path.is_absol
25 | os.path.join(p, q)
26 | os.sep.join([p, q])
|
= help: Replace with `Path(...).is_absolute()`
full_name.py:25:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
@ -219,6 +230,7 @@ full_name.py:28:1: PTH119 `os.path.basename()` should be replaced by `Path.name`
29 | os.path.dirname(p)
30 | os.path.samefile(p)
|
= help: Replace with `Path(...).name`
full_name.py:29:1: PTH120 `os.path.dirname()` should be replaced by `Path.parent`
|
@ -229,6 +241,7 @@ full_name.py:29:1: PTH120 `os.path.dirname()` should be replaced by `Path.parent
30 | os.path.samefile(p)
31 | os.path.splitext(p)
|
= help: Replace with `Path(...).parent`
full_name.py:30:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|

View file

@ -10,6 +10,7 @@ import_as.py:7:5: PTH100 `os.path.abspath()` should be replaced by `Path.resolve
8 | aa = foo.chmod(p)
9 | aaa = foo.mkdir(p)
|
= help: Replace with `Path(...).resolve()`
import_as.py:8:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
@ -69,6 +70,7 @@ import_as.py:13:1: PTH106 `os.rmdir()` should be replaced by `Path.rmdir()`
14 | foo.remove(p)
15 | foo.unlink(p)
|
= help: Replace with `Path(...).rmdir()`
import_as.py:14:1: PTH107 `os.remove()` should be replaced by `Path.unlink()`
|
@ -79,6 +81,7 @@ import_as.py:14:1: PTH107 `os.remove()` should be replaced by `Path.unlink()`
15 | foo.unlink(p)
16 | foo.getcwd(p)
|
= help: Replace with `Path(...).unlink()`
import_as.py:15:1: PTH108 `os.unlink()` should be replaced by `Path.unlink()`
|
@ -89,6 +92,7 @@ import_as.py:15:1: PTH108 `os.unlink()` should be replaced by `Path.unlink()`
16 | foo.getcwd(p)
17 | b = foo_p.exists(p)
|
= help: Replace with `Path(...).unlink()`
import_as.py:16:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
@ -109,6 +113,7 @@ import_as.py:17:5: PTH110 `os.path.exists()` should be replaced by `Path.exists(
18 | bb = foo_p.expanduser(p)
19 | bbb = foo_p.isdir(p)
|
= help: Replace with `Path(...).exists()`
import_as.py:18:6: PTH111 `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
@ -119,6 +124,7 @@ import_as.py:18:6: PTH111 `os.path.expanduser()` should be replaced by `Path.exp
19 | bbb = foo_p.isdir(p)
20 | bbbb = foo_p.isfile(p)
|
= help: Replace with `Path(...).expanduser()`
import_as.py:19:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_dir()`
|
@ -129,6 +135,7 @@ import_as.py:19:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_dir()
20 | bbbb = foo_p.isfile(p)
21 | bbbbb = foo_p.islink(p)
|
= help: Replace with `Path(...).is_dir()`
import_as.py:20:8: PTH113 `os.path.isfile()` should be replaced by `Path.is_file()`
|
@ -139,6 +146,7 @@ import_as.py:20:8: PTH113 `os.path.isfile()` should be replaced by `Path.is_file
21 | bbbbb = foo_p.islink(p)
22 | foo.readlink(p)
|
= help: Replace with `Path(...).is_file()`
import_as.py:21:9: PTH114 `os.path.islink()` should be replaced by `Path.is_symlink()`
|
@ -149,6 +157,7 @@ import_as.py:21:9: PTH114 `os.path.islink()` should be replaced by `Path.is_syml
22 | foo.readlink(p)
23 | foo.stat(p)
|
= help: Replace with `Path(...).is_symlink()`
import_as.py:22:1: PTH115 `os.readlink()` should be replaced by `Path.readlink()`
|
@ -159,6 +168,7 @@ import_as.py:22:1: PTH115 `os.readlink()` should be replaced by `Path.readlink()
23 | foo.stat(p)
24 | foo_p.isabs(p)
|
= help: Replace with `Path(...).readlink()`
import_as.py:23:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
@ -179,6 +189,7 @@ import_as.py:24:1: PTH117 `os.path.isabs()` should be replaced by `Path.is_absol
25 | foo_p.join(p, q)
26 | foo.sep.join([p, q])
|
= help: Replace with `Path(...).is_absolute()`
import_as.py:25:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
@ -219,6 +230,7 @@ import_as.py:28:1: PTH119 `os.path.basename()` should be replaced by `Path.name`
29 | foo_p.dirname(p)
30 | foo_p.samefile(p)
|
= help: Replace with `Path(...).name`
import_as.py:29:1: PTH120 `os.path.dirname()` should be replaced by `Path.parent`
|
@ -229,6 +241,7 @@ import_as.py:29:1: PTH120 `os.path.dirname()` should be replaced by `Path.parent
30 | foo_p.samefile(p)
31 | foo_p.splitext(p)
|
= help: Replace with `Path(...).parent`
import_as.py:30:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|

View file

@ -10,6 +10,7 @@ import_from.py:9:5: PTH100 `os.path.abspath()` should be replaced by `Path.resol
10 | aa = chmod(p)
11 | aaa = mkdir(p)
|
= help: Replace with `Path(...).resolve()`
import_from.py:10:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
@ -69,6 +70,7 @@ import_from.py:15:1: PTH106 `os.rmdir()` should be replaced by `Path.rmdir()`
16 | remove(p)
17 | unlink(p)
|
= help: Replace with `Path(...).rmdir()`
import_from.py:16:1: PTH107 `os.remove()` should be replaced by `Path.unlink()`
|
@ -79,6 +81,7 @@ import_from.py:16:1: PTH107 `os.remove()` should be replaced by `Path.unlink()`
17 | unlink(p)
18 | getcwd(p)
|
= help: Replace with `Path(...).unlink()`
import_from.py:17:1: PTH108 `os.unlink()` should be replaced by `Path.unlink()`
|
@ -89,6 +92,7 @@ import_from.py:17:1: PTH108 `os.unlink()` should be replaced by `Path.unlink()`
18 | getcwd(p)
19 | b = exists(p)
|
= help: Replace with `Path(...).unlink()`
import_from.py:18:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
@ -109,6 +113,7 @@ import_from.py:19:5: PTH110 `os.path.exists()` should be replaced by `Path.exist
20 | bb = expanduser(p)
21 | bbb = isdir(p)
|
= help: Replace with `Path(...).exists()`
import_from.py:20:6: PTH111 `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
@ -119,6 +124,7 @@ import_from.py:20:6: PTH111 `os.path.expanduser()` should be replaced by `Path.e
21 | bbb = isdir(p)
22 | bbbb = isfile(p)
|
= help: Replace with `Path(...).expanduser()`
import_from.py:21:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_dir()`
|
@ -129,6 +135,7 @@ import_from.py:21:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_dir
22 | bbbb = isfile(p)
23 | bbbbb = islink(p)
|
= help: Replace with `Path(...).is_dir()`
import_from.py:22:8: PTH113 `os.path.isfile()` should be replaced by `Path.is_file()`
|
@ -139,6 +146,7 @@ import_from.py:22:8: PTH113 `os.path.isfile()` should be replaced by `Path.is_fi
23 | bbbbb = islink(p)
24 | readlink(p)
|
= help: Replace with `Path(...).is_file()`
import_from.py:23:9: PTH114 `os.path.islink()` should be replaced by `Path.is_symlink()`
|
@ -149,6 +157,7 @@ import_from.py:23:9: PTH114 `os.path.islink()` should be replaced by `Path.is_sy
24 | readlink(p)
25 | stat(p)
|
= help: Replace with `Path(...).is_symlink()`
import_from.py:24:1: PTH115 `os.readlink()` should be replaced by `Path.readlink()`
|
@ -159,6 +168,7 @@ import_from.py:24:1: PTH115 `os.readlink()` should be replaced by `Path.readlink
25 | stat(p)
26 | isabs(p)
|
= help: Replace with `Path(...).readlink()`
import_from.py:25:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
@ -179,6 +189,7 @@ import_from.py:26:1: PTH117 `os.path.isabs()` should be replaced by `Path.is_abs
27 | join(p, q)
28 | sep.join((p, q))
|
= help: Replace with `Path(...).is_absolute()`
import_from.py:27:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
@ -219,6 +230,7 @@ import_from.py:30:1: PTH119 `os.path.basename()` should be replaced by `Path.nam
31 | dirname(p)
32 | samefile(p)
|
= help: Replace with `Path(...).name`
import_from.py:31:1: PTH120 `os.path.dirname()` should be replaced by `Path.parent`
|
@ -229,6 +241,7 @@ import_from.py:31:1: PTH120 `os.path.dirname()` should be replaced by `Path.pare
32 | samefile(p)
33 | splitext(p)
|
= help: Replace with `Path(...).parent`
import_from.py:32:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|

View file

@ -10,6 +10,7 @@ import_from_as.py:14:5: PTH100 `os.path.abspath()` should be replaced by `Path.r
15 | aa = xchmod(p)
16 | aaa = xmkdir(p)
|
= help: Replace with `Path(...).resolve()`
import_from_as.py:15:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
@ -69,6 +70,7 @@ import_from_as.py:20:1: PTH106 `os.rmdir()` should be replaced by `Path.rmdir()`
21 | xremove(p)
22 | xunlink(p)
|
= help: Replace with `Path(...).rmdir()`
import_from_as.py:21:1: PTH107 `os.remove()` should be replaced by `Path.unlink()`
|
@ -79,6 +81,7 @@ import_from_as.py:21:1: PTH107 `os.remove()` should be replaced by `Path.unlink(
22 | xunlink(p)
23 | xgetcwd(p)
|
= help: Replace with `Path(...).unlink()`
import_from_as.py:22:1: PTH108 `os.unlink()` should be replaced by `Path.unlink()`
|
@ -89,6 +92,7 @@ import_from_as.py:22:1: PTH108 `os.unlink()` should be replaced by `Path.unlink(
23 | xgetcwd(p)
24 | b = xexists(p)
|
= help: Replace with `Path(...).unlink()`
import_from_as.py:23:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
@ -109,6 +113,7 @@ import_from_as.py:24:5: PTH110 `os.path.exists()` should be replaced by `Path.ex
25 | bb = xexpanduser(p)
26 | bbb = xisdir(p)
|
= help: Replace with `Path(...).exists()`
import_from_as.py:25:6: PTH111 `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
@ -119,6 +124,7 @@ import_from_as.py:25:6: PTH111 `os.path.expanduser()` should be replaced by `Pat
26 | bbb = xisdir(p)
27 | bbbb = xisfile(p)
|
= help: Replace with `Path(...).expanduser()`
import_from_as.py:26:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_dir()`
|
@ -129,6 +135,7 @@ import_from_as.py:26:7: PTH112 `os.path.isdir()` should be replaced by `Path.is_
27 | bbbb = xisfile(p)
28 | bbbbb = xislink(p)
|
= help: Replace with `Path(...).is_dir()`
import_from_as.py:27:8: PTH113 `os.path.isfile()` should be replaced by `Path.is_file()`
|
@ -139,6 +146,7 @@ import_from_as.py:27:8: PTH113 `os.path.isfile()` should be replaced by `Path.is
28 | bbbbb = xislink(p)
29 | xreadlink(p)
|
= help: Replace with `Path(...).is_file()`
import_from_as.py:28:9: PTH114 `os.path.islink()` should be replaced by `Path.is_symlink()`
|
@ -149,6 +157,7 @@ import_from_as.py:28:9: PTH114 `os.path.islink()` should be replaced by `Path.is
29 | xreadlink(p)
30 | xstat(p)
|
= help: Replace with `Path(...).is_symlink()`
import_from_as.py:29:1: PTH115 `os.readlink()` should be replaced by `Path.readlink()`
|
@ -159,6 +168,7 @@ import_from_as.py:29:1: PTH115 `os.readlink()` should be replaced by `Path.readl
30 | xstat(p)
31 | xisabs(p)
|
= help: Replace with `Path(...).readlink()`
import_from_as.py:30:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
@ -179,6 +189,7 @@ import_from_as.py:31:1: PTH117 `os.path.isabs()` should be replaced by `Path.is_
32 | xjoin(p, q)
33 | s.join((p, q))
|
= help: Replace with `Path(...).is_absolute()`
import_from_as.py:32:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
@ -219,6 +230,7 @@ import_from_as.py:35:1: PTH119 `os.path.basename()` should be replaced by `Path.
36 | xdirname(p)
37 | xsamefile(p)
|
= help: Replace with `Path(...).name`
import_from_as.py:36:1: PTH120 `os.path.dirname()` should be replaced by `Path.parent`
|
@ -229,6 +241,7 @@ import_from_as.py:36:1: PTH120 `os.path.dirname()` should be replaced by `Path.p
37 | xsamefile(p)
38 | xsplitext(p)
|
= help: Replace with `Path(...).parent`
import_from_as.py:37:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|

View file

@ -0,0 +1,580 @@
---
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
---
full_name.py:7:5: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
|
5 | q = "bar"
6 |
7 | a = os.path.abspath(p)
| ^^^^^^^^^^^^^^^ PTH100
8 | aa = os.chmod(p)
9 | aaa = os.mkdir(p)
|
= help: Replace with `Path(...).resolve()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
6 7 |
7 |-a = os.path.abspath(p)
8 |+a = pathlib.Path(p).resolve()
8 9 | aa = os.chmod(p)
9 10 | aaa = os.mkdir(p)
10 11 | os.makedirs(p)
full_name.py:8:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
7 | a = os.path.abspath(p)
8 | aa = os.chmod(p)
| ^^^^^^^^ PTH101
9 | aaa = os.mkdir(p)
10 | os.makedirs(p)
|
full_name.py:9:7: PTH102 `os.mkdir()` should be replaced by `Path.mkdir()`
|
7 | a = os.path.abspath(p)
8 | aa = os.chmod(p)
9 | aaa = os.mkdir(p)
| ^^^^^^^^ PTH102
10 | os.makedirs(p)
11 | os.rename(p)
|
full_name.py:10:1: PTH103 `os.makedirs()` should be replaced by `Path.mkdir(parents=True)`
|
8 | aa = os.chmod(p)
9 | aaa = os.mkdir(p)
10 | os.makedirs(p)
| ^^^^^^^^^^^ PTH103
11 | os.rename(p)
12 | os.replace(p)
|
full_name.py:11:1: PTH104 `os.rename()` should be replaced by `Path.rename()`
|
9 | aaa = os.mkdir(p)
10 | os.makedirs(p)
11 | os.rename(p)
| ^^^^^^^^^ PTH104
12 | os.replace(p)
13 | os.rmdir(p)
|
full_name.py:12:1: PTH105 `os.replace()` should be replaced by `Path.replace()`
|
10 | os.makedirs(p)
11 | os.rename(p)
12 | os.replace(p)
| ^^^^^^^^^^ PTH105
13 | os.rmdir(p)
14 | os.remove(p)
|
full_name.py:13:1: PTH106 [*] `os.rmdir()` should be replaced by `Path.rmdir()`
|
11 | os.rename(p)
12 | os.replace(p)
13 | os.rmdir(p)
| ^^^^^^^^ PTH106
14 | os.remove(p)
15 | os.unlink(p)
|
= help: Replace with `Path(...).rmdir()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
10 11 | os.makedirs(p)
11 12 | os.rename(p)
12 13 | os.replace(p)
13 |-os.rmdir(p)
14 |+pathlib.Path(p).rmdir()
14 15 | os.remove(p)
15 16 | os.unlink(p)
16 17 | os.getcwd(p)
full_name.py:14:1: PTH107 [*] `os.remove()` should be replaced by `Path.unlink()`
|
12 | os.replace(p)
13 | os.rmdir(p)
14 | os.remove(p)
| ^^^^^^^^^ PTH107
15 | os.unlink(p)
16 | os.getcwd(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
11 12 | os.rename(p)
12 13 | os.replace(p)
13 14 | os.rmdir(p)
14 |-os.remove(p)
15 |+pathlib.Path(p).unlink()
15 16 | os.unlink(p)
16 17 | os.getcwd(p)
17 18 | b = os.path.exists(p)
full_name.py:15:1: PTH108 [*] `os.unlink()` should be replaced by `Path.unlink()`
|
13 | os.rmdir(p)
14 | os.remove(p)
15 | os.unlink(p)
| ^^^^^^^^^ PTH108
16 | os.getcwd(p)
17 | b = os.path.exists(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
12 13 | os.replace(p)
13 14 | os.rmdir(p)
14 15 | os.remove(p)
15 |-os.unlink(p)
16 |+pathlib.Path(p).unlink()
16 17 | os.getcwd(p)
17 18 | b = os.path.exists(p)
18 19 | bb = os.path.expanduser(p)
full_name.py:16:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
14 | os.remove(p)
15 | os.unlink(p)
16 | os.getcwd(p)
| ^^^^^^^^^ PTH109
17 | b = os.path.exists(p)
18 | bb = os.path.expanduser(p)
|
full_name.py:17:5: PTH110 [*] `os.path.exists()` should be replaced by `Path.exists()`
|
15 | os.unlink(p)
16 | os.getcwd(p)
17 | b = os.path.exists(p)
| ^^^^^^^^^^^^^^ PTH110
18 | bb = os.path.expanduser(p)
19 | bbb = os.path.isdir(p)
|
= help: Replace with `Path(...).exists()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
14 15 | os.remove(p)
15 16 | os.unlink(p)
16 17 | os.getcwd(p)
17 |-b = os.path.exists(p)
18 |+b = pathlib.Path(p).exists()
18 19 | bb = os.path.expanduser(p)
19 20 | bbb = os.path.isdir(p)
20 21 | bbbb = os.path.isfile(p)
full_name.py:18:6: PTH111 [*] `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
16 | os.getcwd(p)
17 | b = os.path.exists(p)
18 | bb = os.path.expanduser(p)
| ^^^^^^^^^^^^^^^^^^ PTH111
19 | bbb = os.path.isdir(p)
20 | bbbb = os.path.isfile(p)
|
= help: Replace with `Path(...).expanduser()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
15 16 | os.unlink(p)
16 17 | os.getcwd(p)
17 18 | b = os.path.exists(p)
18 |-bb = os.path.expanduser(p)
19 |+bb = pathlib.Path(p).expanduser()
19 20 | bbb = os.path.isdir(p)
20 21 | bbbb = os.path.isfile(p)
21 22 | bbbbb = os.path.islink(p)
full_name.py:19:7: PTH112 [*] `os.path.isdir()` should be replaced by `Path.is_dir()`
|
17 | b = os.path.exists(p)
18 | bb = os.path.expanduser(p)
19 | bbb = os.path.isdir(p)
| ^^^^^^^^^^^^^ PTH112
20 | bbbb = os.path.isfile(p)
21 | bbbbb = os.path.islink(p)
|
= help: Replace with `Path(...).is_dir()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
16 17 | os.getcwd(p)
17 18 | b = os.path.exists(p)
18 19 | bb = os.path.expanduser(p)
19 |-bbb = os.path.isdir(p)
20 |+bbb = pathlib.Path(p).is_dir()
20 21 | bbbb = os.path.isfile(p)
21 22 | bbbbb = os.path.islink(p)
22 23 | os.readlink(p)
full_name.py:20:8: PTH113 [*] `os.path.isfile()` should be replaced by `Path.is_file()`
|
18 | bb = os.path.expanduser(p)
19 | bbb = os.path.isdir(p)
20 | bbbb = os.path.isfile(p)
| ^^^^^^^^^^^^^^ PTH113
21 | bbbbb = os.path.islink(p)
22 | os.readlink(p)
|
= help: Replace with `Path(...).is_file()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
17 18 | b = os.path.exists(p)
18 19 | bb = os.path.expanduser(p)
19 20 | bbb = os.path.isdir(p)
20 |-bbbb = os.path.isfile(p)
21 |+bbbb = pathlib.Path(p).is_file()
21 22 | bbbbb = os.path.islink(p)
22 23 | os.readlink(p)
23 24 | os.stat(p)
full_name.py:21:9: PTH114 [*] `os.path.islink()` should be replaced by `Path.is_symlink()`
|
19 | bbb = os.path.isdir(p)
20 | bbbb = os.path.isfile(p)
21 | bbbbb = os.path.islink(p)
| ^^^^^^^^^^^^^^ PTH114
22 | os.readlink(p)
23 | os.stat(p)
|
= help: Replace with `Path(...).is_symlink()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
18 19 | bb = os.path.expanduser(p)
19 20 | bbb = os.path.isdir(p)
20 21 | bbbb = os.path.isfile(p)
21 |-bbbbb = os.path.islink(p)
22 |+bbbbb = pathlib.Path(p).is_symlink()
22 23 | os.readlink(p)
23 24 | os.stat(p)
24 25 | os.path.isabs(p)
full_name.py:22:1: PTH115 [*] `os.readlink()` should be replaced by `Path.readlink()`
|
20 | bbbb = os.path.isfile(p)
21 | bbbbb = os.path.islink(p)
22 | os.readlink(p)
| ^^^^^^^^^^^ PTH115
23 | os.stat(p)
24 | os.path.isabs(p)
|
= help: Replace with `Path(...).readlink()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
19 20 | bbb = os.path.isdir(p)
20 21 | bbbb = os.path.isfile(p)
21 22 | bbbbb = os.path.islink(p)
22 |-os.readlink(p)
23 |+pathlib.Path(p).readlink()
23 24 | os.stat(p)
24 25 | os.path.isabs(p)
25 26 | os.path.join(p, q)
full_name.py:23:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
21 | bbbbb = os.path.islink(p)
22 | os.readlink(p)
23 | os.stat(p)
| ^^^^^^^ PTH116
24 | os.path.isabs(p)
25 | os.path.join(p, q)
|
full_name.py:24:1: PTH117 [*] `os.path.isabs()` should be replaced by `Path.is_absolute()`
|
22 | os.readlink(p)
23 | os.stat(p)
24 | os.path.isabs(p)
| ^^^^^^^^^^^^^ PTH117
25 | os.path.join(p, q)
26 | os.sep.join([p, q])
|
= help: Replace with `Path(...).is_absolute()`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
21 22 | bbbbb = os.path.islink(p)
22 23 | os.readlink(p)
23 24 | os.stat(p)
24 |-os.path.isabs(p)
25 |+pathlib.Path(p).is_absolute()
25 26 | os.path.join(p, q)
26 27 | os.sep.join([p, q])
27 28 | os.sep.join((p, q))
full_name.py:25:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
23 | os.stat(p)
24 | os.path.isabs(p)
25 | os.path.join(p, q)
| ^^^^^^^^^^^^ PTH118
26 | os.sep.join([p, q])
27 | os.sep.join((p, q))
|
full_name.py:26:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
24 | os.path.isabs(p)
25 | os.path.join(p, q)
26 | os.sep.join([p, q])
| ^^^^^^^^^^^ PTH118
27 | os.sep.join((p, q))
28 | os.path.basename(p)
|
full_name.py:27:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
25 | os.path.join(p, q)
26 | os.sep.join([p, q])
27 | os.sep.join((p, q))
| ^^^^^^^^^^^ PTH118
28 | os.path.basename(p)
29 | os.path.dirname(p)
|
full_name.py:28:1: PTH119 [*] `os.path.basename()` should be replaced by `Path.name`
|
26 | os.sep.join([p, q])
27 | os.sep.join((p, q))
28 | os.path.basename(p)
| ^^^^^^^^^^^^^^^^ PTH119
29 | os.path.dirname(p)
30 | os.path.samefile(p)
|
= help: Replace with `Path(...).name`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
25 26 | os.path.join(p, q)
26 27 | os.sep.join([p, q])
27 28 | os.sep.join((p, q))
28 |-os.path.basename(p)
29 |+pathlib.Path(p).name
29 30 | os.path.dirname(p)
30 31 | os.path.samefile(p)
31 32 | os.path.splitext(p)
full_name.py:29:1: PTH120 [*] `os.path.dirname()` should be replaced by `Path.parent`
|
27 | os.sep.join((p, q))
28 | os.path.basename(p)
29 | os.path.dirname(p)
| ^^^^^^^^^^^^^^^ PTH120
30 | os.path.samefile(p)
31 | os.path.splitext(p)
|
= help: Replace with `Path(...).parent`
Safe fix
1 1 | import os
2 2 | import os.path
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
26 27 | os.sep.join([p, q])
27 28 | os.sep.join((p, q))
28 29 | os.path.basename(p)
29 |-os.path.dirname(p)
30 |+pathlib.Path(p).parent
30 31 | os.path.samefile(p)
31 32 | os.path.splitext(p)
32 33 | with open(p) as fp:
full_name.py:30:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|
28 | os.path.basename(p)
29 | os.path.dirname(p)
30 | os.path.samefile(p)
| ^^^^^^^^^^^^^^^^ PTH121
31 | os.path.splitext(p)
32 | with open(p) as fp:
|
full_name.py:31:1: PTH122 `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, and `Path.parent`
|
29 | os.path.dirname(p)
30 | os.path.samefile(p)
31 | os.path.splitext(p)
| ^^^^^^^^^^^^^^^^ PTH122
32 | with open(p) as fp:
33 | fp.read()
|
full_name.py:32:6: PTH123 `open()` should be replaced by `Path.open()`
|
30 | os.path.samefile(p)
31 | os.path.splitext(p)
32 | with open(p) as fp:
| ^^^^ PTH123
33 | fp.read()
34 | open(p).close()
|
full_name.py:34:1: PTH123 `open()` should be replaced by `Path.open()`
|
32 | with open(p) as fp:
33 | fp.read()
34 | open(p).close()
| ^^^^ PTH123
35 | os.getcwdb(p)
36 | os.path.join(p, *q)
|
full_name.py:35:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
33 | fp.read()
34 | open(p).close()
35 | os.getcwdb(p)
| ^^^^^^^^^^ PTH109
36 | os.path.join(p, *q)
37 | os.sep.join(p, *q)
|
full_name.py:36:1: PTH118 `os.path.join()` should be replaced by `Path.joinpath()`
|
34 | open(p).close()
35 | os.getcwdb(p)
36 | os.path.join(p, *q)
| ^^^^^^^^^^^^ PTH118
37 | os.sep.join(p, *q)
|
full_name.py:37:1: PTH118 `os.sep.join()` should be replaced by `Path.joinpath()`
|
35 | os.getcwdb(p)
36 | os.path.join(p, *q)
37 | os.sep.join(p, *q)
| ^^^^^^^^^^^ PTH118
38 |
39 | # https://github.com/astral-sh/ruff/issues/7620
|
full_name.py:46:1: PTH123 `open()` should be replaced by `Path.open()`
|
44 | open(p, closefd=False)
45 | open(p, opener=opener)
46 | open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
| ^^^^ PTH123
47 | open(p, 'r', - 1, None, None, None, True, None)
48 | open(p, 'r', - 1, None, None, None, False, opener)
|
full_name.py:47:1: PTH123 `open()` should be replaced by `Path.open()`
|
45 | open(p, opener=opener)
46 | open(p, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
47 | open(p, 'r', - 1, None, None, None, True, None)
| ^^^^ PTH123
48 | open(p, 'r', - 1, None, None, None, False, opener)
|
full_name.py:65:1: PTH123 `open()` should be replaced by `Path.open()`
|
63 | open(f())
64 |
65 | open(b"foo")
| ^^^^ PTH123
66 | byte_str = b"bar"
67 | open(byte_str)
|
full_name.py:67:1: PTH123 `open()` should be replaced by `Path.open()`
|
65 | open(b"foo")
66 | byte_str = b"bar"
67 | open(byte_str)
| ^^^^ PTH123
68 |
69 | def bytes_str_func() -> bytes:
|
full_name.py:71:1: PTH123 `open()` should be replaced by `Path.open()`
|
69 | def bytes_str_func() -> bytes:
70 | return b"foo"
71 | open(bytes_str_func())
| ^^^^ PTH123
72 |
73 | # https://github.com/astral-sh/ruff/issues/17693
|

View file

@ -0,0 +1,478 @@
---
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
---
import_as.py:7:5: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
|
5 | q = "bar"
6 |
7 | a = foo_p.abspath(p)
| ^^^^^^^^^^^^^ PTH100
8 | aa = foo.chmod(p)
9 | aaa = foo.mkdir(p)
|
= help: Replace with `Path(...).resolve()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
6 7 |
7 |-a = foo_p.abspath(p)
8 |+a = pathlib.Path(p).resolve()
8 9 | aa = foo.chmod(p)
9 10 | aaa = foo.mkdir(p)
10 11 | foo.makedirs(p)
import_as.py:8:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
7 | a = foo_p.abspath(p)
8 | aa = foo.chmod(p)
| ^^^^^^^^^ PTH101
9 | aaa = foo.mkdir(p)
10 | foo.makedirs(p)
|
import_as.py:9:7: PTH102 `os.mkdir()` should be replaced by `Path.mkdir()`
|
7 | a = foo_p.abspath(p)
8 | aa = foo.chmod(p)
9 | aaa = foo.mkdir(p)
| ^^^^^^^^^ PTH102
10 | foo.makedirs(p)
11 | foo.rename(p)
|
import_as.py:10:1: PTH103 `os.makedirs()` should be replaced by `Path.mkdir(parents=True)`
|
8 | aa = foo.chmod(p)
9 | aaa = foo.mkdir(p)
10 | foo.makedirs(p)
| ^^^^^^^^^^^^ PTH103
11 | foo.rename(p)
12 | foo.replace(p)
|
import_as.py:11:1: PTH104 `os.rename()` should be replaced by `Path.rename()`
|
9 | aaa = foo.mkdir(p)
10 | foo.makedirs(p)
11 | foo.rename(p)
| ^^^^^^^^^^ PTH104
12 | foo.replace(p)
13 | foo.rmdir(p)
|
import_as.py:12:1: PTH105 `os.replace()` should be replaced by `Path.replace()`
|
10 | foo.makedirs(p)
11 | foo.rename(p)
12 | foo.replace(p)
| ^^^^^^^^^^^ PTH105
13 | foo.rmdir(p)
14 | foo.remove(p)
|
import_as.py:13:1: PTH106 [*] `os.rmdir()` should be replaced by `Path.rmdir()`
|
11 | foo.rename(p)
12 | foo.replace(p)
13 | foo.rmdir(p)
| ^^^^^^^^^ PTH106
14 | foo.remove(p)
15 | foo.unlink(p)
|
= help: Replace with `Path(...).rmdir()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
10 11 | foo.makedirs(p)
11 12 | foo.rename(p)
12 13 | foo.replace(p)
13 |-foo.rmdir(p)
14 |+pathlib.Path(p).rmdir()
14 15 | foo.remove(p)
15 16 | foo.unlink(p)
16 17 | foo.getcwd(p)
import_as.py:14:1: PTH107 [*] `os.remove()` should be replaced by `Path.unlink()`
|
12 | foo.replace(p)
13 | foo.rmdir(p)
14 | foo.remove(p)
| ^^^^^^^^^^ PTH107
15 | foo.unlink(p)
16 | foo.getcwd(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
11 12 | foo.rename(p)
12 13 | foo.replace(p)
13 14 | foo.rmdir(p)
14 |-foo.remove(p)
15 |+pathlib.Path(p).unlink()
15 16 | foo.unlink(p)
16 17 | foo.getcwd(p)
17 18 | b = foo_p.exists(p)
import_as.py:15:1: PTH108 [*] `os.unlink()` should be replaced by `Path.unlink()`
|
13 | foo.rmdir(p)
14 | foo.remove(p)
15 | foo.unlink(p)
| ^^^^^^^^^^ PTH108
16 | foo.getcwd(p)
17 | b = foo_p.exists(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
12 13 | foo.replace(p)
13 14 | foo.rmdir(p)
14 15 | foo.remove(p)
15 |-foo.unlink(p)
16 |+pathlib.Path(p).unlink()
16 17 | foo.getcwd(p)
17 18 | b = foo_p.exists(p)
18 19 | bb = foo_p.expanduser(p)
import_as.py:16:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
14 | foo.remove(p)
15 | foo.unlink(p)
16 | foo.getcwd(p)
| ^^^^^^^^^^ PTH109
17 | b = foo_p.exists(p)
18 | bb = foo_p.expanduser(p)
|
import_as.py:17:5: PTH110 [*] `os.path.exists()` should be replaced by `Path.exists()`
|
15 | foo.unlink(p)
16 | foo.getcwd(p)
17 | b = foo_p.exists(p)
| ^^^^^^^^^^^^ PTH110
18 | bb = foo_p.expanduser(p)
19 | bbb = foo_p.isdir(p)
|
= help: Replace with `Path(...).exists()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
14 15 | foo.remove(p)
15 16 | foo.unlink(p)
16 17 | foo.getcwd(p)
17 |-b = foo_p.exists(p)
18 |+b = pathlib.Path(p).exists()
18 19 | bb = foo_p.expanduser(p)
19 20 | bbb = foo_p.isdir(p)
20 21 | bbbb = foo_p.isfile(p)
import_as.py:18:6: PTH111 [*] `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
16 | foo.getcwd(p)
17 | b = foo_p.exists(p)
18 | bb = foo_p.expanduser(p)
| ^^^^^^^^^^^^^^^^ PTH111
19 | bbb = foo_p.isdir(p)
20 | bbbb = foo_p.isfile(p)
|
= help: Replace with `Path(...).expanduser()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
15 16 | foo.unlink(p)
16 17 | foo.getcwd(p)
17 18 | b = foo_p.exists(p)
18 |-bb = foo_p.expanduser(p)
19 |+bb = pathlib.Path(p).expanduser()
19 20 | bbb = foo_p.isdir(p)
20 21 | bbbb = foo_p.isfile(p)
21 22 | bbbbb = foo_p.islink(p)
import_as.py:19:7: PTH112 [*] `os.path.isdir()` should be replaced by `Path.is_dir()`
|
17 | b = foo_p.exists(p)
18 | bb = foo_p.expanduser(p)
19 | bbb = foo_p.isdir(p)
| ^^^^^^^^^^^ PTH112
20 | bbbb = foo_p.isfile(p)
21 | bbbbb = foo_p.islink(p)
|
= help: Replace with `Path(...).is_dir()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
16 17 | foo.getcwd(p)
17 18 | b = foo_p.exists(p)
18 19 | bb = foo_p.expanduser(p)
19 |-bbb = foo_p.isdir(p)
20 |+bbb = pathlib.Path(p).is_dir()
20 21 | bbbb = foo_p.isfile(p)
21 22 | bbbbb = foo_p.islink(p)
22 23 | foo.readlink(p)
import_as.py:20:8: PTH113 [*] `os.path.isfile()` should be replaced by `Path.is_file()`
|
18 | bb = foo_p.expanduser(p)
19 | bbb = foo_p.isdir(p)
20 | bbbb = foo_p.isfile(p)
| ^^^^^^^^^^^^ PTH113
21 | bbbbb = foo_p.islink(p)
22 | foo.readlink(p)
|
= help: Replace with `Path(...).is_file()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
17 18 | b = foo_p.exists(p)
18 19 | bb = foo_p.expanduser(p)
19 20 | bbb = foo_p.isdir(p)
20 |-bbbb = foo_p.isfile(p)
21 |+bbbb = pathlib.Path(p).is_file()
21 22 | bbbbb = foo_p.islink(p)
22 23 | foo.readlink(p)
23 24 | foo.stat(p)
import_as.py:21:9: PTH114 [*] `os.path.islink()` should be replaced by `Path.is_symlink()`
|
19 | bbb = foo_p.isdir(p)
20 | bbbb = foo_p.isfile(p)
21 | bbbbb = foo_p.islink(p)
| ^^^^^^^^^^^^ PTH114
22 | foo.readlink(p)
23 | foo.stat(p)
|
= help: Replace with `Path(...).is_symlink()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
18 19 | bb = foo_p.expanduser(p)
19 20 | bbb = foo_p.isdir(p)
20 21 | bbbb = foo_p.isfile(p)
21 |-bbbbb = foo_p.islink(p)
22 |+bbbbb = pathlib.Path(p).is_symlink()
22 23 | foo.readlink(p)
23 24 | foo.stat(p)
24 25 | foo_p.isabs(p)
import_as.py:22:1: PTH115 [*] `os.readlink()` should be replaced by `Path.readlink()`
|
20 | bbbb = foo_p.isfile(p)
21 | bbbbb = foo_p.islink(p)
22 | foo.readlink(p)
| ^^^^^^^^^^^^ PTH115
23 | foo.stat(p)
24 | foo_p.isabs(p)
|
= help: Replace with `Path(...).readlink()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
19 20 | bbb = foo_p.isdir(p)
20 21 | bbbb = foo_p.isfile(p)
21 22 | bbbbb = foo_p.islink(p)
22 |-foo.readlink(p)
23 |+pathlib.Path(p).readlink()
23 24 | foo.stat(p)
24 25 | foo_p.isabs(p)
25 26 | foo_p.join(p, q)
import_as.py:23:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
21 | bbbbb = foo_p.islink(p)
22 | foo.readlink(p)
23 | foo.stat(p)
| ^^^^^^^^ PTH116
24 | foo_p.isabs(p)
25 | foo_p.join(p, q)
|
import_as.py:24:1: PTH117 [*] `os.path.isabs()` should be replaced by `Path.is_absolute()`
|
22 | foo.readlink(p)
23 | foo.stat(p)
24 | foo_p.isabs(p)
| ^^^^^^^^^^^ PTH117
25 | foo_p.join(p, q)
26 | foo.sep.join([p, q])
|
= help: Replace with `Path(...).is_absolute()`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
21 22 | bbbbb = foo_p.islink(p)
22 23 | foo.readlink(p)
23 24 | foo.stat(p)
24 |-foo_p.isabs(p)
25 |+pathlib.Path(p).is_absolute()
25 26 | foo_p.join(p, q)
26 27 | foo.sep.join([p, q])
27 28 | foo.sep.join((p, q))
import_as.py:25:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
23 | foo.stat(p)
24 | foo_p.isabs(p)
25 | foo_p.join(p, q)
| ^^^^^^^^^^ PTH118
26 | foo.sep.join([p, q])
27 | foo.sep.join((p, q))
|
import_as.py:26:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
24 | foo_p.isabs(p)
25 | foo_p.join(p, q)
26 | foo.sep.join([p, q])
| ^^^^^^^^^^^^ PTH118
27 | foo.sep.join((p, q))
28 | foo_p.basename(p)
|
import_as.py:27:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
25 | foo_p.join(p, q)
26 | foo.sep.join([p, q])
27 | foo.sep.join((p, q))
| ^^^^^^^^^^^^ PTH118
28 | foo_p.basename(p)
29 | foo_p.dirname(p)
|
import_as.py:28:1: PTH119 [*] `os.path.basename()` should be replaced by `Path.name`
|
26 | foo.sep.join([p, q])
27 | foo.sep.join((p, q))
28 | foo_p.basename(p)
| ^^^^^^^^^^^^^^ PTH119
29 | foo_p.dirname(p)
30 | foo_p.samefile(p)
|
= help: Replace with `Path(...).name`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
25 26 | foo_p.join(p, q)
26 27 | foo.sep.join([p, q])
27 28 | foo.sep.join((p, q))
28 |-foo_p.basename(p)
29 |+pathlib.Path(p).name
29 30 | foo_p.dirname(p)
30 31 | foo_p.samefile(p)
31 32 | foo_p.splitext(p)
import_as.py:29:1: PTH120 [*] `os.path.dirname()` should be replaced by `Path.parent`
|
27 | foo.sep.join((p, q))
28 | foo_p.basename(p)
29 | foo_p.dirname(p)
| ^^^^^^^^^^^^^ PTH120
30 | foo_p.samefile(p)
31 | foo_p.splitext(p)
|
= help: Replace with `Path(...).parent`
Safe fix
1 1 | import os as foo
2 2 | import os.path as foo_p
3 |+import pathlib
3 4 |
4 5 | p = "/foo"
5 6 | q = "bar"
--------------------------------------------------------------------------------
26 27 | foo.sep.join([p, q])
27 28 | foo.sep.join((p, q))
28 29 | foo_p.basename(p)
29 |-foo_p.dirname(p)
30 |+pathlib.Path(p).parent
30 31 | foo_p.samefile(p)
31 32 | foo_p.splitext(p)
import_as.py:30:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|
28 | foo_p.basename(p)
29 | foo_p.dirname(p)
30 | foo_p.samefile(p)
| ^^^^^^^^^^^^^^ PTH121
31 | foo_p.splitext(p)
|
import_as.py:31:1: PTH122 `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, and `Path.parent`
|
29 | foo_p.dirname(p)
30 | foo_p.samefile(p)
31 | foo_p.splitext(p)
| ^^^^^^^^^^^^^^ PTH122
|

View file

@ -0,0 +1,521 @@
---
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
---
import_from.py:9:5: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
|
7 | q = "bar"
8 |
9 | a = abspath(p)
| ^^^^^^^ PTH100
10 | aa = chmod(p)
11 | aaa = mkdir(p)
|
= help: Replace with `Path(...).resolve()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
8 9 |
9 |-a = abspath(p)
10 |+a = pathlib.Path(p).resolve()
10 11 | aa = chmod(p)
11 12 | aaa = mkdir(p)
12 13 | makedirs(p)
import_from.py:10:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
9 | a = abspath(p)
10 | aa = chmod(p)
| ^^^^^ PTH101
11 | aaa = mkdir(p)
12 | makedirs(p)
|
import_from.py:11:7: PTH102 `os.mkdir()` should be replaced by `Path.mkdir()`
|
9 | a = abspath(p)
10 | aa = chmod(p)
11 | aaa = mkdir(p)
| ^^^^^ PTH102
12 | makedirs(p)
13 | rename(p)
|
import_from.py:12:1: PTH103 `os.makedirs()` should be replaced by `Path.mkdir(parents=True)`
|
10 | aa = chmod(p)
11 | aaa = mkdir(p)
12 | makedirs(p)
| ^^^^^^^^ PTH103
13 | rename(p)
14 | replace(p)
|
import_from.py:13:1: PTH104 `os.rename()` should be replaced by `Path.rename()`
|
11 | aaa = mkdir(p)
12 | makedirs(p)
13 | rename(p)
| ^^^^^^ PTH104
14 | replace(p)
15 | rmdir(p)
|
import_from.py:14:1: PTH105 `os.replace()` should be replaced by `Path.replace()`
|
12 | makedirs(p)
13 | rename(p)
14 | replace(p)
| ^^^^^^^ PTH105
15 | rmdir(p)
16 | remove(p)
|
import_from.py:15:1: PTH106 [*] `os.rmdir()` should be replaced by `Path.rmdir()`
|
13 | rename(p)
14 | replace(p)
15 | rmdir(p)
| ^^^^^ PTH106
16 | remove(p)
17 | unlink(p)
|
= help: Replace with `Path(...).rmdir()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
12 13 | makedirs(p)
13 14 | rename(p)
14 15 | replace(p)
15 |-rmdir(p)
16 |+pathlib.Path(p).rmdir()
16 17 | remove(p)
17 18 | unlink(p)
18 19 | getcwd(p)
import_from.py:16:1: PTH107 [*] `os.remove()` should be replaced by `Path.unlink()`
|
14 | replace(p)
15 | rmdir(p)
16 | remove(p)
| ^^^^^^ PTH107
17 | unlink(p)
18 | getcwd(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
13 14 | rename(p)
14 15 | replace(p)
15 16 | rmdir(p)
16 |-remove(p)
17 |+pathlib.Path(p).unlink()
17 18 | unlink(p)
18 19 | getcwd(p)
19 20 | b = exists(p)
import_from.py:17:1: PTH108 [*] `os.unlink()` should be replaced by `Path.unlink()`
|
15 | rmdir(p)
16 | remove(p)
17 | unlink(p)
| ^^^^^^ PTH108
18 | getcwd(p)
19 | b = exists(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
14 15 | replace(p)
15 16 | rmdir(p)
16 17 | remove(p)
17 |-unlink(p)
18 |+pathlib.Path(p).unlink()
18 19 | getcwd(p)
19 20 | b = exists(p)
20 21 | bb = expanduser(p)
import_from.py:18:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
16 | remove(p)
17 | unlink(p)
18 | getcwd(p)
| ^^^^^^ PTH109
19 | b = exists(p)
20 | bb = expanduser(p)
|
import_from.py:19:5: PTH110 [*] `os.path.exists()` should be replaced by `Path.exists()`
|
17 | unlink(p)
18 | getcwd(p)
19 | b = exists(p)
| ^^^^^^ PTH110
20 | bb = expanduser(p)
21 | bbb = isdir(p)
|
= help: Replace with `Path(...).exists()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
16 17 | remove(p)
17 18 | unlink(p)
18 19 | getcwd(p)
19 |-b = exists(p)
20 |+b = pathlib.Path(p).exists()
20 21 | bb = expanduser(p)
21 22 | bbb = isdir(p)
22 23 | bbbb = isfile(p)
import_from.py:20:6: PTH111 [*] `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
18 | getcwd(p)
19 | b = exists(p)
20 | bb = expanduser(p)
| ^^^^^^^^^^ PTH111
21 | bbb = isdir(p)
22 | bbbb = isfile(p)
|
= help: Replace with `Path(...).expanduser()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
17 18 | unlink(p)
18 19 | getcwd(p)
19 20 | b = exists(p)
20 |-bb = expanduser(p)
21 |+bb = pathlib.Path(p).expanduser()
21 22 | bbb = isdir(p)
22 23 | bbbb = isfile(p)
23 24 | bbbbb = islink(p)
import_from.py:21:7: PTH112 [*] `os.path.isdir()` should be replaced by `Path.is_dir()`
|
19 | b = exists(p)
20 | bb = expanduser(p)
21 | bbb = isdir(p)
| ^^^^^ PTH112
22 | bbbb = isfile(p)
23 | bbbbb = islink(p)
|
= help: Replace with `Path(...).is_dir()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
18 19 | getcwd(p)
19 20 | b = exists(p)
20 21 | bb = expanduser(p)
21 |-bbb = isdir(p)
22 |+bbb = pathlib.Path(p).is_dir()
22 23 | bbbb = isfile(p)
23 24 | bbbbb = islink(p)
24 25 | readlink(p)
import_from.py:22:8: PTH113 [*] `os.path.isfile()` should be replaced by `Path.is_file()`
|
20 | bb = expanduser(p)
21 | bbb = isdir(p)
22 | bbbb = isfile(p)
| ^^^^^^ PTH113
23 | bbbbb = islink(p)
24 | readlink(p)
|
= help: Replace with `Path(...).is_file()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
19 20 | b = exists(p)
20 21 | bb = expanduser(p)
21 22 | bbb = isdir(p)
22 |-bbbb = isfile(p)
23 |+bbbb = pathlib.Path(p).is_file()
23 24 | bbbbb = islink(p)
24 25 | readlink(p)
25 26 | stat(p)
import_from.py:23:9: PTH114 [*] `os.path.islink()` should be replaced by `Path.is_symlink()`
|
21 | bbb = isdir(p)
22 | bbbb = isfile(p)
23 | bbbbb = islink(p)
| ^^^^^^ PTH114
24 | readlink(p)
25 | stat(p)
|
= help: Replace with `Path(...).is_symlink()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
20 21 | bb = expanduser(p)
21 22 | bbb = isdir(p)
22 23 | bbbb = isfile(p)
23 |-bbbbb = islink(p)
24 |+bbbbb = pathlib.Path(p).is_symlink()
24 25 | readlink(p)
25 26 | stat(p)
26 27 | isabs(p)
import_from.py:24:1: PTH115 [*] `os.readlink()` should be replaced by `Path.readlink()`
|
22 | bbbb = isfile(p)
23 | bbbbb = islink(p)
24 | readlink(p)
| ^^^^^^^^ PTH115
25 | stat(p)
26 | isabs(p)
|
= help: Replace with `Path(...).readlink()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
21 22 | bbb = isdir(p)
22 23 | bbbb = isfile(p)
23 24 | bbbbb = islink(p)
24 |-readlink(p)
25 |+pathlib.Path(p).readlink()
25 26 | stat(p)
26 27 | isabs(p)
27 28 | join(p, q)
import_from.py:25:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
23 | bbbbb = islink(p)
24 | readlink(p)
25 | stat(p)
| ^^^^ PTH116
26 | isabs(p)
27 | join(p, q)
|
import_from.py:26:1: PTH117 [*] `os.path.isabs()` should be replaced by `Path.is_absolute()`
|
24 | readlink(p)
25 | stat(p)
26 | isabs(p)
| ^^^^^ PTH117
27 | join(p, q)
28 | sep.join((p, q))
|
= help: Replace with `Path(...).is_absolute()`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
23 24 | bbbbb = islink(p)
24 25 | readlink(p)
25 26 | stat(p)
26 |-isabs(p)
27 |+pathlib.Path(p).is_absolute()
27 28 | join(p, q)
28 29 | sep.join((p, q))
29 30 | sep.join([p, q])
import_from.py:27:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
25 | stat(p)
26 | isabs(p)
27 | join(p, q)
| ^^^^ PTH118
28 | sep.join((p, q))
29 | sep.join([p, q])
|
import_from.py:28:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
26 | isabs(p)
27 | join(p, q)
28 | sep.join((p, q))
| ^^^^^^^^ PTH118
29 | sep.join([p, q])
30 | basename(p)
|
import_from.py:29:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
27 | join(p, q)
28 | sep.join((p, q))
29 | sep.join([p, q])
| ^^^^^^^^ PTH118
30 | basename(p)
31 | dirname(p)
|
import_from.py:30:1: PTH119 [*] `os.path.basename()` should be replaced by `Path.name`
|
28 | sep.join((p, q))
29 | sep.join([p, q])
30 | basename(p)
| ^^^^^^^^ PTH119
31 | dirname(p)
32 | samefile(p)
|
= help: Replace with `Path(...).name`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
27 28 | join(p, q)
28 29 | sep.join((p, q))
29 30 | sep.join([p, q])
30 |-basename(p)
31 |+pathlib.Path(p).name
31 32 | dirname(p)
32 33 | samefile(p)
33 34 | splitext(p)
import_from.py:31:1: PTH120 [*] `os.path.dirname()` should be replaced by `Path.parent`
|
29 | sep.join([p, q])
30 | basename(p)
31 | dirname(p)
| ^^^^^^^ PTH120
32 | samefile(p)
33 | splitext(p)
|
= help: Replace with `Path(...).parent`
Safe fix
2 2 | from os import remove, unlink, getcwd, readlink, stat
3 3 | from os.path import abspath, exists, expanduser, isdir, isfile, islink
4 4 | from os.path import isabs, join, basename, dirname, samefile, splitext
5 |+import pathlib
5 6 |
6 7 | p = "/foo"
7 8 | q = "bar"
--------------------------------------------------------------------------------
28 29 | sep.join((p, q))
29 30 | sep.join([p, q])
30 31 | basename(p)
31 |-dirname(p)
32 |+pathlib.Path(p).parent
32 33 | samefile(p)
33 34 | splitext(p)
34 35 | with open(p) as fp:
import_from.py:32:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|
30 | basename(p)
31 | dirname(p)
32 | samefile(p)
| ^^^^^^^^ PTH121
33 | splitext(p)
34 | with open(p) as fp:
|
import_from.py:33:1: PTH122 `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, and `Path.parent`
|
31 | dirname(p)
32 | samefile(p)
33 | splitext(p)
| ^^^^^^^^ PTH122
34 | with open(p) as fp:
35 | fp.read()
|
import_from.py:34:6: PTH123 `open()` should be replaced by `Path.open()`
|
32 | samefile(p)
33 | splitext(p)
34 | with open(p) as fp:
| ^^^^ PTH123
35 | fp.read()
36 | open(p).close()
|
import_from.py:36:1: PTH123 `open()` should be replaced by `Path.open()`
|
34 | with open(p) as fp:
35 | fp.read()
36 | open(p).close()
| ^^^^ PTH123
|
import_from.py:43:10: PTH123 `open()` should be replaced by `Path.open()`
|
41 | from builtins import open
42 |
43 | with open(p) as _: ... # Error
| ^^^^ PTH123
|

View file

@ -0,0 +1,491 @@
---
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
---
import_from_as.py:14:5: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
|
12 | q = "bar"
13 |
14 | a = xabspath(p)
| ^^^^^^^^ PTH100
15 | aa = xchmod(p)
16 | aaa = xmkdir(p)
|
= help: Replace with `Path(...).resolve()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
13 14 |
14 |-a = xabspath(p)
15 |+a = pathlib.Path(p).resolve()
15 16 | aa = xchmod(p)
16 17 | aaa = xmkdir(p)
17 18 | xmakedirs(p)
import_from_as.py:15:6: PTH101 `os.chmod()` should be replaced by `Path.chmod()`
|
14 | a = xabspath(p)
15 | aa = xchmod(p)
| ^^^^^^ PTH101
16 | aaa = xmkdir(p)
17 | xmakedirs(p)
|
import_from_as.py:16:7: PTH102 `os.mkdir()` should be replaced by `Path.mkdir()`
|
14 | a = xabspath(p)
15 | aa = xchmod(p)
16 | aaa = xmkdir(p)
| ^^^^^^ PTH102
17 | xmakedirs(p)
18 | xrename(p)
|
import_from_as.py:17:1: PTH103 `os.makedirs()` should be replaced by `Path.mkdir(parents=True)`
|
15 | aa = xchmod(p)
16 | aaa = xmkdir(p)
17 | xmakedirs(p)
| ^^^^^^^^^ PTH103
18 | xrename(p)
19 | xreplace(p)
|
import_from_as.py:18:1: PTH104 `os.rename()` should be replaced by `Path.rename()`
|
16 | aaa = xmkdir(p)
17 | xmakedirs(p)
18 | xrename(p)
| ^^^^^^^ PTH104
19 | xreplace(p)
20 | xrmdir(p)
|
import_from_as.py:19:1: PTH105 `os.replace()` should be replaced by `Path.replace()`
|
17 | xmakedirs(p)
18 | xrename(p)
19 | xreplace(p)
| ^^^^^^^^ PTH105
20 | xrmdir(p)
21 | xremove(p)
|
import_from_as.py:20:1: PTH106 [*] `os.rmdir()` should be replaced by `Path.rmdir()`
|
18 | xrename(p)
19 | xreplace(p)
20 | xrmdir(p)
| ^^^^^^ PTH106
21 | xremove(p)
22 | xunlink(p)
|
= help: Replace with `Path(...).rmdir()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
17 18 | xmakedirs(p)
18 19 | xrename(p)
19 20 | xreplace(p)
20 |-xrmdir(p)
21 |+pathlib.Path(p).rmdir()
21 22 | xremove(p)
22 23 | xunlink(p)
23 24 | xgetcwd(p)
import_from_as.py:21:1: PTH107 [*] `os.remove()` should be replaced by `Path.unlink()`
|
19 | xreplace(p)
20 | xrmdir(p)
21 | xremove(p)
| ^^^^^^^ PTH107
22 | xunlink(p)
23 | xgetcwd(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
18 19 | xrename(p)
19 20 | xreplace(p)
20 21 | xrmdir(p)
21 |-xremove(p)
22 |+pathlib.Path(p).unlink()
22 23 | xunlink(p)
23 24 | xgetcwd(p)
24 25 | b = xexists(p)
import_from_as.py:22:1: PTH108 [*] `os.unlink()` should be replaced by `Path.unlink()`
|
20 | xrmdir(p)
21 | xremove(p)
22 | xunlink(p)
| ^^^^^^^ PTH108
23 | xgetcwd(p)
24 | b = xexists(p)
|
= help: Replace with `Path(...).unlink()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
19 20 | xreplace(p)
20 21 | xrmdir(p)
21 22 | xremove(p)
22 |-xunlink(p)
23 |+pathlib.Path(p).unlink()
23 24 | xgetcwd(p)
24 25 | b = xexists(p)
25 26 | bb = xexpanduser(p)
import_from_as.py:23:1: PTH109 `os.getcwd()` should be replaced by `Path.cwd()`
|
21 | xremove(p)
22 | xunlink(p)
23 | xgetcwd(p)
| ^^^^^^^ PTH109
24 | b = xexists(p)
25 | bb = xexpanduser(p)
|
import_from_as.py:24:5: PTH110 [*] `os.path.exists()` should be replaced by `Path.exists()`
|
22 | xunlink(p)
23 | xgetcwd(p)
24 | b = xexists(p)
| ^^^^^^^ PTH110
25 | bb = xexpanduser(p)
26 | bbb = xisdir(p)
|
= help: Replace with `Path(...).exists()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
21 22 | xremove(p)
22 23 | xunlink(p)
23 24 | xgetcwd(p)
24 |-b = xexists(p)
25 |+b = pathlib.Path(p).exists()
25 26 | bb = xexpanduser(p)
26 27 | bbb = xisdir(p)
27 28 | bbbb = xisfile(p)
import_from_as.py:25:6: PTH111 [*] `os.path.expanduser()` should be replaced by `Path.expanduser()`
|
23 | xgetcwd(p)
24 | b = xexists(p)
25 | bb = xexpanduser(p)
| ^^^^^^^^^^^ PTH111
26 | bbb = xisdir(p)
27 | bbbb = xisfile(p)
|
= help: Replace with `Path(...).expanduser()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
22 23 | xunlink(p)
23 24 | xgetcwd(p)
24 25 | b = xexists(p)
25 |-bb = xexpanduser(p)
26 |+bb = pathlib.Path(p).expanduser()
26 27 | bbb = xisdir(p)
27 28 | bbbb = xisfile(p)
28 29 | bbbbb = xislink(p)
import_from_as.py:26:7: PTH112 [*] `os.path.isdir()` should be replaced by `Path.is_dir()`
|
24 | b = xexists(p)
25 | bb = xexpanduser(p)
26 | bbb = xisdir(p)
| ^^^^^^ PTH112
27 | bbbb = xisfile(p)
28 | bbbbb = xislink(p)
|
= help: Replace with `Path(...).is_dir()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
23 24 | xgetcwd(p)
24 25 | b = xexists(p)
25 26 | bb = xexpanduser(p)
26 |-bbb = xisdir(p)
27 |+bbb = pathlib.Path(p).is_dir()
27 28 | bbbb = xisfile(p)
28 29 | bbbbb = xislink(p)
29 30 | xreadlink(p)
import_from_as.py:27:8: PTH113 [*] `os.path.isfile()` should be replaced by `Path.is_file()`
|
25 | bb = xexpanduser(p)
26 | bbb = xisdir(p)
27 | bbbb = xisfile(p)
| ^^^^^^^ PTH113
28 | bbbbb = xislink(p)
29 | xreadlink(p)
|
= help: Replace with `Path(...).is_file()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
24 25 | b = xexists(p)
25 26 | bb = xexpanduser(p)
26 27 | bbb = xisdir(p)
27 |-bbbb = xisfile(p)
28 |+bbbb = pathlib.Path(p).is_file()
28 29 | bbbbb = xislink(p)
29 30 | xreadlink(p)
30 31 | xstat(p)
import_from_as.py:28:9: PTH114 [*] `os.path.islink()` should be replaced by `Path.is_symlink()`
|
26 | bbb = xisdir(p)
27 | bbbb = xisfile(p)
28 | bbbbb = xislink(p)
| ^^^^^^^ PTH114
29 | xreadlink(p)
30 | xstat(p)
|
= help: Replace with `Path(...).is_symlink()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
25 26 | bb = xexpanduser(p)
26 27 | bbb = xisdir(p)
27 28 | bbbb = xisfile(p)
28 |-bbbbb = xislink(p)
29 |+bbbbb = pathlib.Path(p).is_symlink()
29 30 | xreadlink(p)
30 31 | xstat(p)
31 32 | xisabs(p)
import_from_as.py:29:1: PTH115 [*] `os.readlink()` should be replaced by `Path.readlink()`
|
27 | bbbb = xisfile(p)
28 | bbbbb = xislink(p)
29 | xreadlink(p)
| ^^^^^^^^^ PTH115
30 | xstat(p)
31 | xisabs(p)
|
= help: Replace with `Path(...).readlink()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
26 27 | bbb = xisdir(p)
27 28 | bbbb = xisfile(p)
28 29 | bbbbb = xislink(p)
29 |-xreadlink(p)
30 |+pathlib.Path(p).readlink()
30 31 | xstat(p)
31 32 | xisabs(p)
32 33 | xjoin(p, q)
import_from_as.py:30:1: PTH116 `os.stat()` should be replaced by `Path.stat()`, `Path.owner()`, or `Path.group()`
|
28 | bbbbb = xislink(p)
29 | xreadlink(p)
30 | xstat(p)
| ^^^^^ PTH116
31 | xisabs(p)
32 | xjoin(p, q)
|
import_from_as.py:31:1: PTH117 [*] `os.path.isabs()` should be replaced by `Path.is_absolute()`
|
29 | xreadlink(p)
30 | xstat(p)
31 | xisabs(p)
| ^^^^^^ PTH117
32 | xjoin(p, q)
33 | s.join((p, q))
|
= help: Replace with `Path(...).is_absolute()`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
28 29 | bbbbb = xislink(p)
29 30 | xreadlink(p)
30 31 | xstat(p)
31 |-xisabs(p)
32 |+pathlib.Path(p).is_absolute()
32 33 | xjoin(p, q)
33 34 | s.join((p, q))
34 35 | s.join([p, q])
import_from_as.py:32:1: PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
|
30 | xstat(p)
31 | xisabs(p)
32 | xjoin(p, q)
| ^^^^^ PTH118
33 | s.join((p, q))
34 | s.join([p, q])
|
import_from_as.py:33:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
31 | xisabs(p)
32 | xjoin(p, q)
33 | s.join((p, q))
| ^^^^^^ PTH118
34 | s.join([p, q])
35 | xbasename(p)
|
import_from_as.py:34:1: PTH118 `os.sep.join()` should be replaced by `Path` with `/` operator
|
32 | xjoin(p, q)
33 | s.join((p, q))
34 | s.join([p, q])
| ^^^^^^ PTH118
35 | xbasename(p)
36 | xdirname(p)
|
import_from_as.py:35:1: PTH119 [*] `os.path.basename()` should be replaced by `Path.name`
|
33 | s.join((p, q))
34 | s.join([p, q])
35 | xbasename(p)
| ^^^^^^^^^ PTH119
36 | xdirname(p)
37 | xsamefile(p)
|
= help: Replace with `Path(...).name`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
32 33 | xjoin(p, q)
33 34 | s.join((p, q))
34 35 | s.join([p, q])
35 |-xbasename(p)
36 |+pathlib.Path(p).name
36 37 | xdirname(p)
37 38 | xsamefile(p)
38 39 | xsplitext(p)
import_from_as.py:36:1: PTH120 [*] `os.path.dirname()` should be replaced by `Path.parent`
|
34 | s.join([p, q])
35 | xbasename(p)
36 | xdirname(p)
| ^^^^^^^^ PTH120
37 | xsamefile(p)
38 | xsplitext(p)
|
= help: Replace with `Path(...).parent`
Safe fix
7 7 | from os.path import isfile as xisfile, islink as xislink, isabs as xisabs
8 8 | from os.path import join as xjoin, basename as xbasename, dirname as xdirname
9 9 | from os.path import samefile as xsamefile, splitext as xsplitext
10 |+import pathlib
10 11 |
11 12 | p = "/foo"
12 13 | q = "bar"
--------------------------------------------------------------------------------
33 34 | s.join((p, q))
34 35 | s.join([p, q])
35 36 | xbasename(p)
36 |-xdirname(p)
37 |+pathlib.Path(p).parent
37 38 | xsamefile(p)
38 39 | xsplitext(p)
import_from_as.py:37:1: PTH121 `os.path.samefile()` should be replaced by `Path.samefile()`
|
35 | xbasename(p)
36 | xdirname(p)
37 | xsamefile(p)
| ^^^^^^^^^ PTH121
38 | xsplitext(p)
|
import_from_as.py:38:1: PTH122 `os.path.splitext()` should be replaced by `Path.suffix`, `Path.stem`, and `Path.parent`
|
36 | xdirname(p)
37 | xsamefile(p)
38 | xsplitext(p)
| ^^^^^^^^^ PTH122
|

View file

@ -2,51 +2,6 @@ use ruff_macros::{ViolationMetadata, derive_message_formats};
use crate::Violation;
/// ## What it does
/// Checks for uses of `os.path.abspath`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// file_path = os.path.abspath("../path/to/file")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// file_path = Path("../path/to/file").resolve()
/// ```
///
/// ## 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)
/// - [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 OsPathAbspath;
impl Violation for OsPathAbspath {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.abspath()` should be replaced by `Path.resolve()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.chmod`.
///
@ -275,141 +230,6 @@ impl Violation for OsReplace {
}
}
/// ## What it does
/// Checks for uses of `os.rmdir`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.rmdir()` can improve readability over the `os`
/// module's counterparts (e.g., `os.rmdir()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.rmdir("folder/")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsRmdir;
impl Violation for OsRmdir {
#[derive_message_formats]
fn message(&self) -> String {
"`os.rmdir()` should be replaced by `Path.rmdir()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.remove`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.unlink()` can improve readability over the `os`
/// module's counterparts (e.g., `os.remove()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.remove("file.py")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsRemove;
impl Violation for OsRemove {
#[derive_message_formats]
fn message(&self) -> String {
"`os.remove()` should be replaced by `Path.unlink()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.unlink`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.unlink()` can improve readability over the `os`
/// module's counterparts (e.g., `os.unlink()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.unlink("file.py")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsUnlink;
impl Violation for OsUnlink {
#[derive_message_formats]
fn message(&self) -> String {
"`os.unlink()` should be replaced by `Path.unlink()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.getcwd` and `os.getcwdb`.
///
@ -456,276 +276,6 @@ impl Violation for OsGetcwd {
}
}
/// ## What it does
/// Checks for uses of `os.path.exists`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.exists("file.py")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsPathExists;
impl Violation for OsPathExists {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.exists()` should be replaced by `Path.exists()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.path.expanduser`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.expanduser("~/films/Monty Python")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsPathExpanduser;
impl Violation for OsPathExpanduser {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.expanduser()` should be replaced by `Path.expanduser()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.path.isdir`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.isdir("docs")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsPathIsdir;
impl Violation for OsPathIsdir {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.isdir()` should be replaced by `Path.is_dir()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.path.isfile`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.isfile("docs")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsPathIsfile;
impl Violation for OsPathIsfile {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.isfile()` should be replaced by `Path.is_file()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.path.islink`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.islink("docs")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsPathIslink;
impl Violation for OsPathIslink {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.islink()` should be replaced by `Path.is_symlink()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.readlink`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os`. When possible, using `Path` object
/// methods such as `Path.readlink()` can improve readability over the `os`
/// module's counterparts (e.g., `os.readlink()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.readlink(file_name)
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsReadlink;
impl Violation for OsReadlink {
#[derive_message_formats]
fn message(&self) -> String {
"`os.readlink()` should be replaced by `Path.readlink()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.stat`.
///
@ -781,53 +331,6 @@ impl Violation for OsStat {
}
}
/// ## What it does
/// Checks for uses of `os.path.isabs`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// if os.path.isabs(file_name):
/// print("Absolute path!")
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// if Path(file_name).is_absolute():
/// print("Absolute path!")
/// ```
///
/// ## 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)
/// - [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 OsPathIsabs;
impl Violation for OsPathIsabs {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.isabs()` should be replaced by `Path.is_absolute()`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.path.join`.
///
@ -890,96 +393,6 @@ pub(crate) enum Joiner {
Joinpath,
}
/// ## What it does
/// Checks for uses of `os.path.basename`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.basename(__file__)
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsPathBasename;
impl Violation for OsPathBasename {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.basename()` should be replaced by `Path.name`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.path.dirname`.
///
/// ## Why is this bad?
/// `pathlib` offers a high-level API for path manipulation, as compared to
/// the lower-level API offered by `os.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()`).
///
/// ## Examples
/// ```python
/// import os
///
/// os.path.dirname(__file__)
/// ```
///
/// Use instead:
/// ```python
/// from pathlib import Path
///
/// 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)
/// - [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 OsPathDirname;
impl Violation for OsPathDirname {
#[derive_message_formats]
fn message(&self) -> String {
"`os.path.dirname()` should be replaced by `Path.parent`".to_string()
}
}
/// ## What it does
/// Checks for uses of `os.path.samefile`.
///