mirror of https://github.com/astral-sh/ruff
Implement pyupgrade check for io.open alias (#1399)
This commit is contained in:
parent
320a48977b
commit
e0b39fa63e
|
|
@ -80,7 +80,7 @@ Then, run `cargo test`. Your test will fail, but you'll be prompted to follow-up
|
||||||
rest of your changes.
|
rest of your changes.
|
||||||
|
|
||||||
Finally, to update the documentation, run `cargo dev generate-rules-table` from the repo root. To
|
Finally, to update the documentation, run `cargo dev generate-rules-table` from the repo root. To
|
||||||
update the generated prefix map, run `cargo dev generate-check-code-prefix`. Both of these commands
|
update the generated prefix map, run `cargo +nightly dev generate-check-code-prefix`. Both of these commands
|
||||||
should be run whenever a new check is added to the codebase.
|
should be run whenever a new check is added to the codebase.
|
||||||
|
|
||||||
### Example: Adding a new configuration option
|
### Example: Adding a new configuration option
|
||||||
|
|
|
||||||
|
|
@ -659,6 +659,7 @@ For more, see [pyupgrade](https://pypi.org/project/pyupgrade/3.2.0/) on PyPI.
|
||||||
| UP017 | DatetimeTimezoneUTC | Use `datetime.UTC` alias | 🛠 |
|
| UP017 | DatetimeTimezoneUTC | Use `datetime.UTC` alias | 🛠 |
|
||||||
| UP018 | NativeLiterals | Unnecessary call to `str` and `bytes` | 🛠 |
|
| UP018 | NativeLiterals | Unnecessary call to `str` and `bytes` | 🛠 |
|
||||||
| UP019 | TypingTextStrAlias | `typing.Text` is deprecated, use `str` | 🛠 |
|
| UP019 | TypingTextStrAlias | `typing.Text` is deprecated, use `str` | 🛠 |
|
||||||
|
| UP020 | OpenAlias | Use builtin `open` instead | 🛠 |
|
||||||
|
|
||||||
### pep8-naming (N)
|
### pep8-naming (N)
|
||||||
|
|
||||||
|
|
@ -1262,7 +1263,7 @@ natively, including:
|
||||||
- [`pep8-naming`](https://pypi.org/project/pep8-naming/)
|
- [`pep8-naming`](https://pypi.org/project/pep8-naming/)
|
||||||
- [`pydocstyle`](https://pypi.org/project/pydocstyle/)
|
- [`pydocstyle`](https://pypi.org/project/pydocstyle/)
|
||||||
- [`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (3/10)
|
- [`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (3/10)
|
||||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (19/33)
|
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (20/33)
|
||||||
- [`yesqa`](https://github.com/asottile/yesqa)
|
- [`yesqa`](https://github.com/asottile/yesqa)
|
||||||
|
|
||||||
Note that, in some cases, Ruff uses different error code prefixes than would be found in the
|
Note that, in some cases, Ruff uses different error code prefixes than would be found in the
|
||||||
|
|
@ -1319,7 +1320,7 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl
|
||||||
Ruff can also replace [`isort`](https://pypi.org/project/isort/),
|
Ruff can also replace [`isort`](https://pypi.org/project/isort/),
|
||||||
[`yesqa`](https://github.com/asottile/yesqa), [`eradicate`](https://pypi.org/project/eradicate/),
|
[`yesqa`](https://github.com/asottile/yesqa), [`eradicate`](https://pypi.org/project/eradicate/),
|
||||||
[`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (3/10), and a subset of the rules
|
[`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (3/10), and a subset of the rules
|
||||||
implemented in [`pyupgrade`](https://pypi.org/project/pyupgrade/) (19/33).
|
implemented in [`pyupgrade`](https://pypi.org/project/pyupgrade/) (20/33).
|
||||||
|
|
||||||
If you're looking to use Ruff, but rely on an unsupported Flake8 plugin, free to file an Issue.
|
If you're looking to use Ruff, but rely on an unsupported Flake8 plugin, free to file an Issue.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
from io import open
|
||||||
|
|
||||||
|
with open("f.txt") as f:
|
||||||
|
print(f.read())
|
||||||
|
|
||||||
|
import io
|
||||||
|
|
||||||
|
with io.open("f.txt", mode="r", buffering=-1, **kwargs) as f:
|
||||||
|
print(f.read())
|
||||||
|
|
@ -865,6 +865,8 @@
|
||||||
"UP017",
|
"UP017",
|
||||||
"UP018",
|
"UP018",
|
||||||
"UP019",
|
"UP019",
|
||||||
|
"UP02",
|
||||||
|
"UP020",
|
||||||
"W",
|
"W",
|
||||||
"W2",
|
"W2",
|
||||||
"W29",
|
"W29",
|
||||||
|
|
|
||||||
|
|
@ -1926,6 +1926,10 @@ where
|
||||||
pyupgrade::plugins::redundant_open_modes(self, expr);
|
pyupgrade::plugins::redundant_open_modes(self, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.settings.enabled.contains(&CheckCode::UP020) {
|
||||||
|
pyupgrade::plugins::open_alias(self, expr, func);
|
||||||
|
}
|
||||||
|
|
||||||
// flake8-boolean-trap
|
// flake8-boolean-trap
|
||||||
if self.settings.enabled.contains(&CheckCode::FBT003) {
|
if self.settings.enabled.contains(&CheckCode::FBT003) {
|
||||||
flake8_boolean_trap::plugins::check_boolean_positional_value_in_function_call(
|
flake8_boolean_trap::plugins::check_boolean_positional_value_in_function_call(
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,7 @@ pub enum CheckCode {
|
||||||
UP017,
|
UP017,
|
||||||
UP018,
|
UP018,
|
||||||
UP019,
|
UP019,
|
||||||
|
UP020,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
D100,
|
D100,
|
||||||
D101,
|
D101,
|
||||||
|
|
@ -839,6 +840,7 @@ pub enum CheckKind {
|
||||||
RemoveSixCompat,
|
RemoveSixCompat,
|
||||||
DatetimeTimezoneUTC,
|
DatetimeTimezoneUTC,
|
||||||
NativeLiterals,
|
NativeLiterals,
|
||||||
|
OpenAlias,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
BlankLineAfterLastSection(String),
|
BlankLineAfterLastSection(String),
|
||||||
BlankLineAfterSection(String),
|
BlankLineAfterSection(String),
|
||||||
|
|
@ -1215,6 +1217,7 @@ impl CheckCode {
|
||||||
CheckCode::UP017 => CheckKind::DatetimeTimezoneUTC,
|
CheckCode::UP017 => CheckKind::DatetimeTimezoneUTC,
|
||||||
CheckCode::UP018 => CheckKind::NativeLiterals,
|
CheckCode::UP018 => CheckKind::NativeLiterals,
|
||||||
CheckCode::UP019 => CheckKind::TypingTextStrAlias,
|
CheckCode::UP019 => CheckKind::TypingTextStrAlias,
|
||||||
|
CheckCode::UP020 => CheckKind::OpenAlias,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
CheckCode::D100 => CheckKind::PublicModule,
|
CheckCode::D100 => CheckKind::PublicModule,
|
||||||
CheckCode::D101 => CheckKind::PublicClass,
|
CheckCode::D101 => CheckKind::PublicClass,
|
||||||
|
|
@ -1635,6 +1638,7 @@ impl CheckCode {
|
||||||
CheckCode::UP017 => CheckCategory::Pyupgrade,
|
CheckCode::UP017 => CheckCategory::Pyupgrade,
|
||||||
CheckCode::UP018 => CheckCategory::Pyupgrade,
|
CheckCode::UP018 => CheckCategory::Pyupgrade,
|
||||||
CheckCode::UP019 => CheckCategory::Pyupgrade,
|
CheckCode::UP019 => CheckCategory::Pyupgrade,
|
||||||
|
CheckCode::UP020 => CheckCategory::Pyupgrade,
|
||||||
CheckCode::W292 => CheckCategory::Pycodestyle,
|
CheckCode::W292 => CheckCategory::Pycodestyle,
|
||||||
CheckCode::W605 => CheckCategory::Pycodestyle,
|
CheckCode::W605 => CheckCategory::Pycodestyle,
|
||||||
CheckCode::YTT101 => CheckCategory::Flake82020,
|
CheckCode::YTT101 => CheckCategory::Flake82020,
|
||||||
|
|
@ -1848,6 +1852,7 @@ impl CheckKind {
|
||||||
CheckKind::DatetimeTimezoneUTC => &CheckCode::UP017,
|
CheckKind::DatetimeTimezoneUTC => &CheckCode::UP017,
|
||||||
CheckKind::NativeLiterals => &CheckCode::UP018,
|
CheckKind::NativeLiterals => &CheckCode::UP018,
|
||||||
CheckKind::TypingTextStrAlias => &CheckCode::UP019,
|
CheckKind::TypingTextStrAlias => &CheckCode::UP019,
|
||||||
|
CheckKind::OpenAlias => &CheckCode::UP020,
|
||||||
// pydocstyle
|
// pydocstyle
|
||||||
CheckKind::BlankLineAfterLastSection(..) => &CheckCode::D413,
|
CheckKind::BlankLineAfterLastSection(..) => &CheckCode::D413,
|
||||||
CheckKind::BlankLineAfterSection(..) => &CheckCode::D410,
|
CheckKind::BlankLineAfterSection(..) => &CheckCode::D410,
|
||||||
|
|
@ -2573,6 +2578,7 @@ impl CheckKind {
|
||||||
CheckKind::RemoveSixCompat => "Unnecessary `six` compatibility usage".to_string(),
|
CheckKind::RemoveSixCompat => "Unnecessary `six` compatibility usage".to_string(),
|
||||||
CheckKind::DatetimeTimezoneUTC => "Use `datetime.UTC` alias".to_string(),
|
CheckKind::DatetimeTimezoneUTC => "Use `datetime.UTC` alias".to_string(),
|
||||||
CheckKind::NativeLiterals => "Unnecessary call to `str` and `bytes`".to_string(),
|
CheckKind::NativeLiterals => "Unnecessary call to `str` and `bytes`".to_string(),
|
||||||
|
CheckKind::OpenAlias => "Use builtin `open` instead".to_string(),
|
||||||
CheckKind::ConvertTypedDictFunctionalToClass(name) => {
|
CheckKind::ConvertTypedDictFunctionalToClass(name) => {
|
||||||
format!("Convert `{name}` from `TypedDict` functional to class syntax")
|
format!("Convert `{name}` from `TypedDict` functional to class syntax")
|
||||||
}
|
}
|
||||||
|
|
@ -3015,6 +3021,7 @@ impl CheckKind {
|
||||||
| CheckKind::MisplacedComparisonConstant(..)
|
| CheckKind::MisplacedComparisonConstant(..)
|
||||||
| CheckKind::MissingReturnTypeSpecialMethod(..)
|
| CheckKind::MissingReturnTypeSpecialMethod(..)
|
||||||
| CheckKind::NativeLiterals
|
| CheckKind::NativeLiterals
|
||||||
|
| CheckKind::OpenAlias
|
||||||
| CheckKind::NewLineAfterLastParagraph
|
| CheckKind::NewLineAfterLastParagraph
|
||||||
| CheckKind::NewLineAfterSectionName(..)
|
| CheckKind::NewLineAfterSectionName(..)
|
||||||
| CheckKind::NoBlankLineAfterFunction(..)
|
| CheckKind::NoBlankLineAfterFunction(..)
|
||||||
|
|
|
||||||
|
|
@ -527,6 +527,8 @@ pub enum CheckCodePrefix {
|
||||||
UP017,
|
UP017,
|
||||||
UP018,
|
UP018,
|
||||||
UP019,
|
UP019,
|
||||||
|
UP02,
|
||||||
|
UP020,
|
||||||
W,
|
W,
|
||||||
W2,
|
W2,
|
||||||
W29,
|
W29,
|
||||||
|
|
@ -2104,6 +2106,7 @@ impl CheckCodePrefix {
|
||||||
CheckCode::UP017,
|
CheckCode::UP017,
|
||||||
CheckCode::UP018,
|
CheckCode::UP018,
|
||||||
CheckCode::UP019,
|
CheckCode::UP019,
|
||||||
|
CheckCode::UP020,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
CheckCodePrefix::U0 => {
|
CheckCodePrefix::U0 => {
|
||||||
|
|
@ -2132,6 +2135,7 @@ impl CheckCodePrefix {
|
||||||
CheckCode::UP017,
|
CheckCode::UP017,
|
||||||
CheckCode::UP018,
|
CheckCode::UP018,
|
||||||
CheckCode::UP019,
|
CheckCode::UP019,
|
||||||
|
CheckCode::UP020,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
CheckCodePrefix::U00 => {
|
CheckCodePrefix::U00 => {
|
||||||
|
|
@ -2344,6 +2348,7 @@ impl CheckCodePrefix {
|
||||||
CheckCode::UP017,
|
CheckCode::UP017,
|
||||||
CheckCode::UP018,
|
CheckCode::UP018,
|
||||||
CheckCode::UP019,
|
CheckCode::UP019,
|
||||||
|
CheckCode::UP020,
|
||||||
],
|
],
|
||||||
CheckCodePrefix::UP0 => vec![
|
CheckCodePrefix::UP0 => vec![
|
||||||
CheckCode::UP001,
|
CheckCode::UP001,
|
||||||
|
|
@ -2364,6 +2369,7 @@ impl CheckCodePrefix {
|
||||||
CheckCode::UP017,
|
CheckCode::UP017,
|
||||||
CheckCode::UP018,
|
CheckCode::UP018,
|
||||||
CheckCode::UP019,
|
CheckCode::UP019,
|
||||||
|
CheckCode::UP020,
|
||||||
],
|
],
|
||||||
CheckCodePrefix::UP00 => vec![
|
CheckCodePrefix::UP00 => vec![
|
||||||
CheckCode::UP001,
|
CheckCode::UP001,
|
||||||
|
|
@ -2405,6 +2411,8 @@ impl CheckCodePrefix {
|
||||||
CheckCodePrefix::UP017 => vec![CheckCode::UP017],
|
CheckCodePrefix::UP017 => vec![CheckCode::UP017],
|
||||||
CheckCodePrefix::UP018 => vec![CheckCode::UP018],
|
CheckCodePrefix::UP018 => vec![CheckCode::UP018],
|
||||||
CheckCodePrefix::UP019 => vec![CheckCode::UP019],
|
CheckCodePrefix::UP019 => vec![CheckCode::UP019],
|
||||||
|
CheckCodePrefix::UP02 => vec![CheckCode::UP020],
|
||||||
|
CheckCodePrefix::UP020 => vec![CheckCode::UP020],
|
||||||
CheckCodePrefix::W => vec![CheckCode::W292, CheckCode::W605],
|
CheckCodePrefix::W => vec![CheckCode::W292, CheckCode::W605],
|
||||||
CheckCodePrefix::W2 => vec![CheckCode::W292],
|
CheckCodePrefix::W2 => vec![CheckCode::W292],
|
||||||
CheckCodePrefix::W29 => vec![CheckCode::W292],
|
CheckCodePrefix::W29 => vec![CheckCode::W292],
|
||||||
|
|
@ -2963,6 +2971,8 @@ impl CheckCodePrefix {
|
||||||
CheckCodePrefix::UP017 => SuffixLength::Three,
|
CheckCodePrefix::UP017 => SuffixLength::Three,
|
||||||
CheckCodePrefix::UP018 => SuffixLength::Three,
|
CheckCodePrefix::UP018 => SuffixLength::Three,
|
||||||
CheckCodePrefix::UP019 => SuffixLength::Three,
|
CheckCodePrefix::UP019 => SuffixLength::Three,
|
||||||
|
CheckCodePrefix::UP02 => SuffixLength::Two,
|
||||||
|
CheckCodePrefix::UP020 => SuffixLength::Three,
|
||||||
CheckCodePrefix::W => SuffixLength::Zero,
|
CheckCodePrefix::W => SuffixLength::Zero,
|
||||||
CheckCodePrefix::W2 => SuffixLength::One,
|
CheckCodePrefix::W2 => SuffixLength::One,
|
||||||
CheckCodePrefix::W29 => SuffixLength::Two,
|
CheckCodePrefix::W29 => SuffixLength::Two,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ pub use convert_typed_dict_functional_to_class::convert_typed_dict_functional_to
|
||||||
pub use datetime_utc_alias::datetime_utc_alias;
|
pub use datetime_utc_alias::datetime_utc_alias;
|
||||||
pub use deprecated_unittest_alias::deprecated_unittest_alias;
|
pub use deprecated_unittest_alias::deprecated_unittest_alias;
|
||||||
pub use native_literals::native_literals;
|
pub use native_literals::native_literals;
|
||||||
|
pub use open_alias::open_alias;
|
||||||
pub use redundant_open_modes::redundant_open_modes;
|
pub use redundant_open_modes::redundant_open_modes;
|
||||||
pub use remove_six_compat::remove_six_compat;
|
pub use remove_six_compat::remove_six_compat;
|
||||||
pub use super_call_with_parameters::super_call_with_parameters;
|
pub use super_call_with_parameters::super_call_with_parameters;
|
||||||
|
|
@ -21,6 +22,7 @@ mod convert_typed_dict_functional_to_class;
|
||||||
mod datetime_utc_alias;
|
mod datetime_utc_alias;
|
||||||
mod deprecated_unittest_alias;
|
mod deprecated_unittest_alias;
|
||||||
mod native_literals;
|
mod native_literals;
|
||||||
|
mod open_alias;
|
||||||
mod redundant_open_modes;
|
mod redundant_open_modes;
|
||||||
mod remove_six_compat;
|
mod remove_six_compat;
|
||||||
mod super_call_with_parameters;
|
mod super_call_with_parameters;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
use rustpython_ast::Expr;
|
||||||
|
|
||||||
|
use crate::ast::helpers::{collect_call_paths, dealias_call_path, match_call_path};
|
||||||
|
use crate::ast::types::Range;
|
||||||
|
use crate::autofix::Fix;
|
||||||
|
use crate::checkers::ast::Checker;
|
||||||
|
use crate::checks::{Check, CheckCode, CheckKind};
|
||||||
|
|
||||||
|
/// UP020
|
||||||
|
pub fn open_alias(checker: &mut Checker, expr: &Expr, func: &Expr) {
|
||||||
|
let call_path = dealias_call_path(collect_call_paths(expr), &checker.import_aliases);
|
||||||
|
|
||||||
|
if match_call_path(&call_path, "io", "open", &checker.from_imports) {
|
||||||
|
let mut check = Check::new(CheckKind::OpenAlias, Range::from_located(expr));
|
||||||
|
if checker.patch(&CheckCode::UP020) {
|
||||||
|
check.amend(Fix::replacement(
|
||||||
|
"open".to_string(),
|
||||||
|
func.location,
|
||||||
|
func.end_location.unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
checker.add_check(check);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue