mirror of https://github.com/astral-sh/ruff
feat: Implement `InvalidPrintSyntax` (`F633`)
This commit is contained in:
parent
53a7758248
commit
6d3abdf1d6
|
|
@ -0,0 +1,4 @@
|
|||
from __future__ import print_function
|
||||
import sys
|
||||
|
||||
print >> sys.stderr, "Hello"
|
||||
|
|
@ -3,7 +3,7 @@ use std::path::Path;
|
|||
|
||||
use rustpython_parser::ast::{
|
||||
Arg, Arguments, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind,
|
||||
KeywordData, Location, Stmt, StmtKind, Suite,
|
||||
KeywordData, Location, Operator, Stmt, StmtKind, Suite,
|
||||
};
|
||||
use rustpython_parser::parser;
|
||||
|
||||
|
|
@ -668,6 +668,28 @@ where
|
|||
}
|
||||
self.in_f_string = true;
|
||||
}
|
||||
ExprKind::BinOp {
|
||||
left,
|
||||
op: Operator::RShift,
|
||||
..
|
||||
} => {
|
||||
if self.settings.select.contains(&CheckCode::F633) {
|
||||
if let ExprKind::Name { id, .. } = &left.node {
|
||||
if id == "print" {
|
||||
let scope = &self.scopes
|
||||
[*(self.scope_stack.last().expect("No current scope found."))];
|
||||
if let Some(Binding {
|
||||
kind: BindingKind::Builtin,
|
||||
..
|
||||
}) = scope.values.get("print")
|
||||
{
|
||||
self.checks
|
||||
.push(Check::new(CheckKind::InvalidPrintSyntax, left.location));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ExprKind::UnaryOp { op, operand } => {
|
||||
let check_not_in = self.settings.select.contains(&CheckCode::E713);
|
||||
let check_not_is = self.settings.select.contains(&CheckCode::E714);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ pub enum CheckCode {
|
|||
F621,
|
||||
F622,
|
||||
F631,
|
||||
F633,
|
||||
F634,
|
||||
F701,
|
||||
F702,
|
||||
|
|
@ -76,6 +77,7 @@ impl FromStr for CheckCode {
|
|||
"F621" => Ok(CheckCode::F621),
|
||||
"F622" => Ok(CheckCode::F622),
|
||||
"F631" => Ok(CheckCode::F631),
|
||||
"F633" => Ok(CheckCode::F633),
|
||||
"F634" => Ok(CheckCode::F634),
|
||||
"F701" => Ok(CheckCode::F701),
|
||||
"F702" => Ok(CheckCode::F702),
|
||||
|
|
@ -121,6 +123,7 @@ impl CheckCode {
|
|||
CheckCode::F621 => "F621",
|
||||
CheckCode::F622 => "F622",
|
||||
CheckCode::F631 => "F631",
|
||||
CheckCode::F633 => "F633",
|
||||
CheckCode::F634 => "F634",
|
||||
CheckCode::F701 => "F701",
|
||||
CheckCode::F702 => "F702",
|
||||
|
|
@ -179,6 +182,7 @@ pub enum CheckKind {
|
|||
FutureFeatureNotDefined(String),
|
||||
IOError(String),
|
||||
IfTuple,
|
||||
InvalidPrintSyntax,
|
||||
ImportStarNotPermitted(String),
|
||||
ImportStarUsage(String),
|
||||
LateFutureImport,
|
||||
|
|
@ -223,6 +227,7 @@ impl CheckKind {
|
|||
CheckKind::FutureFeatureNotDefined(_) => "FutureFeatureNotDefined",
|
||||
CheckKind::IOError(_) => "IOError",
|
||||
CheckKind::IfTuple => "IfTuple",
|
||||
CheckKind::InvalidPrintSyntax => "InvalidPrintSyntax",
|
||||
CheckKind::ImportStarNotPermitted(_) => "ImportStarNotPermitted",
|
||||
CheckKind::ImportStarUsage(_) => "ImportStarUsage",
|
||||
CheckKind::LateFutureImport => "LateFutureImport",
|
||||
|
|
@ -269,6 +274,7 @@ impl CheckKind {
|
|||
CheckKind::FutureFeatureNotDefined(_) => &CheckCode::F407,
|
||||
CheckKind::IOError(_) => &CheckCode::E902,
|
||||
CheckKind::IfTuple => &CheckCode::F634,
|
||||
CheckKind::InvalidPrintSyntax => &CheckCode::F633,
|
||||
CheckKind::ImportStarNotPermitted(_) => &CheckCode::F406,
|
||||
CheckKind::ImportStarUsage(_) => &CheckCode::F403,
|
||||
CheckKind::LateFutureImport => &CheckCode::F404,
|
||||
|
|
@ -335,6 +341,7 @@ impl CheckKind {
|
|||
format!("No such file or directory: `{name}`")
|
||||
}
|
||||
CheckKind::IfTuple => "If test is a tuple, which is always `True`".to_string(),
|
||||
CheckKind::InvalidPrintSyntax => "use of >> is invalid with print function".to_string(),
|
||||
CheckKind::ImportStarNotPermitted(name) => {
|
||||
format!("`from {name} import *` only allowed at module level")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -851,6 +851,31 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f633() -> Result<()> {
|
||||
let mut actual = check_path(
|
||||
Path::new("./resources/test/fixtures/F633.py"),
|
||||
&settings::Settings {
|
||||
line_length: 88,
|
||||
exclude: vec![],
|
||||
select: BTreeSet::from([CheckCode::F633]),
|
||||
},
|
||||
&fixer::Mode::Generate,
|
||||
)?;
|
||||
actual.sort_by_key(|check| check.location);
|
||||
let expected = vec![Check {
|
||||
kind: CheckKind::InvalidPrintSyntax,
|
||||
location: Location::new(4, 1),
|
||||
fix: None,
|
||||
}];
|
||||
assert_eq!(actual.len(), expected.len());
|
||||
for i in 0..actual.len() {
|
||||
assert_eq!(actual[i], expected[i]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f634() -> Result<()> {
|
||||
let mut actual = check_path(
|
||||
|
|
|
|||
Loading…
Reference in New Issue