mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-05 08:00:27 +00:00
[pyupgrade
]: Remove outdated sys.version_info
blocks (#2099)
This commit is contained in:
parent
1c2fc38853
commit
b032f50775
22 changed files with 2113 additions and 2 deletions
|
@ -77,7 +77,7 @@ wasm-bindgen = { version = "0.2.83" }
|
|||
is_executable = "1.0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
insta = { version = "1.19.1", features = ["yaml", "redactions"] }
|
||||
insta = { version = "1.19.0", features = ["yaml", "redactions"] }
|
||||
test-case = { version = "2.2.2" }
|
||||
wasm-bindgen-test = { version = "0.3.33" }
|
||||
|
||||
|
|
|
@ -850,6 +850,7 @@ For more, see [pyupgrade](https://pypi.org/project/pyupgrade/) on PyPI.
|
|||
| UP033 | functools-cache | Use `@functools.cache` instead of `@functools.lru_cache(maxsize=None)` | 🛠 |
|
||||
| UP034 | extraneous-parentheses | Avoid extraneous parentheses | 🛠 |
|
||||
| UP035 | import-replacements | Import from `{module}` instead: {names} | 🛠 |
|
||||
| UP036 | outdated-version-block | Version block is outdated for minimum Python version | 🛠 |
|
||||
|
||||
### flake8-2020 (YTT)
|
||||
|
||||
|
|
4
foo.py
Normal file
4
foo.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
import sys
|
||||
|
||||
expected_error = \
|
||||
[]
|
180
resources/test/fixtures/pyupgrade/UP036_0.py
vendored
Normal file
180
resources/test/fixtures/pyupgrade/UP036_0.py
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
import sys
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
print("py2")
|
||||
else:
|
||||
print("py3")
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
if True:
|
||||
print("py2!")
|
||||
else:
|
||||
print("???")
|
||||
else:
|
||||
print("py3")
|
||||
|
||||
if sys.version_info < (3,0): print("PY2!")
|
||||
else: print("PY3!")
|
||||
|
||||
if True:
|
||||
if sys.version_info < (3,0):
|
||||
print("PY2")
|
||||
else:
|
||||
print("PY3")
|
||||
|
||||
if sys.version_info < (3,0): print(1 if True else 3)
|
||||
else:
|
||||
print("py3")
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
def f():
|
||||
print("py2")
|
||||
else:
|
||||
def f():
|
||||
print("py3")
|
||||
print("This the next")
|
||||
|
||||
if sys.version_info > (3,0):
|
||||
print("py3")
|
||||
else:
|
||||
print("py2")
|
||||
|
||||
|
||||
x = 1
|
||||
|
||||
if sys.version_info > (3,0):
|
||||
print("py3")
|
||||
else:
|
||||
print("py2")
|
||||
# ohai
|
||||
|
||||
x = 1
|
||||
|
||||
if sys.version_info > (3,0): print("py3")
|
||||
else: print("py2")
|
||||
|
||||
if sys.version_info > (3,):
|
||||
print("py3")
|
||||
else:
|
||||
print("py2")
|
||||
|
||||
if True:
|
||||
if sys.version_info > (3,):
|
||||
print("py3")
|
||||
else:
|
||||
print("py2")
|
||||
|
||||
if sys.version_info < (3,):
|
||||
print("py2")
|
||||
else:
|
||||
print("py3")
|
||||
|
||||
def f():
|
||||
if sys.version_info < (3,0):
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
pass
|
||||
else:
|
||||
yield
|
||||
|
||||
|
||||
class C:
|
||||
def g():
|
||||
pass
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
def f(py2):
|
||||
pass
|
||||
else:
|
||||
def f(py3):
|
||||
pass
|
||||
|
||||
def h():
|
||||
pass
|
||||
|
||||
if True:
|
||||
if sys.version_info < (3,0):
|
||||
2
|
||||
else:
|
||||
3
|
||||
|
||||
# comment
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
def f():
|
||||
print("py2")
|
||||
def g():
|
||||
print("py2")
|
||||
else:
|
||||
def f():
|
||||
print("py3")
|
||||
def g():
|
||||
print("py3")
|
||||
|
||||
if True:
|
||||
if sys.version_info > (3,):
|
||||
print(3)
|
||||
# comment
|
||||
print(2+3)
|
||||
|
||||
if True:
|
||||
if sys.version_info > (3,): print(3)
|
||||
|
||||
if True:
|
||||
if sys.version_info > (3,):
|
||||
print(3)
|
||||
|
||||
|
||||
if True:
|
||||
if sys.version_info <= (3, 0):
|
||||
expected_error = []
|
||||
else:
|
||||
expected_error = [
|
||||
"<stdin>:1:5: Generator expression must be parenthesized",
|
||||
"max(1 for i in range(10), key=lambda x: x+1)",
|
||||
" ^",
|
||||
]
|
||||
|
||||
|
||||
if sys.version_info <= (3, 0):
|
||||
expected_error = []
|
||||
else:
|
||||
expected_error = [
|
||||
"<stdin>:1:5: Generator expression must be parenthesized",
|
||||
"max(1 for i in range(10), key=lambda x: x+1)",
|
||||
" ^",
|
||||
]
|
||||
|
||||
|
||||
if sys.version_info > (3,0):
|
||||
"""this
|
||||
is valid"""
|
||||
|
||||
"""the indentation on
|
||||
this line is significant"""
|
||||
|
||||
"this is" \
|
||||
"allowed too"
|
||||
|
||||
("so is"
|
||||
"this for some reason")
|
||||
|
||||
if sys.version_info > (3, 0): expected_error = \
|
||||
[]
|
||||
|
||||
if sys.version_info > (3, 0): expected_error = []
|
||||
|
||||
if sys.version_info > (3, 0): \
|
||||
expected_error = []
|
||||
|
||||
if True:
|
||||
if sys.version_info > (3, 0): expected_error = \
|
||||
[]
|
||||
|
||||
if True:
|
||||
if sys.version_info > (3, 0): expected_error = []
|
||||
|
||||
if True:
|
||||
if sys.version_info > (3, 0): \
|
||||
expected_error = []
|
76
resources/test/fixtures/pyupgrade/UP036_1.py
vendored
Normal file
76
resources/test/fixtures/pyupgrade/UP036_1.py
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
import sys
|
||||
|
||||
if sys.version_info == 2:
|
||||
2
|
||||
else:
|
||||
3
|
||||
|
||||
if sys.version_info < (3,):
|
||||
2
|
||||
else:
|
||||
3
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
2
|
||||
else:
|
||||
3
|
||||
|
||||
if sys.version_info == 3:
|
||||
3
|
||||
else:
|
||||
2
|
||||
|
||||
if sys.version_info > (3,):
|
||||
3
|
||||
else:
|
||||
2
|
||||
|
||||
if sys.version_info >= (3,):
|
||||
3
|
||||
else:
|
||||
2
|
||||
|
||||
from sys import version_info
|
||||
|
||||
if version_info > (3,):
|
||||
3
|
||||
else:
|
||||
2
|
||||
|
||||
if True:
|
||||
print(1)
|
||||
elif sys.version_info < (3,0):
|
||||
print(2)
|
||||
else:
|
||||
print(3)
|
||||
|
||||
if True:
|
||||
print(1)
|
||||
elif sys.version_info > (3,):
|
||||
print(3)
|
||||
else:
|
||||
print(2)
|
||||
|
||||
if True:
|
||||
print(1)
|
||||
elif sys.version_info > (3,):
|
||||
print(3)
|
||||
|
||||
def f():
|
||||
if True:
|
||||
print(1)
|
||||
elif sys.version_info > (3,):
|
||||
print(3)
|
||||
|
||||
if True:
|
||||
print(1)
|
||||
elif sys.version_info < (3,0):
|
||||
print(2)
|
||||
else:
|
||||
print(3)
|
||||
|
||||
def f():
|
||||
if True:
|
||||
print(1)
|
||||
elif sys.version_info > (3,):
|
||||
print(3)
|
62
resources/test/fixtures/pyupgrade/UP036_2.py
vendored
Normal file
62
resources/test/fixtures/pyupgrade/UP036_2.py
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
import sys
|
||||
from sys import version_info
|
||||
|
||||
if sys.version_info > (3, 5):
|
||||
3+6
|
||||
else:
|
||||
3-5
|
||||
|
||||
if version_info > (3, 5):
|
||||
3+6
|
||||
else:
|
||||
3-5
|
||||
|
||||
if sys.version_info >= (3,6):
|
||||
3+6
|
||||
else:
|
||||
3-5
|
||||
|
||||
if version_info >= (3,6):
|
||||
3+6
|
||||
else:
|
||||
3-5
|
||||
|
||||
if sys.version_info < (3,6):
|
||||
3-5
|
||||
else:
|
||||
3+6
|
||||
|
||||
if sys.version_info <= (3,5):
|
||||
3-5
|
||||
else:
|
||||
3+6
|
||||
|
||||
if sys.version_info <= (3, 5):
|
||||
3-5
|
||||
else:
|
||||
3+6
|
||||
|
||||
if sys.version_info >= (3, 5):
|
||||
pass
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
pass
|
||||
|
||||
if True:
|
||||
if sys.version_info < (3,0):
|
||||
pass
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
pass
|
||||
elif False:
|
||||
pass
|
||||
|
||||
if sys.version_info > (3,):
|
||||
pass
|
||||
elif False:
|
||||
pass
|
||||
|
||||
if sys.version_info[0] > "2":
|
||||
3
|
||||
else:
|
||||
2
|
24
resources/test/fixtures/pyupgrade/UP036_3.py
vendored
Normal file
24
resources/test/fixtures/pyupgrade/UP036_3.py
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
import sys
|
||||
|
||||
if sys.version_info < (3,0):
|
||||
print("py2")
|
||||
for item in range(10):
|
||||
print(f"PY2-{item}")
|
||||
else :
|
||||
print("py3")
|
||||
for item in range(10):
|
||||
print(f"PY3-{item}")
|
||||
|
||||
if False:
|
||||
if sys.version_info < (3,0):
|
||||
print("py2")
|
||||
for item in range(10):
|
||||
print(f"PY2-{item}")
|
||||
else :
|
||||
print("py3")
|
||||
for item in range(10):
|
||||
print(f"PY3-{item}")
|
||||
|
||||
|
||||
if sys.version_info < (3,0): print("PY2!")
|
||||
else : print("PY3!")
|
45
resources/test/fixtures/pyupgrade/UP036_4.py
vendored
Normal file
45
resources/test/fixtures/pyupgrade/UP036_4.py
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
import sys
|
||||
|
||||
if True:
|
||||
if sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
|
||||
|
||||
if True:
|
||||
if foo:
|
||||
pass
|
||||
elif sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
|
||||
if True:
|
||||
if foo:
|
||||
pass
|
||||
elif sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
elif foo:
|
||||
cmd = [sys.executable, "-m", "test", "-j0"]
|
||||
|
||||
if foo:
|
||||
pass
|
||||
elif sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
|
||||
if sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
|
||||
if foo:
|
||||
pass
|
||||
elif sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
else:
|
||||
cmd = [sys.executable, "-m", "test", "-j0"]
|
||||
|
||||
if sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
else:
|
||||
cmd = [sys.executable, "-m", "test", "-j0"]
|
||||
|
||||
if sys.version_info < (3, 3):
|
||||
cmd = [sys.executable, "-m", "test.regrtest"]
|
||||
elif foo:
|
||||
cmd = [sys.executable, "-m", "test", "-j0"]
|
|
@ -1905,6 +1905,7 @@
|
|||
"UP033",
|
||||
"UP034",
|
||||
"UP035",
|
||||
"UP036",
|
||||
"W",
|
||||
"W2",
|
||||
"W29",
|
||||
|
|
2
setup.py
2
setup.py
|
@ -22,3 +22,5 @@ sys.exit(1)
|
|||
# To be removed once GitHub catches up.
|
||||
|
||||
setup(name="ruff", install_requires=[])
|
||||
if True: a = 1; \
|
||||
b = 2
|
||||
|
|
|
@ -1500,6 +1500,9 @@ where
|
|||
self.current_stmt_parent().map(Into::into),
|
||||
);
|
||||
}
|
||||
if self.settings.rules.enabled(&Rule::OutdatedVersionBlock) {
|
||||
pyupgrade::rules::outdated_version_block(self, stmt, test, body, orelse);
|
||||
}
|
||||
}
|
||||
StmtKind::Assert { test, msg } => {
|
||||
if self.settings.rules.enabled(&Rule::AssertTuple) {
|
||||
|
|
|
@ -256,6 +256,7 @@ ruff_macros::define_rule_mapping!(
|
|||
UP033 => violations::FunctoolsCache,
|
||||
UP034 => violations::ExtraneousParentheses,
|
||||
UP035 => rules::pyupgrade::rules::ImportReplacements,
|
||||
UP036 => rules::pyupgrade::rules::OutdatedVersionBlock,
|
||||
// pydocstyle
|
||||
D100 => violations::PublicModule,
|
||||
D101 => violations::PublicClass,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use anyhow::{bail, Result};
|
||||
use libcst_native::{
|
||||
Codegen, CodegenState, Expression, ParenthesizableWhitespace, SmallStatement, Statement,
|
||||
Codegen, CodegenState, CompoundStatement, Expression, ParenthesizableWhitespace,
|
||||
SmallStatement, Statement, Suite,
|
||||
};
|
||||
use rustpython_ast::{Expr, Keyword, Location};
|
||||
use rustpython_parser::lexer;
|
||||
|
@ -7,9 +9,47 @@ use rustpython_parser::lexer::Tok;
|
|||
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix::helpers::remove_argument;
|
||||
use crate::cst::matchers::match_module;
|
||||
use crate::fix::Fix;
|
||||
use crate::source_code::{Locator, Stylist};
|
||||
|
||||
/// Safely adjust the indentation of the indented block at [`Range`].
|
||||
pub fn adjust_indentation(
|
||||
range: Range,
|
||||
indentation: &str,
|
||||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
) -> Result<String> {
|
||||
let contents = locator.slice_source_code_range(&range);
|
||||
|
||||
let module_text = format!("def f():{}{contents}", stylist.line_ending().as_str());
|
||||
|
||||
let mut tree = match_module(&module_text)?;
|
||||
|
||||
let [Statement::Compound(CompoundStatement::FunctionDef(embedding))] = &mut *tree.body else {
|
||||
bail!("Expected statement to be embedded in a function definition")
|
||||
};
|
||||
|
||||
let Suite::IndentedBlock(indented_block) = &mut embedding.body else {
|
||||
bail!("Expected indented block")
|
||||
};
|
||||
indented_block.indent = Some(indentation);
|
||||
|
||||
let mut state = CodegenState {
|
||||
default_newline: stylist.line_ending(),
|
||||
default_indent: stylist.indentation(),
|
||||
..Default::default()
|
||||
};
|
||||
indented_block.codegen(&mut state);
|
||||
|
||||
let module_text = state.to_string();
|
||||
let module_text = module_text
|
||||
.strip_prefix(stylist.line_ending().as_str())
|
||||
.unwrap()
|
||||
.to_string();
|
||||
Ok(module_text)
|
||||
}
|
||||
|
||||
/// Generate a fix to remove a base from a `ClassDef` statement.
|
||||
pub fn remove_class_def_base(
|
||||
locator: &Locator,
|
||||
|
|
|
@ -58,6 +58,11 @@ mod tests {
|
|||
#[test_case(Rule::FunctoolsCache, Path::new("UP033.py"); "UP033")]
|
||||
#[test_case(Rule::ExtraneousParentheses, Path::new("UP034.py"); "UP034")]
|
||||
#[test_case(Rule::ImportReplacements, Path::new("UP035.py"); "UP035")]
|
||||
#[test_case(Rule::OutdatedVersionBlock, Path::new("UP036_0.py"); "UP036_0")]
|
||||
#[test_case(Rule::OutdatedVersionBlock, Path::new("UP036_1.py"); "UP036_1")]
|
||||
#[test_case(Rule::OutdatedVersionBlock, Path::new("UP036_2.py"); "UP036_2")]
|
||||
#[test_case(Rule::OutdatedVersionBlock, Path::new("UP036_3.py"); "UP036_3")]
|
||||
#[test_case(Rule::OutdatedVersionBlock, Path::new("UP036_4.py"); "UP036_4")]
|
||||
fn rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.code(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
|
|
|
@ -11,6 +11,7 @@ pub(crate) use lru_cache_without_parameters::lru_cache_without_parameters;
|
|||
pub(crate) use native_literals::native_literals;
|
||||
pub(crate) use open_alias::open_alias;
|
||||
pub(crate) use os_error_alias::os_error_alias;
|
||||
pub(crate) use outdated_version_block::{outdated_version_block, OutdatedVersionBlock};
|
||||
pub(crate) use printf_string_formatting::printf_string_formatting;
|
||||
pub(crate) use redundant_open_modes::redundant_open_modes;
|
||||
pub(crate) use replace_stdout_stderr::replace_stdout_stderr;
|
||||
|
@ -46,6 +47,7 @@ mod lru_cache_without_parameters;
|
|||
mod native_literals;
|
||||
mod open_alias;
|
||||
mod os_error_alias;
|
||||
mod outdated_version_block;
|
||||
mod printf_string_formatting;
|
||||
mod redundant_open_modes;
|
||||
mod replace_stdout_stderr;
|
||||
|
|
442
src/rules/pyupgrade/rules/outdated_version_block.rs
Normal file
442
src/rules/pyupgrade/rules/outdated_version_block.rs
Normal file
|
@ -0,0 +1,442 @@
|
|||
use std::cmp::Ordering;
|
||||
|
||||
use log::error;
|
||||
use num_bigint::{BigInt, Sign};
|
||||
use rustpython_ast::Location;
|
||||
use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind, Located, Stmt};
|
||||
use rustpython_parser::lexer;
|
||||
use rustpython_parser::lexer::Tok;
|
||||
|
||||
use ruff_macros::derive_message_formats;
|
||||
|
||||
use crate::ast::types::{Range, RefEquality};
|
||||
use crate::ast::whitespace::indentation;
|
||||
use crate::autofix::helpers::delete_stmt;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::define_violation;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::rules::pyupgrade::fixes::adjust_indentation;
|
||||
use crate::settings::types::PythonVersion;
|
||||
use crate::source_code::Locator;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
|
||||
define_violation!(
|
||||
pub struct OutdatedVersionBlock;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for OutdatedVersionBlock {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Version block is outdated for minimum Python version")
|
||||
}
|
||||
|
||||
fn autofix_title(&self) -> String {
|
||||
"Remove outdated version block".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BlockMetadata {
|
||||
/// The first non-whitespace token in the block.
|
||||
starter: Tok,
|
||||
/// The location of the first `elif` token, if any.
|
||||
elif: Option<Location>,
|
||||
/// The location of the `else` token, if any.
|
||||
else_: Option<Location>,
|
||||
}
|
||||
|
||||
impl BlockMetadata {
|
||||
fn new(starter: Tok, elif: Option<Location>, else_: Option<Location>) -> Self {
|
||||
Self {
|
||||
starter,
|
||||
elif,
|
||||
else_,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn metadata<T>(locator: &Locator, located: &Located<T>) -> Option<BlockMetadata> {
|
||||
indentation(locator, located)?;
|
||||
|
||||
// Start the selection at the start-of-line. This ensures consistent indentation in the
|
||||
// token stream, in the event that the entire block is indented.
|
||||
let text = locator.slice_source_code_range(&Range::new(
|
||||
Location::new(located.location.row(), 0),
|
||||
located.end_location.unwrap(),
|
||||
));
|
||||
|
||||
let mut starter: Option<Tok> = None;
|
||||
let mut elif = None;
|
||||
let mut else_ = None;
|
||||
|
||||
for (start, tok, _) in
|
||||
lexer::make_tokenizer_located(text, Location::new(located.location.row(), 0))
|
||||
.flatten()
|
||||
.filter(|(_, tok, _)| {
|
||||
!matches!(
|
||||
tok,
|
||||
Tok::Indent
|
||||
| Tok::Dedent
|
||||
| Tok::NonLogicalNewline
|
||||
| Tok::Newline
|
||||
| Tok::Comment(..)
|
||||
)
|
||||
})
|
||||
{
|
||||
if starter.is_none() {
|
||||
starter = Some(tok.clone());
|
||||
} else {
|
||||
if matches!(tok, Tok::Elif) && elif.is_none() {
|
||||
elif = Some(start);
|
||||
}
|
||||
if matches!(tok, Tok::Else) && else_.is_none() {
|
||||
else_ = Some(start);
|
||||
}
|
||||
}
|
||||
if starter.is_some() && elif.is_some() && else_.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Some(BlockMetadata::new(starter.unwrap(), elif, else_))
|
||||
}
|
||||
|
||||
/// Converts a `BigInt` to a `u32`, if the number is negative, it will return 0
|
||||
fn bigint_to_u32(number: &BigInt) -> u32 {
|
||||
let the_number = number.to_u32_digits();
|
||||
match the_number.0 {
|
||||
Sign::Minus | Sign::NoSign => 0,
|
||||
Sign::Plus => *the_number.1.first().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the version from the tuple
|
||||
fn extract_version(elts: &[Expr]) -> Vec<u32> {
|
||||
let mut version: Vec<u32> = vec![];
|
||||
for elt in elts {
|
||||
if let ExprKind::Constant {
|
||||
value: Constant::Int(item),
|
||||
..
|
||||
} = &elt.node
|
||||
{
|
||||
let number = bigint_to_u32(item);
|
||||
version.push(number);
|
||||
} else {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
version
|
||||
}
|
||||
|
||||
/// Returns true if the `if_version` is less than the `PythonVersion`
|
||||
fn compare_version(if_version: &[u32], py_version: PythonVersion, or_equal: bool) -> bool {
|
||||
let mut if_version_iter = if_version.iter();
|
||||
if let Some(if_major) = if_version_iter.next() {
|
||||
let (py_major, py_minor) = py_version.as_tuple();
|
||||
match if_major.cmp(&py_major) {
|
||||
Ordering::Less => true,
|
||||
Ordering::Equal => {
|
||||
if let Some(if_minor) = if_version_iter.next() {
|
||||
// Check the if_minor number (the minor version).
|
||||
if or_equal {
|
||||
*if_minor <= py_minor
|
||||
} else {
|
||||
*if_minor < py_minor
|
||||
}
|
||||
} else {
|
||||
// Assume Python 3.0.
|
||||
true
|
||||
}
|
||||
}
|
||||
Ordering::Greater => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a [`StmtKind::If`], retaining the `else`.
|
||||
fn fix_py2_block(
|
||||
checker: &mut Checker,
|
||||
stmt: &Stmt,
|
||||
body: &[Stmt],
|
||||
orelse: &[Stmt],
|
||||
block: &BlockMetadata,
|
||||
) -> Option<Fix> {
|
||||
if orelse.is_empty() {
|
||||
// Delete the entire statement. If this is an `elif`, know it's the only child of its
|
||||
// parent, so avoid passing in the parent at all. Otherwise, `delete_stmt` will erroneously
|
||||
// include a `pass`.
|
||||
let deleted: Vec<&Stmt> = checker
|
||||
.deletions
|
||||
.iter()
|
||||
.map(std::convert::Into::into)
|
||||
.collect();
|
||||
let defined_by = checker.current_stmt();
|
||||
let defined_in = checker.current_stmt_parent();
|
||||
return match delete_stmt(
|
||||
defined_by.into(),
|
||||
if block.starter == Tok::If {
|
||||
defined_in.map(std::convert::Into::into)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
&deleted,
|
||||
checker.locator,
|
||||
checker.indexer,
|
||||
checker.stylist,
|
||||
) {
|
||||
Ok(fix) => {
|
||||
checker.deletions.insert(RefEquality(defined_by.into()));
|
||||
Some(fix)
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Failed to remove block: {}", err);
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// If we only have an `if` and an `else`, dedent the `else` block.
|
||||
if block.starter == Tok::If && block.elif.is_none() {
|
||||
let start = orelse.first().unwrap();
|
||||
let end = orelse.last().unwrap();
|
||||
|
||||
if indentation(checker.locator, start).is_none() {
|
||||
// Inline `else` block (e.g., `else: x = 1`).
|
||||
Some(Fix::replacement(
|
||||
checker
|
||||
.locator
|
||||
.slice_source_code_range(&Range::new(start.location, end.end_location.unwrap()))
|
||||
.to_string(),
|
||||
stmt.location,
|
||||
stmt.end_location.unwrap(),
|
||||
))
|
||||
} else {
|
||||
indentation(checker.locator, stmt)
|
||||
.and_then(|indentation| {
|
||||
adjust_indentation(
|
||||
Range::new(
|
||||
Location::new(start.location.row(), 0),
|
||||
end.end_location.unwrap(),
|
||||
),
|
||||
indentation,
|
||||
checker.locator,
|
||||
checker.stylist,
|
||||
)
|
||||
.ok()
|
||||
})
|
||||
.map(|contents| {
|
||||
Fix::replacement(
|
||||
contents,
|
||||
Location::new(stmt.location.row(), 0),
|
||||
stmt.end_location.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let mut end_location = orelse.last().unwrap().location;
|
||||
if block.starter == Tok::If && block.elif.is_some() {
|
||||
// Turn the `elif` into an `if`.
|
||||
end_location = block.elif.unwrap();
|
||||
end_location.go_right();
|
||||
end_location.go_right();
|
||||
} else if block.starter == Tok::Elif {
|
||||
if let Some(elif) = block.elif {
|
||||
end_location = elif;
|
||||
} else if let Some(else_) = block.else_ {
|
||||
end_location = else_;
|
||||
} else {
|
||||
end_location = body.last().unwrap().end_location.unwrap();
|
||||
}
|
||||
}
|
||||
Some(Fix::deletion(stmt.location, end_location))
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a [`StmtKind::If`], removing the `else` block.
|
||||
fn fix_py3_block(
|
||||
checker: &mut Checker,
|
||||
stmt: &Stmt,
|
||||
test: &Expr,
|
||||
body: &[Stmt],
|
||||
block: &BlockMetadata,
|
||||
) -> Option<Fix> {
|
||||
match block.starter {
|
||||
Tok::If => {
|
||||
// If the first statement is an if, use the body of this statement, and ignore the rest.
|
||||
let start = body.first().unwrap();
|
||||
let end = body.last().unwrap();
|
||||
|
||||
if indentation(checker.locator, start).is_none() {
|
||||
// Inline `if` block (e.g., `if ...: x = 1`).
|
||||
Some(Fix::replacement(
|
||||
checker
|
||||
.locator
|
||||
.slice_source_code_range(&Range::new(
|
||||
start.location,
|
||||
end.end_location.unwrap(),
|
||||
))
|
||||
.to_string(),
|
||||
stmt.location,
|
||||
stmt.end_location.unwrap(),
|
||||
))
|
||||
} else {
|
||||
indentation(checker.locator, stmt)
|
||||
.and_then(|indentation| {
|
||||
adjust_indentation(
|
||||
Range::new(
|
||||
Location::new(start.location.row(), 0),
|
||||
end.end_location.unwrap(),
|
||||
),
|
||||
indentation,
|
||||
checker.locator,
|
||||
checker.stylist,
|
||||
)
|
||||
.ok()
|
||||
})
|
||||
.map(|contents| {
|
||||
Fix::replacement(
|
||||
contents,
|
||||
Location::new(stmt.location.row(), 0),
|
||||
stmt.end_location.unwrap(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
Tok::Elif => {
|
||||
// Replace the `elif` with an `else, preserve the body of the elif, and remove the rest.
|
||||
let end = body.last().unwrap();
|
||||
let text = checker.locator.slice_source_code_range(&Range::new(
|
||||
test.end_location.unwrap(),
|
||||
end.end_location.unwrap(),
|
||||
));
|
||||
Some(Fix::replacement(
|
||||
format!("else{text}"),
|
||||
stmt.location,
|
||||
stmt.end_location.unwrap(),
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// UP036
|
||||
pub fn outdated_version_block(
|
||||
checker: &mut Checker,
|
||||
stmt: &Stmt,
|
||||
test: &Expr,
|
||||
body: &[Stmt],
|
||||
orelse: &[Stmt],
|
||||
) {
|
||||
let ExprKind::Compare {
|
||||
left,
|
||||
ops,
|
||||
comparators,
|
||||
} = &test.node else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !checker.resolve_call_path(left).map_or(false, |call_path| {
|
||||
call_path.as_slice() == ["sys", "version_info"]
|
||||
}) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ops.len() == 1 && comparators.len() == 1 {
|
||||
let comparison = &comparators[0].node;
|
||||
let op = &ops[0];
|
||||
match comparison {
|
||||
ExprKind::Tuple { elts, .. } => {
|
||||
let version = extract_version(elts);
|
||||
let target = checker.settings.target_version;
|
||||
if op == &Cmpop::Lt || op == &Cmpop::LtE {
|
||||
if compare_version(&version, target, op == &Cmpop::LtE) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(OutdatedVersionBlock, Range::from_located(stmt));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if let Some(block) = metadata(checker.locator, stmt) {
|
||||
if let Some(fix) =
|
||||
fix_py2_block(checker, stmt, body, orelse, &block)
|
||||
{
|
||||
diagnostic.amend(fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
} else if op == &Cmpop::Gt || op == &Cmpop::GtE {
|
||||
if compare_version(&version, target, op == &Cmpop::GtE) {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(OutdatedVersionBlock, Range::from_located(stmt));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if let Some(block) = metadata(checker.locator, stmt) {
|
||||
if let Some(fix) = fix_py3_block(checker, stmt, test, body, &block)
|
||||
{
|
||||
diagnostic.amend(fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
ExprKind::Constant {
|
||||
value: Constant::Int(number),
|
||||
..
|
||||
} => {
|
||||
let version_number = bigint_to_u32(number);
|
||||
if version_number == 2 && op == &Cmpop::Eq {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(OutdatedVersionBlock, Range::from_located(stmt));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if let Some(block) = metadata(checker.locator, stmt) {
|
||||
if let Some(fix) = fix_py2_block(checker, stmt, body, orelse, &block) {
|
||||
diagnostic.amend(fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
} else if version_number == 3 && op == &Cmpop::Eq {
|
||||
let mut diagnostic =
|
||||
Diagnostic::new(OutdatedVersionBlock, Range::from_located(stmt));
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
if let Some(block) = metadata(checker.locator, stmt) {
|
||||
if let Some(fix) = fix_py3_block(checker, stmt, test, body, &block) {
|
||||
diagnostic.amend(fix);
|
||||
}
|
||||
}
|
||||
}
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use test_case::test_case;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test_case(PythonVersion::Py37, &[2], true, true; "compare-2.0")]
|
||||
#[test_case(PythonVersion::Py37, &[2, 0], true, true; "compare-2.0-whole")]
|
||||
#[test_case(PythonVersion::Py37, &[3], true, true; "compare-3.0")]
|
||||
#[test_case(PythonVersion::Py37, &[3, 0], true, true; "compare-3.0-whole")]
|
||||
#[test_case(PythonVersion::Py37, &[3, 1], true, true; "compare-3.1")]
|
||||
#[test_case(PythonVersion::Py37, &[3, 5], true, true; "compare-3.5")]
|
||||
#[test_case(PythonVersion::Py37, &[3, 7], true, true; "compare-3.7")]
|
||||
#[test_case(PythonVersion::Py37, &[3, 7], false, false; "compare-3.7-not-equal")]
|
||||
#[test_case(PythonVersion::Py37, &[3, 8], false , false; "compare-3.8")]
|
||||
#[test_case(PythonVersion::Py310, &[3,9], true, true; "compare-3.9")]
|
||||
#[test_case(PythonVersion::Py310, &[3, 11], true, false; "compare-3.11")]
|
||||
fn test_compare_version(
|
||||
version: PythonVersion,
|
||||
version_vec: &[u32],
|
||||
or_equal: bool,
|
||||
expected: bool,
|
||||
) {
|
||||
assert_eq!(compare_version(version_vec, version, or_equal), expected);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,535 @@
|
|||
---
|
||||
source: src/rules/pyupgrade/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 6
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 6
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
end_location:
|
||||
row: 14
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
end_location:
|
||||
row: 14
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 16
|
||||
column: 0
|
||||
end_location:
|
||||
row: 17
|
||||
column: 19
|
||||
fix:
|
||||
content:
|
||||
- "print(\"PY3!\")"
|
||||
location:
|
||||
row: 16
|
||||
column: 0
|
||||
end_location:
|
||||
row: 17
|
||||
column: 19
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 20
|
||||
column: 4
|
||||
end_location:
|
||||
row: 23
|
||||
column: 20
|
||||
fix:
|
||||
content:
|
||||
- " print(\"PY3\")"
|
||||
location:
|
||||
row: 20
|
||||
column: 0
|
||||
end_location:
|
||||
row: 23
|
||||
column: 20
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 25
|
||||
column: 0
|
||||
end_location:
|
||||
row: 27
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 25
|
||||
column: 0
|
||||
end_location:
|
||||
row: 27
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 29
|
||||
column: 0
|
||||
end_location:
|
||||
row: 35
|
||||
column: 30
|
||||
fix:
|
||||
content:
|
||||
- "def f():"
|
||||
- " print(\"py3\")"
|
||||
- " print(\"This the next\")"
|
||||
location:
|
||||
row: 29
|
||||
column: 0
|
||||
end_location:
|
||||
row: 35
|
||||
column: 30
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 37
|
||||
column: 0
|
||||
end_location:
|
||||
row: 40
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 37
|
||||
column: 0
|
||||
end_location:
|
||||
row: 40
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 45
|
||||
column: 0
|
||||
end_location:
|
||||
row: 48
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 45
|
||||
column: 0
|
||||
end_location:
|
||||
row: 48
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 53
|
||||
column: 0
|
||||
end_location:
|
||||
row: 54
|
||||
column: 18
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 53
|
||||
column: 0
|
||||
end_location:
|
||||
row: 54
|
||||
column: 18
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 56
|
||||
column: 0
|
||||
end_location:
|
||||
row: 59
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 56
|
||||
column: 0
|
||||
end_location:
|
||||
row: 59
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 62
|
||||
column: 4
|
||||
end_location:
|
||||
row: 65
|
||||
column: 20
|
||||
fix:
|
||||
content:
|
||||
- " print(\"py3\")"
|
||||
location:
|
||||
row: 62
|
||||
column: 0
|
||||
end_location:
|
||||
row: 65
|
||||
column: 20
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 67
|
||||
column: 0
|
||||
end_location:
|
||||
row: 70
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
location:
|
||||
row: 67
|
||||
column: 0
|
||||
end_location:
|
||||
row: 70
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 73
|
||||
column: 4
|
||||
end_location:
|
||||
row: 79
|
||||
column: 13
|
||||
fix:
|
||||
content:
|
||||
- " yield"
|
||||
location:
|
||||
row: 73
|
||||
column: 0
|
||||
end_location:
|
||||
row: 79
|
||||
column: 13
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 86
|
||||
column: 4
|
||||
end_location:
|
||||
row: 91
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- " def f(py3):"
|
||||
- " pass"
|
||||
location:
|
||||
row: 86
|
||||
column: 0
|
||||
end_location:
|
||||
row: 91
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 97
|
||||
column: 4
|
||||
end_location:
|
||||
row: 100
|
||||
column: 9
|
||||
fix:
|
||||
content:
|
||||
- " 3"
|
||||
location:
|
||||
row: 97
|
||||
column: 0
|
||||
end_location:
|
||||
row: 100
|
||||
column: 9
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 104
|
||||
column: 0
|
||||
end_location:
|
||||
row: 113
|
||||
column: 20
|
||||
fix:
|
||||
content:
|
||||
- "def f():"
|
||||
- " print(\"py3\")"
|
||||
- "def g():"
|
||||
- " print(\"py3\")"
|
||||
location:
|
||||
row: 104
|
||||
column: 0
|
||||
end_location:
|
||||
row: 113
|
||||
column: 20
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 116
|
||||
column: 4
|
||||
end_location:
|
||||
row: 117
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- " print(3)"
|
||||
location:
|
||||
row: 116
|
||||
column: 0
|
||||
end_location:
|
||||
row: 117
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 122
|
||||
column: 4
|
||||
end_location:
|
||||
row: 122
|
||||
column: 40
|
||||
fix:
|
||||
content:
|
||||
- print(3)
|
||||
location:
|
||||
row: 122
|
||||
column: 4
|
||||
end_location:
|
||||
row: 122
|
||||
column: 40
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 125
|
||||
column: 4
|
||||
end_location:
|
||||
row: 126
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- " print(3)"
|
||||
location:
|
||||
row: 125
|
||||
column: 0
|
||||
end_location:
|
||||
row: 126
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 130
|
||||
column: 4
|
||||
end_location:
|
||||
row: 137
|
||||
column: 9
|
||||
fix:
|
||||
content:
|
||||
- " expected_error = ["
|
||||
- "\"<stdin>:1:5: Generator expression must be parenthesized\","
|
||||
- "\"max(1 for i in range(10), key=lambda x: x+1)\","
|
||||
- "\" ^\","
|
||||
- " ]"
|
||||
location:
|
||||
row: 130
|
||||
column: 0
|
||||
end_location:
|
||||
row: 137
|
||||
column: 9
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 140
|
||||
column: 0
|
||||
end_location:
|
||||
row: 147
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "expected_error = ["
|
||||
- "\"<stdin>:1:5: Generator expression must be parenthesized\","
|
||||
- "\"max(1 for i in range(10), key=lambda x: x+1)\","
|
||||
- "\" ^\","
|
||||
- "]"
|
||||
location:
|
||||
row: 140
|
||||
column: 0
|
||||
end_location:
|
||||
row: 147
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 150
|
||||
column: 0
|
||||
end_location:
|
||||
row: 161
|
||||
column: 28
|
||||
fix:
|
||||
content:
|
||||
- "\"\"\"this"
|
||||
- "is valid\"\"\""
|
||||
- ""
|
||||
- "\"\"\"the indentation on"
|
||||
- " this line is significant\"\"\""
|
||||
- ""
|
||||
- "\"this is\" \\"
|
||||
- " \"allowed too\""
|
||||
- ""
|
||||
- "(\"so is\""
|
||||
- " \"this for some reason\")"
|
||||
location:
|
||||
row: 150
|
||||
column: 0
|
||||
end_location:
|
||||
row: 161
|
||||
column: 28
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 163
|
||||
column: 0
|
||||
end_location:
|
||||
row: 164
|
||||
column: 6
|
||||
fix:
|
||||
content:
|
||||
- "expected_error = \\"
|
||||
- " []"
|
||||
location:
|
||||
row: 163
|
||||
column: 0
|
||||
end_location:
|
||||
row: 164
|
||||
column: 6
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 166
|
||||
column: 0
|
||||
end_location:
|
||||
row: 166
|
||||
column: 49
|
||||
fix:
|
||||
content:
|
||||
- "expected_error = []"
|
||||
location:
|
||||
row: 166
|
||||
column: 0
|
||||
end_location:
|
||||
row: 166
|
||||
column: 49
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 168
|
||||
column: 0
|
||||
end_location:
|
||||
row: 169
|
||||
column: 23
|
||||
fix:
|
||||
content:
|
||||
- "expected_error = []"
|
||||
location:
|
||||
row: 168
|
||||
column: 0
|
||||
end_location:
|
||||
row: 169
|
||||
column: 23
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 172
|
||||
column: 4
|
||||
end_location:
|
||||
row: 173
|
||||
column: 6
|
||||
fix:
|
||||
content:
|
||||
- "expected_error = \\"
|
||||
- " []"
|
||||
location:
|
||||
row: 172
|
||||
column: 4
|
||||
end_location:
|
||||
row: 173
|
||||
column: 6
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 176
|
||||
column: 4
|
||||
end_location:
|
||||
row: 176
|
||||
column: 53
|
||||
fix:
|
||||
content:
|
||||
- "expected_error = []"
|
||||
location:
|
||||
row: 176
|
||||
column: 4
|
||||
end_location:
|
||||
row: 176
|
||||
column: 53
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 179
|
||||
column: 4
|
||||
end_location:
|
||||
row: 180
|
||||
column: 23
|
||||
fix:
|
||||
content:
|
||||
- " expected_error = []"
|
||||
location:
|
||||
row: 179
|
||||
column: 0
|
||||
end_location:
|
||||
row: 180
|
||||
column: 23
|
||||
parent: ~
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
---
|
||||
source: src/rules/pyupgrade/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 6
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "3"
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 6
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
end_location:
|
||||
row: 11
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "3"
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
end_location:
|
||||
row: 11
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 13
|
||||
column: 0
|
||||
end_location:
|
||||
row: 16
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "3"
|
||||
location:
|
||||
row: 13
|
||||
column: 0
|
||||
end_location:
|
||||
row: 16
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 18
|
||||
column: 0
|
||||
end_location:
|
||||
row: 21
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "3"
|
||||
location:
|
||||
row: 18
|
||||
column: 0
|
||||
end_location:
|
||||
row: 21
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 23
|
||||
column: 0
|
||||
end_location:
|
||||
row: 26
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "3"
|
||||
location:
|
||||
row: 23
|
||||
column: 0
|
||||
end_location:
|
||||
row: 26
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 28
|
||||
column: 0
|
||||
end_location:
|
||||
row: 31
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "3"
|
||||
location:
|
||||
row: 28
|
||||
column: 0
|
||||
end_location:
|
||||
row: 31
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 35
|
||||
column: 0
|
||||
end_location:
|
||||
row: 38
|
||||
column: 5
|
||||
fix:
|
||||
content:
|
||||
- "3"
|
||||
location:
|
||||
row: 35
|
||||
column: 0
|
||||
end_location:
|
||||
row: 38
|
||||
column: 5
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 42
|
||||
column: 0
|
||||
end_location:
|
||||
row: 45
|
||||
column: 12
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 42
|
||||
column: 0
|
||||
end_location:
|
||||
row: 44
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 49
|
||||
column: 0
|
||||
end_location:
|
||||
row: 52
|
||||
column: 12
|
||||
fix:
|
||||
content:
|
||||
- "else:"
|
||||
- " print(3)"
|
||||
location:
|
||||
row: 49
|
||||
column: 0
|
||||
end_location:
|
||||
row: 52
|
||||
column: 12
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 56
|
||||
column: 0
|
||||
end_location:
|
||||
row: 57
|
||||
column: 12
|
||||
fix:
|
||||
content:
|
||||
- "else:"
|
||||
- " print(3)"
|
||||
location:
|
||||
row: 56
|
||||
column: 0
|
||||
end_location:
|
||||
row: 57
|
||||
column: 12
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 62
|
||||
column: 4
|
||||
end_location:
|
||||
row: 63
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "else:"
|
||||
- " print(3)"
|
||||
location:
|
||||
row: 62
|
||||
column: 4
|
||||
end_location:
|
||||
row: 63
|
||||
column: 16
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 67
|
||||
column: 0
|
||||
end_location:
|
||||
row: 70
|
||||
column: 12
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 67
|
||||
column: 0
|
||||
end_location:
|
||||
row: 69
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 75
|
||||
column: 4
|
||||
end_location:
|
||||
row: 76
|
||||
column: 16
|
||||
fix:
|
||||
content:
|
||||
- "else:"
|
||||
- " print(3)"
|
||||
location:
|
||||
row: 75
|
||||
column: 4
|
||||
end_location:
|
||||
row: 76
|
||||
column: 16
|
||||
parent: ~
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
---
|
||||
source: src/rules/pyupgrade/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 4
|
||||
column: 0
|
||||
end_location:
|
||||
row: 7
|
||||
column: 7
|
||||
fix:
|
||||
content:
|
||||
- 3+6
|
||||
location:
|
||||
row: 4
|
||||
column: 0
|
||||
end_location:
|
||||
row: 7
|
||||
column: 7
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 9
|
||||
column: 0
|
||||
end_location:
|
||||
row: 12
|
||||
column: 7
|
||||
fix:
|
||||
content:
|
||||
- 3+6
|
||||
location:
|
||||
row: 9
|
||||
column: 0
|
||||
end_location:
|
||||
row: 12
|
||||
column: 7
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 14
|
||||
column: 0
|
||||
end_location:
|
||||
row: 17
|
||||
column: 7
|
||||
fix:
|
||||
content:
|
||||
- 3+6
|
||||
location:
|
||||
row: 14
|
||||
column: 0
|
||||
end_location:
|
||||
row: 17
|
||||
column: 7
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 19
|
||||
column: 0
|
||||
end_location:
|
||||
row: 22
|
||||
column: 7
|
||||
fix:
|
||||
content:
|
||||
- 3+6
|
||||
location:
|
||||
row: 19
|
||||
column: 0
|
||||
end_location:
|
||||
row: 22
|
||||
column: 7
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 24
|
||||
column: 0
|
||||
end_location:
|
||||
row: 27
|
||||
column: 7
|
||||
fix:
|
||||
content:
|
||||
- 3+6
|
||||
location:
|
||||
row: 24
|
||||
column: 0
|
||||
end_location:
|
||||
row: 27
|
||||
column: 7
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 29
|
||||
column: 0
|
||||
end_location:
|
||||
row: 32
|
||||
column: 7
|
||||
fix:
|
||||
content:
|
||||
- 3+6
|
||||
location:
|
||||
row: 29
|
||||
column: 0
|
||||
end_location:
|
||||
row: 32
|
||||
column: 7
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 34
|
||||
column: 0
|
||||
end_location:
|
||||
row: 37
|
||||
column: 7
|
||||
fix:
|
||||
content:
|
||||
- 3+6
|
||||
location:
|
||||
row: 34
|
||||
column: 0
|
||||
end_location:
|
||||
row: 37
|
||||
column: 7
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 39
|
||||
column: 0
|
||||
end_location:
|
||||
row: 40
|
||||
column: 8
|
||||
fix:
|
||||
content:
|
||||
- pass
|
||||
location:
|
||||
row: 39
|
||||
column: 0
|
||||
end_location:
|
||||
row: 40
|
||||
column: 8
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 42
|
||||
column: 0
|
||||
end_location:
|
||||
row: 43
|
||||
column: 8
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 42
|
||||
column: 0
|
||||
end_location:
|
||||
row: 44
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 46
|
||||
column: 4
|
||||
end_location:
|
||||
row: 47
|
||||
column: 12
|
||||
fix:
|
||||
content:
|
||||
- pass
|
||||
location:
|
||||
row: 46
|
||||
column: 4
|
||||
end_location:
|
||||
row: 47
|
||||
column: 12
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 49
|
||||
column: 0
|
||||
end_location:
|
||||
row: 52
|
||||
column: 8
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 49
|
||||
column: 0
|
||||
end_location:
|
||||
row: 51
|
||||
column: 2
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 54
|
||||
column: 0
|
||||
end_location:
|
||||
row: 57
|
||||
column: 8
|
||||
fix:
|
||||
content:
|
||||
- pass
|
||||
location:
|
||||
row: 54
|
||||
column: 0
|
||||
end_location:
|
||||
row: 57
|
||||
column: 8
|
||||
parent: ~
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
source: src/rules/pyupgrade/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 10
|
||||
column: 28
|
||||
fix:
|
||||
content:
|
||||
- "print(\"py3\")"
|
||||
- "for item in range(10):"
|
||||
- " print(f\"PY3-{item}\")"
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 10
|
||||
column: 28
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 13
|
||||
column: 4
|
||||
end_location:
|
||||
row: 20
|
||||
column: 32
|
||||
fix:
|
||||
content:
|
||||
- " print(\"py3\")"
|
||||
- " for item in range(10):"
|
||||
- " print(f\"PY3-{item}\")"
|
||||
location:
|
||||
row: 13
|
||||
column: 0
|
||||
end_location:
|
||||
row: 20
|
||||
column: 32
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 23
|
||||
column: 0
|
||||
end_location:
|
||||
row: 24
|
||||
column: 50
|
||||
fix:
|
||||
content:
|
||||
- "print(\"PY3!\")"
|
||||
location:
|
||||
row: 23
|
||||
column: 0
|
||||
end_location:
|
||||
row: 24
|
||||
column: 50
|
||||
parent: ~
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
---
|
||||
source: src/rules/pyupgrade/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 4
|
||||
column: 4
|
||||
end_location:
|
||||
row: 5
|
||||
column: 53
|
||||
fix:
|
||||
content:
|
||||
- pass
|
||||
location:
|
||||
row: 4
|
||||
column: 4
|
||||
end_location:
|
||||
row: 5
|
||||
column: 53
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 11
|
||||
column: 4
|
||||
end_location:
|
||||
row: 12
|
||||
column: 53
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 11
|
||||
column: 0
|
||||
end_location:
|
||||
row: 13
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 17
|
||||
column: 4
|
||||
end_location:
|
||||
row: 20
|
||||
column: 51
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 17
|
||||
column: 4
|
||||
end_location:
|
||||
row: 19
|
||||
column: 4
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 24
|
||||
column: 4
|
||||
end_location:
|
||||
row: 25
|
||||
column: 53
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 24
|
||||
column: 0
|
||||
end_location:
|
||||
row: 26
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 27
|
||||
column: 4
|
||||
end_location:
|
||||
row: 28
|
||||
column: 53
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 27
|
||||
column: 0
|
||||
end_location:
|
||||
row: 29
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 32
|
||||
column: 4
|
||||
end_location:
|
||||
row: 35
|
||||
column: 51
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 32
|
||||
column: 4
|
||||
end_location:
|
||||
row: 34
|
||||
column: 4
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 37
|
||||
column: 4
|
||||
end_location:
|
||||
row: 40
|
||||
column: 51
|
||||
fix:
|
||||
content:
|
||||
- " cmd = [sys.executable, \"-m\", \"test\", \"-j0\"]"
|
||||
location:
|
||||
row: 37
|
||||
column: 0
|
||||
end_location:
|
||||
row: 40
|
||||
column: 51
|
||||
parent: ~
|
||||
- kind:
|
||||
OutdatedVersionBlock: ~
|
||||
location:
|
||||
row: 42
|
||||
column: 4
|
||||
end_location:
|
||||
row: 45
|
||||
column: 51
|
||||
fix:
|
||||
content:
|
||||
- ""
|
||||
location:
|
||||
row: 42
|
||||
column: 4
|
||||
end_location:
|
||||
row: 44
|
||||
column: 6
|
||||
parent: ~
|
||||
|
|
@ -49,6 +49,18 @@ impl FromStr for PythonVersion {
|
|||
}
|
||||
}
|
||||
|
||||
impl PythonVersion {
|
||||
pub fn as_tuple(&self) -> (u32, u32) {
|
||||
match self {
|
||||
PythonVersion::Py37 => (3, 7),
|
||||
PythonVersion::Py38 => (3, 8),
|
||||
PythonVersion::Py39 => (3, 9),
|
||||
PythonVersion::Py310 => (3, 10),
|
||||
PythonVersion::Py311 => (3, 11),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
|
||||
pub enum FilePattern {
|
||||
Builtin(&'static str),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue