Compare commits
7 Commits
cjm/subscr
...
dhruv/redi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37c856cbc1 | ||
|
|
b8c3dfab4e | ||
|
|
25efb820e6 | ||
|
|
9348821e77 | ||
|
|
7096340c70 | ||
|
|
ab9b050ecd | ||
|
|
5232835a40 |
17
Cargo.lock
generated
17
Cargo.lock
generated
@@ -754,6 +754,17 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "etcetera"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"home",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.12"
|
||||
@@ -2493,7 +2504,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"colored",
|
||||
"dirs 5.0.1",
|
||||
"etcetera",
|
||||
"glob",
|
||||
"globset",
|
||||
"ignore",
|
||||
@@ -3248,9 +3259,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_names2"
|
||||
|
||||
@@ -58,9 +58,9 @@ countme = { version = "3.0.1" }
|
||||
criterion = { version = "0.5.1", default-features = false }
|
||||
crossbeam = { version = "0.8.4" }
|
||||
dashmap = { version = "5.5.3" }
|
||||
dirs = { version = "5.0.0" }
|
||||
drop_bomb = { version = "0.1.5" }
|
||||
env_logger = { version = "0.11.0" }
|
||||
etcetera = { version = "0.8.0" }
|
||||
fern = { version = "0.6.1" }
|
||||
filetime = { version = "0.2.23" }
|
||||
glob = { version = "0.3.1" }
|
||||
|
||||
@@ -18,8 +18,8 @@ use ruff_linter::line_width::LineLength;
|
||||
use ruff_linter::logging::LogLevel;
|
||||
use ruff_linter::registry::Rule;
|
||||
use ruff_linter::settings::types::{
|
||||
ExtensionPair, FilePattern, PatternPrefixPair, PerFileIgnore, PreviewMode, PythonVersion,
|
||||
SerializationFormat, UnsafeFixes,
|
||||
ExtensionPair, FilePattern, OutputFormat, PatternPrefixPair, PerFileIgnore, PreviewMode,
|
||||
PythonVersion, UnsafeFixes,
|
||||
};
|
||||
use ruff_linter::{warn_user, RuleParser, RuleSelector, RuleSelectorParser};
|
||||
use ruff_source_file::{LineIndex, OneIndexed};
|
||||
@@ -160,13 +160,6 @@ pub struct CheckCommand {
|
||||
unsafe_fixes: bool,
|
||||
#[arg(long, overrides_with("unsafe_fixes"), hide = true)]
|
||||
no_unsafe_fixes: bool,
|
||||
/// Show violations with source code.
|
||||
/// Use `--no-show-source` to disable.
|
||||
/// (Deprecated: use `--output-format=full` or `--output-format=concise` instead of `--show-source` and `--no-show-source`, respectively)
|
||||
#[arg(long, overrides_with("no_show_source"))]
|
||||
show_source: bool,
|
||||
#[clap(long, overrides_with("show_source"), hide = true)]
|
||||
no_show_source: bool,
|
||||
/// Show an enumeration of all fixed lint violations.
|
||||
/// Use `--no-show-fixes` to disable.
|
||||
#[arg(long, overrides_with("no_show_fixes"))]
|
||||
@@ -194,7 +187,7 @@ pub struct CheckCommand {
|
||||
/// The default serialization format is "concise".
|
||||
/// In preview mode, the default serialization format is "full".
|
||||
#[arg(long, value_enum, env = "RUFF_OUTPUT_FORMAT")]
|
||||
pub output_format: Option<SerializationFormat>,
|
||||
pub output_format: Option<OutputFormat>,
|
||||
|
||||
/// Specify file to write the linter output to (default: stdout).
|
||||
#[arg(short, long, env = "RUFF_OUTPUT_FILE")]
|
||||
@@ -365,7 +358,6 @@ pub struct CheckCommand {
|
||||
long,
|
||||
// Unsupported default-command arguments.
|
||||
conflicts_with = "diff",
|
||||
conflicts_with = "show_source",
|
||||
conflicts_with = "watch",
|
||||
)]
|
||||
pub statistics: bool,
|
||||
@@ -703,7 +695,6 @@ impl CheckCommand {
|
||||
force_exclude: resolve_bool_arg(self.force_exclude, self.no_force_exclude),
|
||||
output_format: resolve_output_format(
|
||||
self.output_format,
|
||||
resolve_bool_arg(self.show_source, self.no_show_source),
|
||||
resolve_bool_arg(self.preview, self.no_preview).unwrap_or_default(),
|
||||
),
|
||||
show_fixes: resolve_bool_arg(self.show_fixes, self.no_show_fixes),
|
||||
@@ -934,37 +925,16 @@ The path `{value}` does not point to a configuration file"
|
||||
}
|
||||
|
||||
fn resolve_output_format(
|
||||
output_format: Option<SerializationFormat>,
|
||||
show_sources: Option<bool>,
|
||||
output_format: Option<OutputFormat>,
|
||||
preview: bool,
|
||||
) -> Option<SerializationFormat> {
|
||||
Some(match (output_format, show_sources) {
|
||||
(Some(o), None) => o,
|
||||
(Some(SerializationFormat::Grouped), Some(true)) => {
|
||||
warn_user!("`--show-source` with `--output-format=grouped` is deprecated, and will not show source files. Use `--output-format=full` to show source information.");
|
||||
SerializationFormat::Grouped
|
||||
}
|
||||
(Some(fmt), Some(true)) => {
|
||||
warn_user!("The `--show-source` argument is deprecated and has been ignored in favor of `--output-format={fmt}`.");
|
||||
fmt
|
||||
}
|
||||
(Some(fmt), Some(false)) => {
|
||||
warn_user!("The `--no-show-source` argument is deprecated and has been ignored in favor of `--output-format={fmt}`.");
|
||||
fmt
|
||||
}
|
||||
(None, Some(true)) => {
|
||||
warn_user!("The `--show-source` argument is deprecated. Use `--output-format=full` instead.");
|
||||
SerializationFormat::Full
|
||||
}
|
||||
(None, Some(false)) => {
|
||||
warn_user!("The `--no-show-source` argument is deprecated. Use `--output-format=concise` instead.");
|
||||
SerializationFormat::Concise
|
||||
}
|
||||
(None, None) => return None
|
||||
) -> Option<OutputFormat> {
|
||||
Some(match output_format {
|
||||
Some(o) => o,
|
||||
None => return None
|
||||
}).map(|format| match format {
|
||||
SerializationFormat::Text => {
|
||||
warn_user!("`--output-format=text` is deprecated. Use `--output-format=full` or `--output-format=concise` instead. `text` will be treated as `{}`.", SerializationFormat::default(preview));
|
||||
SerializationFormat::default(preview)
|
||||
OutputFormat::Text => {
|
||||
warn_user!("`--output-format=text` is deprecated. Use `--output-format=full` or `--output-format=concise` instead. `text` will be treated as `{}`.", OutputFormat::default(preview));
|
||||
OutputFormat::default(preview)
|
||||
},
|
||||
other => other
|
||||
})
|
||||
@@ -1219,7 +1189,7 @@ struct ExplicitConfigOverrides {
|
||||
fix_only: Option<bool>,
|
||||
unsafe_fixes: Option<UnsafeFixes>,
|
||||
force_exclude: Option<bool>,
|
||||
output_format: Option<SerializationFormat>,
|
||||
output_format: Option<OutputFormat>,
|
||||
show_fixes: Option<bool>,
|
||||
extension: Option<Vec<ExtensionPair>>,
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ impl<'a> Explanation<'a> {
|
||||
message_formats: rule.message_formats(),
|
||||
fix,
|
||||
explanation: rule.explanation(),
|
||||
preview: rule.is_preview() || rule.is_nursery(),
|
||||
preview: rule.is_preview(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ fn format_rule_text(rule: Rule) -> String {
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
if rule.is_preview() || rule.is_nursery() {
|
||||
if rule.is_preview() {
|
||||
output.push_str(
|
||||
r"This rule is in preview and is not stable. The `--preview` flag is required for use.",
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ use notify::{recommended_watcher, RecursiveMode, Watcher};
|
||||
|
||||
use ruff_linter::logging::{set_up_logging, LogLevel};
|
||||
use ruff_linter::settings::flags::FixMode;
|
||||
use ruff_linter::settings::types::SerializationFormat;
|
||||
use ruff_linter::settings::types::OutputFormat;
|
||||
use ruff_linter::{fs, warn_user, warn_user_once};
|
||||
use ruff_workspace::Settings;
|
||||
|
||||
@@ -351,10 +351,10 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
|
||||
let preview = pyproject_config.settings.linter.preview.is_enabled();
|
||||
|
||||
if cli.watch {
|
||||
if output_format != SerializationFormat::default(preview) {
|
||||
if output_format != OutputFormat::default(preview) {
|
||||
warn_user!(
|
||||
"`--output-format {}` is always used in watch mode.",
|
||||
SerializationFormat::default(preview)
|
||||
OutputFormat::default(preview)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ use ruff_linter::message::{
|
||||
use ruff_linter::notify_user;
|
||||
use ruff_linter::registry::{AsRule, Rule};
|
||||
use ruff_linter::settings::flags::{self};
|
||||
use ruff_linter::settings::types::{SerializationFormat, UnsafeFixes};
|
||||
use ruff_linter::settings::types::{OutputFormat, UnsafeFixes};
|
||||
|
||||
use crate::diagnostics::{Diagnostics, FixMap};
|
||||
|
||||
@@ -36,9 +36,9 @@ bitflags! {
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct ExpandedStatistics<'a> {
|
||||
struct ExpandedStatistics {
|
||||
code: SerializeRuleAsCode,
|
||||
message: &'a str,
|
||||
name: SerializeRuleAsTitle,
|
||||
count: usize,
|
||||
fixable: bool,
|
||||
}
|
||||
@@ -66,8 +66,31 @@ impl From<Rule> for SerializeRuleAsCode {
|
||||
}
|
||||
}
|
||||
|
||||
struct SerializeRuleAsTitle(Rule);
|
||||
|
||||
impl Serialize for SerializeRuleAsTitle {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.0.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SerializeRuleAsTitle {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rule> for SerializeRuleAsTitle {
|
||||
fn from(rule: Rule) -> Self {
|
||||
Self(rule)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Printer {
|
||||
format: SerializationFormat,
|
||||
format: OutputFormat,
|
||||
log_level: LogLevel,
|
||||
fix_mode: flags::FixMode,
|
||||
unsafe_fixes: UnsafeFixes,
|
||||
@@ -76,7 +99,7 @@ pub(crate) struct Printer {
|
||||
|
||||
impl Printer {
|
||||
pub(crate) const fn new(
|
||||
format: SerializationFormat,
|
||||
format: OutputFormat,
|
||||
log_level: LogLevel,
|
||||
fix_mode: flags::FixMode,
|
||||
unsafe_fixes: UnsafeFixes,
|
||||
@@ -219,10 +242,10 @@ impl Printer {
|
||||
if !self.flags.intersects(Flags::SHOW_VIOLATIONS) {
|
||||
if matches!(
|
||||
self.format,
|
||||
SerializationFormat::Text
|
||||
| SerializationFormat::Full
|
||||
| SerializationFormat::Concise
|
||||
| SerializationFormat::Grouped
|
||||
OutputFormat::Text
|
||||
| OutputFormat::Full
|
||||
| OutputFormat::Concise
|
||||
| OutputFormat::Grouped
|
||||
) {
|
||||
if self.flags.intersects(Flags::SHOW_FIX_SUMMARY) {
|
||||
if !diagnostics.fixed.is_empty() {
|
||||
@@ -240,24 +263,24 @@ impl Printer {
|
||||
let fixables = FixableStatistics::try_from(diagnostics, self.unsafe_fixes);
|
||||
|
||||
match self.format {
|
||||
SerializationFormat::Json => {
|
||||
OutputFormat::Json => {
|
||||
JsonEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Rdjson => {
|
||||
OutputFormat::Rdjson => {
|
||||
RdjsonEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::JsonLines => {
|
||||
OutputFormat::JsonLines => {
|
||||
JsonLinesEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Junit => {
|
||||
OutputFormat::Junit => {
|
||||
JunitEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Concise
|
||||
| SerializationFormat::Full => {
|
||||
OutputFormat::Concise
|
||||
| OutputFormat::Full => {
|
||||
TextEmitter::default()
|
||||
.with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref()))
|
||||
.with_show_fix_diff(self.flags.intersects(Flags::SHOW_FIX_DIFF))
|
||||
.with_show_source(self.format == SerializationFormat::Full)
|
||||
.with_show_source(self.format == OutputFormat::Full)
|
||||
.with_unsafe_fixes(self.unsafe_fixes)
|
||||
.emit(writer, &diagnostics.messages, &context)?;
|
||||
|
||||
@@ -271,7 +294,7 @@ impl Printer {
|
||||
|
||||
self.write_summary_text(writer, diagnostics)?;
|
||||
}
|
||||
SerializationFormat::Grouped => {
|
||||
OutputFormat::Grouped => {
|
||||
GroupedEmitter::default()
|
||||
.with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref()))
|
||||
.with_unsafe_fixes(self.unsafe_fixes)
|
||||
@@ -286,22 +309,22 @@ impl Printer {
|
||||
}
|
||||
self.write_summary_text(writer, diagnostics)?;
|
||||
}
|
||||
SerializationFormat::Github => {
|
||||
OutputFormat::Github => {
|
||||
GithubEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Gitlab => {
|
||||
OutputFormat::Gitlab => {
|
||||
GitlabEmitter::default().emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Pylint => {
|
||||
OutputFormat::Pylint => {
|
||||
PylintEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Azure => {
|
||||
OutputFormat::Azure => {
|
||||
AzureEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Sarif => {
|
||||
OutputFormat::Sarif => {
|
||||
SarifEmitter.emit(writer, &diagnostics.messages, &context)?;
|
||||
}
|
||||
SerializationFormat::Text => unreachable!("Text is deprecated and should have been automatically converted to the default serialization format")
|
||||
OutputFormat::Text => unreachable!("Text is deprecated and should have been automatically converted to the default serialization format")
|
||||
}
|
||||
|
||||
writer.flush()?;
|
||||
@@ -317,29 +340,23 @@ impl Printer {
|
||||
let statistics: Vec<ExpandedStatistics> = diagnostics
|
||||
.messages
|
||||
.iter()
|
||||
.map(|message| {
|
||||
(
|
||||
message.kind.rule(),
|
||||
&message.kind.body,
|
||||
message.fix.is_some(),
|
||||
)
|
||||
})
|
||||
.map(|message| (message.kind.rule(), message.fix.is_some()))
|
||||
.sorted()
|
||||
.fold(vec![], |mut acc, (rule, body, fixable)| {
|
||||
if let Some((prev_rule, _, _, count)) = acc.last_mut() {
|
||||
.fold(vec![], |mut acc, (rule, fixable)| {
|
||||
if let Some((prev_rule, _, count)) = acc.last_mut() {
|
||||
if *prev_rule == rule {
|
||||
*count += 1;
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
acc.push((rule, body, fixable, 1));
|
||||
acc.push((rule, fixable, 1));
|
||||
acc
|
||||
})
|
||||
.iter()
|
||||
.map(|(rule, message, fixable, count)| ExpandedStatistics {
|
||||
.map(|(rule, fixable, count)| ExpandedStatistics {
|
||||
code: (*rule).into(),
|
||||
name: (*rule).into(),
|
||||
count: *count,
|
||||
message,
|
||||
fixable: *fixable,
|
||||
})
|
||||
.sorted_by_key(|statistic| Reverse(statistic.count))
|
||||
@@ -350,9 +367,7 @@ impl Printer {
|
||||
}
|
||||
|
||||
match self.format {
|
||||
SerializationFormat::Text
|
||||
| SerializationFormat::Full
|
||||
| SerializationFormat::Concise => {
|
||||
OutputFormat::Text | OutputFormat::Full | OutputFormat::Concise => {
|
||||
// Compute the maximum number of digits in the count and code, for all messages,
|
||||
// to enable pretty-printing.
|
||||
let count_width = num_digits(
|
||||
@@ -388,12 +403,12 @@ impl Printer {
|
||||
} else {
|
||||
""
|
||||
},
|
||||
statistic.message,
|
||||
statistic.name,
|
||||
)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
SerializationFormat::Json => {
|
||||
OutputFormat::Json => {
|
||||
writeln!(writer, "{}", serde_json::to_string_pretty(&statistics)?)?;
|
||||
}
|
||||
_ => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! A test suite that ensures deprecated command line options have appropriate warnings / behaviors
|
||||
|
||||
use ruff_linter::settings::types::SerializationFormat;
|
||||
use ruff_linter::settings::types::OutputFormat;
|
||||
use std::process::Command;
|
||||
|
||||
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
|
||||
@@ -9,58 +9,21 @@ const BIN_NAME: &str = "ruff";
|
||||
|
||||
const STDIN: &str = "l = 1";
|
||||
|
||||
fn ruff_check(show_source: Option<bool>, output_format: Option<String>) -> Command {
|
||||
fn ruff_check(output_format: Option<String>) -> Command {
|
||||
let mut cmd = Command::new(get_cargo_bin(BIN_NAME));
|
||||
let output_format = output_format.unwrap_or(format!("{}", SerializationFormat::default(false)));
|
||||
let output_format = output_format.unwrap_or(format!("{}", OutputFormat::default(false)));
|
||||
cmd.arg("check")
|
||||
.arg("--output-format")
|
||||
.arg(output_format)
|
||||
.arg("--no-cache");
|
||||
match show_source {
|
||||
Some(true) => {
|
||||
cmd.arg("--show-source");
|
||||
}
|
||||
Some(false) => {
|
||||
cmd.arg("--no-show-source");
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
cmd.arg("-");
|
||||
|
||||
cmd
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_show_source_is_deprecated() {
|
||||
assert_cmd_snapshot!(ruff_check(Some(true), None).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: The `--show-source` argument is deprecated and has been ignored in favor of `--output-format=concise`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_no_show_source_is_deprecated() {
|
||||
assert_cmd_snapshot!(ruff_check(Some(false), None).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: The `--no-show-source` argument is deprecated and has been ignored in favor of `--output-format=concise`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_output_format_is_deprecated() {
|
||||
assert_cmd_snapshot!(ruff_check(None, Some("text".into())).pass_stdin(STDIN), @r###"
|
||||
assert_cmd_snapshot!(ruff_check(Some("text".into())).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
@@ -71,80 +34,3 @@ fn ensure_output_format_is_deprecated() {
|
||||
warning: `--output-format=text` is deprecated. Use `--output-format=full` or `--output-format=concise` instead. `text` will be treated as `concise`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_output_format_overrides_show_source() {
|
||||
assert_cmd_snapshot!(ruff_check(Some(true), Some("concise".into())).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: The `--show-source` argument is deprecated and has been ignored in favor of `--output-format=concise`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_full_output_format_overrides_no_show_source() {
|
||||
assert_cmd_snapshot!(ruff_check(Some(false), Some("full".into())).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
|
|
||||
1 | l = 1
|
||||
| ^ E741
|
||||
|
|
||||
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: The `--no-show-source` argument is deprecated and has been ignored in favor of `--output-format=full`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_output_format_uses_concise_over_no_show_source() {
|
||||
assert_cmd_snapshot!(ruff_check(Some(false), Some("concise".into())).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: The `--no-show-source` argument is deprecated and has been ignored in favor of `--output-format=concise`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_deprecated_output_format_overrides_show_source() {
|
||||
assert_cmd_snapshot!(ruff_check(Some(true), Some("text".into())).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: The `--show-source` argument is deprecated and has been ignored in favor of `--output-format=text`.
|
||||
warning: `--output-format=text` is deprecated. Use `--output-format=full` or `--output-format=concise` instead. `text` will be treated as `concise`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_deprecated_output_format_overrides_no_show_source() {
|
||||
assert_cmd_snapshot!(ruff_check(Some(false), Some("text".into())).pass_stdin(STDIN), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: E741 Ambiguous variable name: `l`
|
||||
Found 1 error.
|
||||
|
||||
----- stderr -----
|
||||
warning: The `--no-show-source` argument is deprecated and has been ignored in favor of `--output-format=text`.
|
||||
warning: `--output-format=text` is deprecated. Use `--output-format=full` or `--output-format=concise` instead. `text` will be treated as `concise`.
|
||||
"###);
|
||||
}
|
||||
|
||||
@@ -854,117 +854,41 @@ fn show_statistics() {
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
1 F401 [*] `sys` imported but unused
|
||||
1 F401 [*] unused-import
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_prefix() {
|
||||
// Should only detect RUF90X, but not the unstable test rules
|
||||
fn show_statistics_json() {
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "RUF9", "--output-format=concise"])
|
||||
.args([
|
||||
"--select",
|
||||
"F401",
|
||||
"--statistics",
|
||||
"--output-format",
|
||||
"json",
|
||||
])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
assert_cmd_snapshot!(cmd
|
||||
.pass_stdin("import sys\nimport os\n\nprint(os.getuid())\n"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: RUF900 Hey this is a stable test rule.
|
||||
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
|
||||
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
-:1:1: RUF921 Hey this is another deprecated test rule.
|
||||
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
|
||||
Found 7 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
[
|
||||
{
|
||||
"code": "F401",
|
||||
"name": "unused-import",
|
||||
"count": 1,
|
||||
"fixable": true
|
||||
}
|
||||
]
|
||||
|
||||
----- stderr -----
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_all() {
|
||||
// Should detect RUF90X, but not the unstable test rules
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "ALL", "--output-format=concise"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
-:1:1: D100 Missing docstring in public module
|
||||
-:1:1: RUF900 Hey this is a stable test rule.
|
||||
-:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix.
|
||||
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
-:1:1: RUF920 Hey this is a deprecated test rule.
|
||||
-:1:1: RUF921 Hey this is another deprecated test rule.
|
||||
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
|
||||
Found 8 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
|
||||
warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_direct() {
|
||||
// Should fail when a nursery rule is selected without the preview flag
|
||||
// Before Ruff v0.2.0 this would warn
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "RUF912", "--output-format=concise"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
ruff failed
|
||||
Cause: Selection of unstable rule `RUF912` without the `--preview` flag is not allowed.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_group_selector() {
|
||||
// The NURSERY selector is removed but parses in the CLI for a nicer error message
|
||||
// Before Ruff v0.2.0 this would warn
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "NURSERY", "--output-format=concise"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
ruff failed
|
||||
Cause: The `NURSERY` selector was removed. Use the `--preview` flag instead.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_group_selector_preview_enabled() {
|
||||
// When preview mode is enabled, we shouldn't suggest using the `--preview` flag.
|
||||
// Before Ruff v0.2.0 this would warn
|
||||
let mut cmd = RuffCheck::default()
|
||||
.args(["--select", "NURSERY", "--preview"])
|
||||
.build();
|
||||
assert_cmd_snapshot!(cmd, @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
ruff failed
|
||||
Cause: The `NURSERY` selector was removed. Unstable rules should be selected individually or by their respective groups.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preview_enabled_prefix() {
|
||||
// All the RUF9XX test rules should be triggered
|
||||
@@ -980,9 +904,8 @@ fn preview_enabled_prefix() {
|
||||
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
-:1:1: RUF911 Hey this is a preview test rule.
|
||||
-:1:1: RUF912 Hey this is a nursery test rule.
|
||||
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
|
||||
Found 7 errors.
|
||||
Found 6 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
@@ -1005,9 +928,8 @@ fn preview_enabled_all() {
|
||||
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
-:1:1: RUF911 Hey this is a preview test rule.
|
||||
-:1:1: RUF912 Hey this is a nursery test rule.
|
||||
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
|
||||
Found 9 errors.
|
||||
Found 8 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
@@ -1145,9 +1067,8 @@ fn preview_enabled_group_ignore() {
|
||||
-:1:1: RUF902 Hey this is a stable test rule with an unsafe fix.
|
||||
-:1:1: RUF903 Hey this is a stable test rule with a display only fix.
|
||||
-:1:1: RUF911 Hey this is a preview test rule.
|
||||
-:1:1: RUF912 Hey this is a nursery test rule.
|
||||
-:1:1: RUF950 Hey this is a test rule that was redirected from another.
|
||||
Found 7 errors.
|
||||
Found 6 errors.
|
||||
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
|
||||
|
||||
----- stderr -----
|
||||
|
||||
@@ -102,7 +102,6 @@ linter.rules.enabled = [
|
||||
percent-format-mixed-positional-and-named (F506),
|
||||
percent-format-positional-count-mismatch (F507),
|
||||
percent-format-star-requires-sequence (F508),
|
||||
percent-format-unsupported-format-character (F509),
|
||||
string-dot-format-invalid-format (F521),
|
||||
string-dot-format-extra-named-arguments (F522),
|
||||
string-dot-format-extra-positional-arguments (F523),
|
||||
@@ -164,7 +163,6 @@ linter.rules.should_fix = [
|
||||
percent-format-mixed-positional-and-named (F506),
|
||||
percent-format-positional-count-mismatch (F507),
|
||||
percent-format-star-requires-sequence (F508),
|
||||
percent-format-unsupported-format-character (F509),
|
||||
string-dot-format-invalid-format (F521),
|
||||
string-dot-format-extra-named-arguments (F522),
|
||||
string-dot-format-extra-positional-arguments (F523),
|
||||
|
||||
@@ -64,7 +64,7 @@ pub(crate) fn main(args: &Args) -> Result<()> {
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
if rule.is_preview() || rule.is_nursery() {
|
||||
if rule.is_preview() {
|
||||
output.push_str(
|
||||
r"This rule is unstable and in [preview](../preview.md). The `--preview` flag is required for use.",
|
||||
);
|
||||
|
||||
@@ -34,7 +34,7 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator<Item = Rule>,
|
||||
format!("<span title='Rule has been deprecated'>{WARNING_SYMBOL}</span>")
|
||||
}
|
||||
#[allow(deprecated)]
|
||||
RuleGroup::Preview | RuleGroup::Nursery => {
|
||||
RuleGroup::Preview => {
|
||||
format!("<span title='Rule is in preview'>{PREVIEW_SYMBOL}</span>")
|
||||
}
|
||||
RuleGroup::Stable => {
|
||||
|
||||
@@ -1098,17 +1098,10 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
||||
let location = expr.range();
|
||||
match pyflakes::cformat::CFormatSummary::try_from(value.to_str()) {
|
||||
Err(CFormatError {
|
||||
typ: CFormatErrorType::UnsupportedFormatChar(c),
|
||||
typ: CFormatErrorType::UnsupportedFormatChar(_),
|
||||
..
|
||||
}) => {
|
||||
if checker.enabled(Rule::PercentFormatUnsupportedFormatCharacter) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
pyflakes::rules::PercentFormatUnsupportedFormatCharacter {
|
||||
char: c,
|
||||
},
|
||||
location,
|
||||
));
|
||||
}
|
||||
// Unsupported format character violation is raised by `PLE1300`
|
||||
}
|
||||
Err(e) => {
|
||||
if checker.enabled(Rule::PercentFormatInvalidFormat) {
|
||||
|
||||
@@ -57,9 +57,6 @@ pub enum RuleGroup {
|
||||
Deprecated,
|
||||
/// The rule has been removed, errors will be displayed on use.
|
||||
Removed,
|
||||
/// Legacy category for unstable rules, supports backwards compatible selection.
|
||||
#[deprecated(note = "Use `RuleGroup::Preview` for new rules instead")]
|
||||
Nursery,
|
||||
}
|
||||
|
||||
#[ruff_macros::map_codes]
|
||||
@@ -71,72 +68,39 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
Some(match (linter, code) {
|
||||
// pycodestyle errors
|
||||
(Pycodestyle, "E101") => (RuleGroup::Stable, rules::pycodestyle::rules::MixedSpacesAndTabs),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E111") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultiple),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E113") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::UnexpectedIndentation),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E114") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultipleComment),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E115") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlockComment),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E116") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::UnexpectedIndentationComment),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E117") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::OverIndented),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E201") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceAfterOpenBracket),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E202") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeCloseBracket),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E203") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforePunctuation),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E211") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeParameters),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E221") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E222") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E223") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabBeforeOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E224") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabAfterOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E225") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E226") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundArithmeticOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E227") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundBitwiseOrShiftOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E228") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundModuloOperator),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E231") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespace),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E241") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterComma),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E242") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabAfterComma),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E251") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::UnexpectedSpacesAroundKeywordParameterEquals),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E252") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundParameterEquals),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E261") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TooFewSpacesBeforeInlineComment),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E262") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoSpaceAfterInlineComment),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E265") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoSpaceAfterBlockComment),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E266") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleLeadingHashesForBlockComment),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E271") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterKeyword),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E272") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeKeyword),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E273") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabAfterKeyword),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E274") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabBeforeKeyword),
|
||||
#[allow(deprecated)]
|
||||
(Pycodestyle, "E275") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAfterKeyword),
|
||||
(Pycodestyle, "E111") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultiple),
|
||||
(Pycodestyle, "E112") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),
|
||||
(Pycodestyle, "E113") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::UnexpectedIndentation),
|
||||
(Pycodestyle, "E114") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultipleComment),
|
||||
(Pycodestyle, "E115") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlockComment),
|
||||
(Pycodestyle, "E116") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::UnexpectedIndentationComment),
|
||||
(Pycodestyle, "E117") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::OverIndented),
|
||||
(Pycodestyle, "E201") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceAfterOpenBracket),
|
||||
(Pycodestyle, "E202") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeCloseBracket),
|
||||
(Pycodestyle, "E203") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceBeforePunctuation),
|
||||
(Pycodestyle, "E211") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeParameters),
|
||||
(Pycodestyle, "E221") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeOperator),
|
||||
(Pycodestyle, "E222") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterOperator),
|
||||
(Pycodestyle, "E223") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabBeforeOperator),
|
||||
(Pycodestyle, "E224") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabAfterOperator),
|
||||
(Pycodestyle, "E225") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundOperator),
|
||||
(Pycodestyle, "E226") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundArithmeticOperator),
|
||||
(Pycodestyle, "E227") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundBitwiseOrShiftOperator),
|
||||
(Pycodestyle, "E228") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundModuloOperator),
|
||||
(Pycodestyle, "E231") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespace),
|
||||
(Pycodestyle, "E241") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterComma),
|
||||
(Pycodestyle, "E242") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabAfterComma),
|
||||
(Pycodestyle, "E251") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::UnexpectedSpacesAroundKeywordParameterEquals),
|
||||
(Pycodestyle, "E252") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundParameterEquals),
|
||||
(Pycodestyle, "E261") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TooFewSpacesBeforeInlineComment),
|
||||
(Pycodestyle, "E262") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoSpaceAfterInlineComment),
|
||||
(Pycodestyle, "E265") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoSpaceAfterBlockComment),
|
||||
(Pycodestyle, "E266") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleLeadingHashesForBlockComment),
|
||||
(Pycodestyle, "E271") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterKeyword),
|
||||
(Pycodestyle, "E272") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeKeyword),
|
||||
(Pycodestyle, "E273") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabAfterKeyword),
|
||||
(Pycodestyle, "E274") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabBeforeKeyword),
|
||||
(Pycodestyle, "E275") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAfterKeyword),
|
||||
(Pycodestyle, "E301") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLineBetweenMethods),
|
||||
(Pycodestyle, "E302") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLinesTopLevel),
|
||||
(Pycodestyle, "E303") => (RuleGroup::Preview, rules::pycodestyle::rules::TooManyBlankLines),
|
||||
@@ -188,7 +152,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Pyflakes, "506") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatMixedPositionalAndNamed),
|
||||
(Pyflakes, "507") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatPositionalCountMismatch),
|
||||
(Pyflakes, "508") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatStarRequiresSequence),
|
||||
(Pyflakes, "509") => (RuleGroup::Stable, rules::pyflakes::rules::PercentFormatUnsupportedFormatCharacter),
|
||||
(Pyflakes, "509") => (RuleGroup::Removed, rules::pyflakes::rules::PercentFormatUnsupportedFormatCharacter),
|
||||
(Pyflakes, "521") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatInvalidFormat),
|
||||
(Pyflakes, "522") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatExtraNamedArguments),
|
||||
(Pyflakes, "523") => (RuleGroup::Stable, rules::pyflakes::rules::StringDotFormatExtraPositionalArguments),
|
||||
@@ -226,8 +190,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Pylint, "C0208") => (RuleGroup::Stable, rules::pylint::rules::IterationOverSet),
|
||||
(Pylint, "C0414") => (RuleGroup::Stable, rules::pylint::rules::UselessImportAlias),
|
||||
(Pylint, "C0415") => (RuleGroup::Preview, rules::pylint::rules::ImportOutsideTopLevel),
|
||||
#[allow(deprecated)]
|
||||
(Pylint, "C1901") => (RuleGroup::Nursery, rules::pylint::rules::CompareToEmptyString),
|
||||
(Pylint, "C1901") => (RuleGroup::Preview, rules::pylint::rules::CompareToEmptyString),
|
||||
(Pylint, "C2401") => (RuleGroup::Preview, rules::pylint::rules::NonAsciiName),
|
||||
(Pylint, "C2403") => (RuleGroup::Preview, rules::pylint::rules::NonAsciiImportName),
|
||||
(Pylint, "C2701") => (RuleGroup::Preview, rules::pylint::rules::ImportPrivateName),
|
||||
@@ -300,8 +263,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Pylint, "R5501") => (RuleGroup::Stable, rules::pylint::rules::CollapsibleElseIf),
|
||||
(Pylint, "R6104") => (RuleGroup::Preview, rules::pylint::rules::NonAugmentedAssignment),
|
||||
(Pylint, "R6201") => (RuleGroup::Preview, rules::pylint::rules::LiteralMembership),
|
||||
#[allow(deprecated)]
|
||||
(Pylint, "R6301") => (RuleGroup::Nursery, rules::pylint::rules::NoSelfUse),
|
||||
(Pylint, "R6301") => (RuleGroup::Preview, rules::pylint::rules::NoSelfUse),
|
||||
(Pylint, "W0108") => (RuleGroup::Preview, rules::pylint::rules::UnnecessaryLambda),
|
||||
(Pylint, "W0177") => (RuleGroup::Preview, rules::pylint::rules::NanComparison),
|
||||
(Pylint, "W0120") => (RuleGroup::Stable, rules::pylint::rules::UselessElseOnLoop),
|
||||
@@ -323,12 +285,10 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Pylint, "W1509") => (RuleGroup::Stable, rules::pylint::rules::SubprocessPopenPreexecFn),
|
||||
(Pylint, "W1510") => (RuleGroup::Stable, rules::pylint::rules::SubprocessRunWithoutCheck),
|
||||
(Pylint, "W1514") => (RuleGroup::Preview, rules::pylint::rules::UnspecifiedEncoding),
|
||||
#[allow(deprecated)]
|
||||
(Pylint, "W1641") => (RuleGroup::Nursery, rules::pylint::rules::EqWithoutHash),
|
||||
(Pylint, "W1641") => (RuleGroup::Preview, rules::pylint::rules::EqWithoutHash),
|
||||
(Pylint, "W2101") => (RuleGroup::Preview, rules::pylint::rules::UselessWithLock),
|
||||
(Pylint, "W2901") => (RuleGroup::Stable, rules::pylint::rules::RedefinedLoopName),
|
||||
#[allow(deprecated)]
|
||||
(Pylint, "W3201") => (RuleGroup::Nursery, rules::pylint::rules::BadDunderMethodName),
|
||||
(Pylint, "W3201") => (RuleGroup::Preview, rules::pylint::rules::BadDunderMethodName),
|
||||
(Pylint, "W3301") => (RuleGroup::Stable, rules::pylint::rules::NestedMinMax),
|
||||
|
||||
// flake8-async
|
||||
@@ -515,8 +475,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Flake8Simplify, "911") => (RuleGroup::Stable, rules::flake8_simplify::rules::ZipDictKeysAndValues),
|
||||
|
||||
// flake8-copyright
|
||||
#[allow(deprecated)]
|
||||
(Flake8Copyright, "001") => (RuleGroup::Nursery, rules::flake8_copyright::rules::MissingCopyrightNotice),
|
||||
(Flake8Copyright, "001") => (RuleGroup::Preview, rules::flake8_copyright::rules::MissingCopyrightNotice),
|
||||
|
||||
// pyupgrade
|
||||
(Pyupgrade, "001") => (RuleGroup::Stable, rules::pyupgrade::rules::UselessMetaclassType),
|
||||
@@ -992,9 +951,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
(Ruff, "911") => (RuleGroup::Preview, rules::ruff::rules::PreviewTestRule),
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
#[allow(deprecated)]
|
||||
(Ruff, "912") => (RuleGroup::Nursery, rules::ruff::rules::NurseryTestRule),
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
(Ruff, "920") => (RuleGroup::Deprecated, rules::ruff::rules::DeprecatedTestRule),
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
(Ruff, "921") => (RuleGroup::Deprecated, rules::ruff::rules::AnotherDeprecatedTestRule),
|
||||
@@ -1059,15 +1015,12 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
||||
(Refurb, "103") => (RuleGroup::Preview, rules::refurb::rules::WriteWholeFile),
|
||||
(Refurb, "105") => (RuleGroup::Preview, rules::refurb::rules::PrintEmptyString),
|
||||
(Refurb, "110") => (RuleGroup::Preview, rules::refurb::rules::IfExpInsteadOfOrOperator),
|
||||
#[allow(deprecated)]
|
||||
(Refurb, "113") => (RuleGroup::Nursery, rules::refurb::rules::RepeatedAppend),
|
||||
(Refurb, "113") => (RuleGroup::Preview, rules::refurb::rules::RepeatedAppend),
|
||||
(Refurb, "116") => (RuleGroup::Preview, rules::refurb::rules::FStringNumberFormat),
|
||||
(Refurb, "118") => (RuleGroup::Preview, rules::refurb::rules::ReimplementedOperator),
|
||||
(Refurb, "129") => (RuleGroup::Preview, rules::refurb::rules::ReadlinesInFor),
|
||||
#[allow(deprecated)]
|
||||
(Refurb, "131") => (RuleGroup::Nursery, rules::refurb::rules::DeleteFullSlice),
|
||||
#[allow(deprecated)]
|
||||
(Refurb, "132") => (RuleGroup::Nursery, rules::refurb::rules::CheckAndRemoveFromSet),
|
||||
(Refurb, "131") => (RuleGroup::Preview, rules::refurb::rules::DeleteFullSlice),
|
||||
(Refurb, "132") => (RuleGroup::Preview, rules::refurb::rules::CheckAndRemoveFromSet),
|
||||
(Refurb, "136") => (RuleGroup::Preview, rules::refurb::rules::IfExprMinMax),
|
||||
(Refurb, "140") => (RuleGroup::Preview, rules::refurb::rules::ReimplementedStarmap),
|
||||
(Refurb, "142") => (RuleGroup::Preview, rules::refurb::rules::ForLoopSetMutations),
|
||||
|
||||
@@ -244,9 +244,6 @@ pub fn check_path(
|
||||
Rule::StableTestRuleDisplayOnlyFix => {
|
||||
test_rules::StableTestRuleDisplayOnlyFix::diagnostic(locator, comment_ranges)
|
||||
}
|
||||
Rule::NurseryTestRule => {
|
||||
test_rules::NurseryTestRule::diagnostic(locator, comment_ranges)
|
||||
}
|
||||
Rule::PreviewTestRule => {
|
||||
test_rules::PreviewTestRule::diagnostic(locator, comment_ranges)
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ static REDIRECTS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||
("TRY200", "B904"),
|
||||
("PGH001", "S307"),
|
||||
("PGH002", "G010"),
|
||||
("F509", "PLE1300"),
|
||||
// Test redirect by exact code
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
("RUF940", "RUF950"),
|
||||
|
||||
@@ -15,9 +15,6 @@ use crate::settings::types::PreviewMode;
|
||||
pub enum RuleSelector {
|
||||
/// Select all rules (includes rules in preview if enabled)
|
||||
All,
|
||||
/// Legacy category to select all rules in the "nursery" which predated preview mode
|
||||
#[deprecated(note = "The nursery was replaced with 'preview mode' which has no selector")]
|
||||
Nursery,
|
||||
/// Legacy category to select both the `mccabe` and `flake8-comprehensions` linters
|
||||
/// via a single selector.
|
||||
C,
|
||||
@@ -65,8 +62,6 @@ impl FromStr for RuleSelector {
|
||||
// **Changes should be reflected in `parse_no_redirect` as well**
|
||||
match s {
|
||||
"ALL" => Ok(Self::All),
|
||||
#[allow(deprecated)]
|
||||
"NURSERY" => Ok(Self::Nursery),
|
||||
"C" => Ok(Self::C),
|
||||
"T" => Ok(Self::T),
|
||||
_ => {
|
||||
@@ -130,8 +125,6 @@ impl RuleSelector {
|
||||
pub fn prefix_and_code(&self) -> (&'static str, &'static str) {
|
||||
match self {
|
||||
RuleSelector::All => ("", "ALL"),
|
||||
#[allow(deprecated)]
|
||||
RuleSelector::Nursery => ("", "NURSERY"),
|
||||
RuleSelector::C => ("", "C"),
|
||||
RuleSelector::T => ("", "T"),
|
||||
RuleSelector::Prefix { prefix, .. } | RuleSelector::Rule { prefix, .. } => {
|
||||
@@ -191,10 +184,6 @@ impl RuleSelector {
|
||||
match self {
|
||||
RuleSelector::All => RuleSelectorIter::All(Rule::iter()),
|
||||
|
||||
#[allow(deprecated)]
|
||||
RuleSelector::Nursery => {
|
||||
RuleSelectorIter::Nursery(Rule::iter().filter(Rule::is_nursery))
|
||||
}
|
||||
RuleSelector::C => RuleSelectorIter::Chain(
|
||||
Linter::Flake8Comprehensions
|
||||
.rules()
|
||||
@@ -216,15 +205,11 @@ impl RuleSelector {
|
||||
pub fn rules<'a>(&'a self, preview: &PreviewOptions) -> impl Iterator<Item = Rule> + 'a {
|
||||
let preview_enabled = preview.mode.is_enabled();
|
||||
let preview_require_explicit = preview.require_explicit;
|
||||
#[allow(deprecated)]
|
||||
self.all_rules().filter(move |rule| {
|
||||
// Always include stable rules
|
||||
rule.is_stable()
|
||||
// Backwards compatibility allows selection of nursery rules by exact code or dedicated group
|
||||
|| ((self.is_exact() || matches!(self, RuleSelector::Nursery { .. })) && rule.is_nursery())
|
||||
// Enabling preview includes all preview or nursery rules unless explicit selection
|
||||
// is turned on
|
||||
|| ((rule.is_preview() || rule.is_nursery()) && preview_enabled && (self.is_exact() || !preview_require_explicit))
|
||||
// Enabling preview includes all preview rules unless explicit selection is turned on
|
||||
|| (rule.is_preview() && preview_enabled && (self.is_exact() || !preview_require_explicit))
|
||||
// Deprecated rules are excluded in preview mode unless explicitly selected
|
||||
|| (rule.is_deprecated() && (!preview_enabled || self.is_exact()))
|
||||
// Removed rules are included if explicitly selected but will error downstream
|
||||
@@ -240,7 +225,6 @@ impl RuleSelector {
|
||||
|
||||
pub enum RuleSelectorIter {
|
||||
All(RuleIter),
|
||||
Nursery(std::iter::Filter<RuleIter, fn(&Rule) -> bool>),
|
||||
Chain(std::iter::Chain<std::vec::IntoIter<Rule>, std::vec::IntoIter<Rule>>),
|
||||
Vec(std::vec::IntoIter<Rule>),
|
||||
}
|
||||
@@ -251,7 +235,6 @@ impl Iterator for RuleSelectorIter {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self {
|
||||
RuleSelectorIter::All(iter) => iter.next(),
|
||||
RuleSelectorIter::Nursery(iter) => iter.next(),
|
||||
RuleSelectorIter::Chain(iter) => iter.next(),
|
||||
RuleSelectorIter::Vec(iter) => iter.next(),
|
||||
}
|
||||
@@ -288,7 +271,7 @@ mod schema {
|
||||
instance_type: Some(InstanceType::String.into()),
|
||||
enum_values: Some(
|
||||
[
|
||||
// Include the non-standard "ALL" and "NURSERY" selectors.
|
||||
// Include the non-standard "ALL" selectors.
|
||||
"ALL".to_string(),
|
||||
// Include the legacy "C" and "T" selectors.
|
||||
"C".to_string(),
|
||||
@@ -345,8 +328,6 @@ impl RuleSelector {
|
||||
pub fn specificity(&self) -> Specificity {
|
||||
match self {
|
||||
RuleSelector::All => Specificity::All,
|
||||
#[allow(deprecated)]
|
||||
RuleSelector::Nursery => Specificity::All,
|
||||
RuleSelector::T => Specificity::LinterGroup,
|
||||
RuleSelector::C => Specificity::LinterGroup,
|
||||
RuleSelector::Linter(..) => Specificity::Linter,
|
||||
@@ -369,8 +350,6 @@ impl RuleSelector {
|
||||
// **Changes should be reflected in `from_str` as well**
|
||||
match s {
|
||||
"ALL" => Ok(Self::All),
|
||||
#[allow(deprecated)]
|
||||
"NURSERY" => Ok(Self::Nursery),
|
||||
"C" => Ok(Self::C),
|
||||
"T" => Ok(Self::T),
|
||||
_ => {
|
||||
|
||||
@@ -75,7 +75,6 @@ mod tests {
|
||||
#[test_case(Rule::PercentFormatMixedPositionalAndNamed, Path::new("F50x.py"))]
|
||||
#[test_case(Rule::PercentFormatPositionalCountMismatch, Path::new("F50x.py"))]
|
||||
#[test_case(Rule::PercentFormatStarRequiresSequence, Path::new("F50x.py"))]
|
||||
#[test_case(Rule::PercentFormatUnsupportedFormatCharacter, Path::new("F50x.py"))]
|
||||
#[test_case(Rule::StringDotFormatInvalidFormat, Path::new("F521.py"))]
|
||||
#[test_case(Rule::StringDotFormatExtraNamedArguments, Path::new("F522.py"))]
|
||||
#[test_case(Rule::StringDotFormatExtraPositionalArguments, Path::new("F523.py"))]
|
||||
|
||||
@@ -297,6 +297,10 @@ impl Violation for PercentFormatStarRequiresSequence {
|
||||
}
|
||||
}
|
||||
|
||||
/// ## Removed
|
||||
///
|
||||
/// This rule is a subset of [PLE1300] which should be used instead.
|
||||
///
|
||||
/// ## What it does
|
||||
/// Checks for `printf`-style format strings with invalid format characters.
|
||||
///
|
||||
@@ -317,11 +321,14 @@ impl Violation for PercentFormatStarRequiresSequence {
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `printf`-style String Formatting](https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting)
|
||||
///
|
||||
/// [PLE1300]: https://docs.astral.sh/ruff/rules/bad-string-format-character/
|
||||
#[violation]
|
||||
pub struct PercentFormatUnsupportedFormatCharacter {
|
||||
pub(crate) char: char,
|
||||
}
|
||||
|
||||
/// F509
|
||||
impl Violation for PercentFormatUnsupportedFormatCharacter {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
||||
---
|
||||
F50x.py:4:1: F509 `%`-format string has unsupported format character `j`
|
||||
|
|
||||
2 | '%s %(foo)s' % {'foo': 'bar'} # F506
|
||||
3 | '%(foo)s %s' % {'foo': 'bar'} # F506
|
||||
4 | '%j' % (1,) # F509
|
||||
| ^^^^^^^^^^^ F509
|
||||
5 | '%s %s' % (1,) # F507
|
||||
6 | '%s %s' % (1, 2, 3) # F507
|
||||
|
|
||||
|
||||
|
||||
@@ -22,10 +22,21 @@ use crate::checkers::ast::Checker;
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// # `z` is not a valid format type.
|
||||
/// print("%z" % "1")
|
||||
/// print("%z" % 1)
|
||||
///
|
||||
/// print("{:z}".format("1"))
|
||||
/// print("{:z}".format(1))
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// print("%d" % 1)
|
||||
///
|
||||
/// print("{:d}".format(1))
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `printf`-style String Formatting](https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting)
|
||||
/// - [Python documentation: `str.format`](https://docs.python.org/3/library/stdtypes.html#str.format)
|
||||
#[violation]
|
||||
pub struct BadStringFormatCharacter {
|
||||
format_char: char,
|
||||
|
||||
@@ -87,7 +87,7 @@ invalid_characters.py:52:60: PLE2515 [*] Invalid unescaped character zero-width-
|
||||
50 | zwsp_after_multibyte_character = "ಫ"
|
||||
51 | zwsp_after_multibyte_character = f"ಫ"
|
||||
52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
| PLE2515
|
||||
| PLE2515
|
||||
53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
|
|
||||
= help: Replace with escape sequence
|
||||
@@ -107,7 +107,7 @@ invalid_characters.py:52:61: PLE2515 [*] Invalid unescaped character zero-width-
|
||||
50 | zwsp_after_multibyte_character = "ಫ"
|
||||
51 | zwsp_after_multibyte_character = f"ಫ"
|
||||
52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
| PLE2515
|
||||
| PLE2515
|
||||
53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
|
|
||||
= help: Replace with escape sequence
|
||||
@@ -127,7 +127,7 @@ invalid_characters.py:53:61: PLE2515 [*] Invalid unescaped character zero-width-
|
||||
51 | zwsp_after_multibyte_character = f"ಫ"
|
||||
52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
| PLE2515
|
||||
| PLE2515
|
||||
54 |
|
||||
55 | nested_fstrings = f'␈{f'{f'␛'}'}'
|
||||
|
|
||||
@@ -148,7 +148,7 @@ invalid_characters.py:53:62: PLE2515 [*] Invalid unescaped character zero-width-
|
||||
51 | zwsp_after_multibyte_character = f"ಫ"
|
||||
52 | zwsp_after_multicharacter_grapheme_cluster = "ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
53 | zwsp_after_multicharacter_grapheme_cluster = f"ಫ್ರಾನ್ಸಿಸ್ಕೊ "
|
||||
| PLE2515
|
||||
| PLE2515
|
||||
54 |
|
||||
55 | nested_fstrings = f'␈{f'{f'␛'}'}'
|
||||
|
|
||||
|
||||
@@ -38,7 +38,6 @@ pub(crate) const TEST_RULES: &[Rule] = &[
|
||||
Rule::StableTestRuleUnsafeFix,
|
||||
Rule::StableTestRuleDisplayOnlyFix,
|
||||
Rule::PreviewTestRule,
|
||||
Rule::NurseryTestRule,
|
||||
Rule::DeprecatedTestRule,
|
||||
Rule::AnotherDeprecatedTestRule,
|
||||
Rule::RemovedTestRule,
|
||||
@@ -262,42 +261,6 @@ impl TestRule for PreviewTestRule {
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Fake rule for testing.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Tests must pass!
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// foo
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// bar
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct NurseryTestRule;
|
||||
|
||||
impl Violation for NurseryTestRule {
|
||||
const FIX_AVAILABILITY: FixAvailability = FixAvailability::None;
|
||||
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
format!("Hey this is a nursery test rule.")
|
||||
}
|
||||
}
|
||||
|
||||
impl TestRule for NurseryTestRule {
|
||||
fn diagnostic(_locator: &Locator, _comment_ranges: &CommentRanges) -> Option<Diagnostic> {
|
||||
Some(Diagnostic::new(
|
||||
NurseryTestRule,
|
||||
ruff_text_size::TextRange::default(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// ## What it does
|
||||
/// Fake rule for testing.
|
||||
///
|
||||
|
||||
@@ -504,7 +504,7 @@ impl FromIterator<ExtensionPair> for ExtensionMapping {
|
||||
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum SerializationFormat {
|
||||
pub enum OutputFormat {
|
||||
Text,
|
||||
Concise,
|
||||
Full,
|
||||
@@ -520,7 +520,7 @@ pub enum SerializationFormat {
|
||||
Sarif,
|
||||
}
|
||||
|
||||
impl Display for SerializationFormat {
|
||||
impl Display for OutputFormat {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Text => write!(f, "text"),
|
||||
@@ -540,7 +540,7 @@ impl Display for SerializationFormat {
|
||||
}
|
||||
}
|
||||
|
||||
impl SerializationFormat {
|
||||
impl OutputFormat {
|
||||
pub fn default(preview: bool) -> Self {
|
||||
if preview {
|
||||
Self::Full
|
||||
|
||||
@@ -11,7 +11,7 @@ use syn::{
|
||||
use crate::rule_code_prefix::{get_prefix_ident, intersection_all};
|
||||
|
||||
/// A rule entry in the big match statement such a
|
||||
/// `(Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),`
|
||||
/// `(Pycodestyle, "E112") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),`
|
||||
#[derive(Clone)]
|
||||
struct Rule {
|
||||
/// The actual name of the rule, e.g., `NoIndentedBlock`.
|
||||
@@ -20,7 +20,7 @@ struct Rule {
|
||||
linter: Ident,
|
||||
/// The code associated with the rule, e.g., `"E112"`.
|
||||
code: LitStr,
|
||||
/// The rule group identifier, e.g., `RuleGroup::Nursery`.
|
||||
/// The rule group identifier, e.g., `RuleGroup::Preview`.
|
||||
group: Path,
|
||||
/// The path to the struct implementing the rule, e.g.
|
||||
/// `rules::pycodestyle::rules::logical_lines::NoIndentedBlock`
|
||||
@@ -321,11 +321,6 @@ See also https://github.com/astral-sh/ruff/issues/2186.
|
||||
matches!(self.group(), RuleGroup::Stable)
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub fn is_nursery(&self) -> bool {
|
||||
matches!(self.group(), RuleGroup::Nursery)
|
||||
}
|
||||
|
||||
pub fn is_deprecated(&self) -> bool {
|
||||
matches!(self.group(), RuleGroup::Deprecated)
|
||||
}
|
||||
@@ -373,13 +368,13 @@ fn generate_iter_impl(
|
||||
|
||||
quote! {
|
||||
impl Linter {
|
||||
/// Rules not in the nursery.
|
||||
/// Rules not in the preview.
|
||||
pub fn rules(self: &Linter) -> ::std::vec::IntoIter<Rule> {
|
||||
match self {
|
||||
#linter_rules_match_arms
|
||||
}
|
||||
}
|
||||
/// All rules, including those in the nursery.
|
||||
/// All rules, including those in the preview.
|
||||
pub fn all_rules(self: &Linter) -> ::std::vec::IntoIter<Rule> {
|
||||
match self {
|
||||
#linter_all_rules_match_arms
|
||||
@@ -481,7 +476,7 @@ fn register_rules<'a>(input: impl Iterator<Item = &'a Rule>) -> TokenStream {
|
||||
}
|
||||
|
||||
impl Parse for Rule {
|
||||
/// Parses a match arm such as `(Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),`
|
||||
/// Parses a match arm such as `(Pycodestyle, "E112") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),`
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let attrs = Attribute::parse_outer(input)?;
|
||||
let pat_tuple;
|
||||
|
||||
@@ -101,7 +101,7 @@ fn format_rule_text(rule: Rule) -> String {
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
if rule.is_preview() || rule.is_nursery() {
|
||||
if rule.is_preview() {
|
||||
output.push_str(r"This rule is in preview and is not stable.");
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
@@ -23,7 +23,6 @@ ruff_macros = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
colored = { workspace = true }
|
||||
dirs = { workspace = true }
|
||||
ignore = { workspace = true }
|
||||
is-macro = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
@@ -42,6 +41,9 @@ shellexpand = { workspace = true }
|
||||
strum = { workspace = true }
|
||||
toml = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
etcetera = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# Enable test rules during development
|
||||
ruff_linter = { workspace = true, features = ["clap", "test-rules"] }
|
||||
|
||||
@@ -27,8 +27,8 @@ use ruff_linter::rules::pycodestyle;
|
||||
use ruff_linter::settings::fix_safety_table::FixSafetyTable;
|
||||
use ruff_linter::settings::rule_table::RuleTable;
|
||||
use ruff_linter::settings::types::{
|
||||
CompiledPerFileIgnoreList, ExtensionMapping, FilePattern, FilePatternSet, PerFileIgnore,
|
||||
PreviewMode, PythonVersion, RequiredVersion, SerializationFormat, UnsafeFixes,
|
||||
CompiledPerFileIgnoreList, ExtensionMapping, FilePattern, FilePatternSet, OutputFormat,
|
||||
PerFileIgnore, PreviewMode, PythonVersion, RequiredVersion, UnsafeFixes,
|
||||
};
|
||||
use ruff_linter::settings::{LinterSettings, DEFAULT_SELECTORS, DUMMY_VARIABLE_RGX, TASK_TAGS};
|
||||
use ruff_linter::{
|
||||
@@ -116,7 +116,7 @@ pub struct Configuration {
|
||||
pub fix: Option<bool>,
|
||||
pub fix_only: Option<bool>,
|
||||
pub unsafe_fixes: Option<UnsafeFixes>,
|
||||
pub output_format: Option<SerializationFormat>,
|
||||
pub output_format: Option<OutputFormat>,
|
||||
pub preview: Option<PreviewMode>,
|
||||
pub required_version: Option<RequiredVersion>,
|
||||
pub extension: Option<ExtensionMapping>,
|
||||
@@ -222,7 +222,7 @@ impl Configuration {
|
||||
unsafe_fixes: self.unsafe_fixes.unwrap_or_default(),
|
||||
output_format: self
|
||||
.output_format
|
||||
.unwrap_or_else(|| SerializationFormat::default(global_preview.is_enabled())),
|
||||
.unwrap_or_else(|| OutputFormat::default(global_preview.is_enabled())),
|
||||
show_fixes: self.show_fixes.unwrap_or(false),
|
||||
|
||||
file_resolver: FileResolverSettings {
|
||||
@@ -429,30 +429,16 @@ impl Configuration {
|
||||
options.indent_width.or(options.tab_size)
|
||||
};
|
||||
|
||||
#[allow(deprecated)]
|
||||
let output_format = {
|
||||
if options.show_source.is_some() {
|
||||
warn_user_once!(
|
||||
r#"The `show-source` option has been deprecated in favor of `output-format`'s "full" and "concise" variants. Please update your configuration to use `output-format = <full|concise>` instead."#
|
||||
);
|
||||
}
|
||||
|
||||
options
|
||||
.output_format
|
||||
.map(|format| match format {
|
||||
SerializationFormat::Text => {
|
||||
warn_user_once!(r#"Setting `output_format` to "text" is deprecated. Use "full" or "concise" instead. "text" will be treated as "{}"."#, SerializationFormat::default(options.preview.unwrap_or_default()));
|
||||
SerializationFormat::default(options.preview.unwrap_or_default())
|
||||
OutputFormat::Text => {
|
||||
warn_user_once!(r#"Setting `output_format` to "text" is deprecated. Use "full" or "concise" instead. "text" will be treated as "{}"."#, OutputFormat::default(options.preview.unwrap_or_default()));
|
||||
OutputFormat::default(options.preview.unwrap_or_default())
|
||||
},
|
||||
other => other
|
||||
})
|
||||
.or(options.show_source.map(|show_source| {
|
||||
if show_source {
|
||||
SerializationFormat::Full
|
||||
} else {
|
||||
SerializationFormat::Concise
|
||||
}
|
||||
}))
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
@@ -777,7 +763,6 @@ impl LintConfiguration {
|
||||
|
||||
// Store selectors for displaying warnings
|
||||
let mut redirects = FxHashMap::default();
|
||||
let mut deprecated_nursery_selectors = FxHashSet::default();
|
||||
let mut deprecated_selectors = FxHashSet::default();
|
||||
let mut removed_selectors = FxHashSet::default();
|
||||
let mut ignored_preview_selectors = FxHashSet::default();
|
||||
@@ -902,27 +887,11 @@ impl LintConfiguration {
|
||||
|
||||
// Check for selections that require a warning
|
||||
for (kind, selector) in selection.selectors_by_kind() {
|
||||
#[allow(deprecated)]
|
||||
if matches!(selector, RuleSelector::Nursery) {
|
||||
let suggestion = if preview.mode.is_disabled() {
|
||||
" Use the `--preview` flag instead."
|
||||
} else {
|
||||
" Unstable rules should be selected individually or by their respective groups."
|
||||
};
|
||||
return Err(anyhow!("The `NURSERY` selector was removed.{suggestion}"));
|
||||
};
|
||||
|
||||
// Some of these checks are only for `Kind::Enable` which means only `--select` will warn
|
||||
// and use with, e.g., `--ignore` or `--fixable` is okay
|
||||
|
||||
// Unstable rules
|
||||
if preview.mode.is_disabled() && kind.is_enable() {
|
||||
if selector.is_exact() {
|
||||
if selector.all_rules().all(|rule| rule.is_nursery()) {
|
||||
deprecated_nursery_selectors.insert(selector);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the selector is empty because preview mode is disabled
|
||||
if selector.rules(&preview).next().is_none()
|
||||
&& selector
|
||||
@@ -999,29 +968,6 @@ impl LintConfiguration {
|
||||
);
|
||||
}
|
||||
|
||||
let deprecated_nursery_selectors = deprecated_nursery_selectors
|
||||
.iter()
|
||||
.sorted()
|
||||
.collect::<Vec<_>>();
|
||||
match deprecated_nursery_selectors.as_slice() {
|
||||
[] => (),
|
||||
[selection] => {
|
||||
let (prefix, code) = selection.prefix_and_code();
|
||||
return Err(anyhow!("Selection of unstable rule `{prefix}{code}` without the `--preview` flag is not allowed."));
|
||||
}
|
||||
[..] => {
|
||||
let mut message = "Selection of unstable rules without the `--preview` flag is not allowed. Enable preview or remove selection of:".to_string();
|
||||
for selection in deprecated_nursery_selectors {
|
||||
let (prefix, code) = selection.prefix_and_code();
|
||||
message.push_str("\n\t- ");
|
||||
message.push_str(prefix);
|
||||
message.push_str(code);
|
||||
}
|
||||
message.push('\n');
|
||||
return Err(anyhow!(message));
|
||||
}
|
||||
}
|
||||
|
||||
if preview.mode.is_disabled() {
|
||||
for selection in deprecated_selectors.iter().sorted() {
|
||||
let (prefix, code) = selection.prefix_and_code();
|
||||
@@ -1896,64 +1842,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nursery_select_code() -> Result<()> {
|
||||
// We do not allow selection of nursery rules when preview is disabled
|
||||
assert!(resolve_rules(
|
||||
[RuleSelection {
|
||||
select: Some(vec![Flake8Copyright::_001.into()]),
|
||||
..RuleSelection::default()
|
||||
}],
|
||||
Some(PreviewOptions {
|
||||
mode: PreviewMode::Disabled,
|
||||
..PreviewOptions::default()
|
||||
}),
|
||||
)
|
||||
.is_err());
|
||||
|
||||
let actual = resolve_rules(
|
||||
[RuleSelection {
|
||||
select: Some(vec![Flake8Copyright::_001.into()]),
|
||||
..RuleSelection::default()
|
||||
}],
|
||||
Some(PreviewOptions {
|
||||
mode: PreviewMode::Enabled,
|
||||
..PreviewOptions::default()
|
||||
}),
|
||||
)?;
|
||||
let expected = RuleSet::from_rule(Rule::MissingCopyrightNotice);
|
||||
assert_eq!(actual, expected);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn select_nursery() {
|
||||
// We no longer allow use of the NURSERY selector and should error in both cases
|
||||
assert!(resolve_rules(
|
||||
[RuleSelection {
|
||||
select: Some(vec![RuleSelector::Nursery]),
|
||||
..RuleSelection::default()
|
||||
}],
|
||||
Some(PreviewOptions {
|
||||
mode: PreviewMode::Disabled,
|
||||
..PreviewOptions::default()
|
||||
}),
|
||||
)
|
||||
.is_err());
|
||||
assert!(resolve_rules(
|
||||
[RuleSelection {
|
||||
select: Some(vec![RuleSelector::Nursery]),
|
||||
..RuleSelection::default()
|
||||
}],
|
||||
Some(PreviewOptions {
|
||||
mode: PreviewMode::Enabled,
|
||||
..PreviewOptions::default()
|
||||
}),
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn select_docstring_convention_override() -> Result<()> {
|
||||
fn assert_override(
|
||||
|
||||
@@ -24,7 +24,7 @@ use ruff_linter::rules::{
|
||||
pycodestyle, pydocstyle, pyflakes, pylint, pyupgrade,
|
||||
};
|
||||
use ruff_linter::settings::types::{
|
||||
IdentifierPattern, PythonVersion, RequiredVersion, SerializationFormat,
|
||||
IdentifierPattern, OutputFormat, PythonVersion, RequiredVersion,
|
||||
};
|
||||
use ruff_linter::{warn_user_once, RuleSelector};
|
||||
use ruff_macros::{CombineOptions, OptionsMetadata};
|
||||
@@ -86,7 +86,7 @@ pub struct Options {
|
||||
output-format = "grouped"
|
||||
"#
|
||||
)]
|
||||
pub output_format: Option<SerializationFormat>,
|
||||
pub output_format: Option<OutputFormat>,
|
||||
|
||||
/// Enable fix behavior by-default when running `ruff` (overridden
|
||||
/// by the `--fix` and `--no-fix` command-line flags).
|
||||
@@ -108,21 +108,6 @@ pub struct Options {
|
||||
#[option(default = "false", value_type = "bool", example = "fix-only = true")]
|
||||
pub fix_only: Option<bool>,
|
||||
|
||||
/// Whether to show source code snippets when reporting lint violations
|
||||
/// (overridden by the `--show-source` command-line flag).
|
||||
#[option(
|
||||
default = "false",
|
||||
value_type = "bool",
|
||||
example = r#"
|
||||
# By default, always show source code snippets.
|
||||
show-source = true
|
||||
"#
|
||||
)]
|
||||
#[deprecated(
|
||||
note = "`show-source` is deprecated and is now part of `output-format` in the form of `full` or `concise` options. Please update your configuration."
|
||||
)]
|
||||
pub show_source: Option<bool>,
|
||||
|
||||
/// Whether to show an enumeration of all fixed lint violations
|
||||
/// (overridden by the `--show-fixes` command-line flag).
|
||||
#[option(
|
||||
|
||||
@@ -98,31 +98,44 @@ pub fn find_settings_toml<P: AsRef<Path>>(path: P) -> Result<Option<PathBuf>> {
|
||||
|
||||
/// Find the path to the user-specific `pyproject.toml` or `ruff.toml`, if it
|
||||
/// exists.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub fn find_user_settings_toml() -> Option<PathBuf> {
|
||||
// Search for a user-specific `.ruff.toml`.
|
||||
let mut path = dirs::config_dir()?;
|
||||
path.push("ruff");
|
||||
path.push(".ruff.toml");
|
||||
if path.is_file() {
|
||||
return Some(path);
|
||||
use etcetera::BaseStrategy;
|
||||
use ruff_linter::warn_user_once;
|
||||
|
||||
let strategy = etcetera::base_strategy::choose_base_strategy().ok()?;
|
||||
let config_dir = strategy.config_dir().join("ruff");
|
||||
|
||||
// Search for a user-specific `.ruff.toml`, then a `ruff.toml`, then a `pyproject.toml`.
|
||||
for filename in [".ruff.toml", "ruff.toml", "pyproject.toml"] {
|
||||
let path = config_dir.join(filename);
|
||||
if path.is_file() {
|
||||
return Some(path);
|
||||
}
|
||||
}
|
||||
|
||||
// Search for a user-specific `ruff.toml`.
|
||||
let mut path = dirs::config_dir()?;
|
||||
path.push("ruff");
|
||||
path.push("ruff.toml");
|
||||
if path.is_file() {
|
||||
return Some(path);
|
||||
// On macOS, we used to support reading from `/Users/Alice/Library/Application Support`.
|
||||
if cfg!(target_os = "macos") {
|
||||
let strategy = etcetera::base_strategy::Apple::new().ok()?;
|
||||
let deprecated_config_dir = strategy.data_dir().join("ruff");
|
||||
|
||||
for file in [".ruff.toml", "ruff.toml", "pyproject.toml"] {
|
||||
let path = deprecated_config_dir.join(file);
|
||||
if path.is_file() {
|
||||
warn_user_once!(
|
||||
"Reading configuration from `~/Library/Application Support` is deprecated. Please move your configuration to `{}/{file}`.",
|
||||
config_dir.display(),
|
||||
);
|
||||
return Some(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search for a user-specific `pyproject.toml`.
|
||||
let mut path = dirs::config_dir()?;
|
||||
path.push("ruff");
|
||||
path.push("pyproject.toml");
|
||||
if path.is_file() {
|
||||
return Some(path);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn find_user_settings_toml() -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use ruff_cache::cache_dir;
|
||||
use ruff_formatter::{FormatOptions, IndentStyle, IndentWidth, LineWidth};
|
||||
use ruff_linter::display_settings;
|
||||
use ruff_linter::settings::types::{
|
||||
ExtensionMapping, FilePattern, FilePatternSet, SerializationFormat, UnsafeFixes,
|
||||
ExtensionMapping, FilePattern, FilePatternSet, OutputFormat, UnsafeFixes,
|
||||
};
|
||||
use ruff_linter::settings::LinterSettings;
|
||||
use ruff_macros::CacheKey;
|
||||
@@ -28,7 +28,7 @@ pub struct Settings {
|
||||
#[cache_key(ignore)]
|
||||
pub unsafe_fixes: UnsafeFixes,
|
||||
#[cache_key(ignore)]
|
||||
pub output_format: SerializationFormat,
|
||||
pub output_format: OutputFormat,
|
||||
#[cache_key(ignore)]
|
||||
pub show_fixes: bool,
|
||||
|
||||
@@ -44,7 +44,7 @@ impl Default for Settings {
|
||||
cache_dir: cache_dir(project_root),
|
||||
fix: false,
|
||||
fix_only: false,
|
||||
output_format: SerializationFormat::default(false),
|
||||
output_format: OutputFormat::default(false),
|
||||
show_fixes: false,
|
||||
unsafe_fixes: UnsafeFixes::default(),
|
||||
linter: LinterSettings::new(project_root),
|
||||
|
||||
@@ -576,10 +576,6 @@ Options:
|
||||
--unsafe-fixes
|
||||
Include fixes that may not retain the original intent of the code.
|
||||
Use `--no-unsafe-fixes` to disable
|
||||
--show-source
|
||||
Show violations with source code. Use `--no-show-source` to disable.
|
||||
(Deprecated: use `--output-format=full` or `--output-format=concise`
|
||||
instead of `--show-source` and `--no-show-source`, respectively)
|
||||
--show-fixes
|
||||
Show an enumeration of all fixed lint violations. Use
|
||||
`--no-show-fixes` to disable
|
||||
|
||||
16
docs/faq.md
16
docs/faq.md
@@ -612,16 +612,20 @@ Ruff doesn't currently support INI files, like `setup.cfg` or `tox.ini`.
|
||||
|
||||
## How can I change Ruff's default configuration?
|
||||
|
||||
When no configuration file is found, Ruff will look for a user-specific `pyproject.toml` or
|
||||
`ruff.toml` file as a last resort. This behavior is similar to Flake8's `~/.config/flake8`.
|
||||
When no configuration file is found, Ruff will look for a user-specific `ruff.toml` file as a
|
||||
last resort. This behavior is similar to Flake8's `~/.config/flake8`.
|
||||
|
||||
On macOS, Ruff expects that file to be located at `/Users/Alice/Library/Application Support/ruff/ruff.toml`.
|
||||
On macOS and Linux, Ruff expects that file to be located at `~/.config/ruff/ruff.toml`,
|
||||
and respects the `XDG_CONFIG_HOME` specification.
|
||||
|
||||
On Linux, Ruff expects that file to be located at `/home/alice/.config/ruff/ruff.toml`.
|
||||
On Windows, Ruff expects that file to be located at `~\AppData\Roaming\ruff\ruff.toml`.
|
||||
|
||||
On Windows, Ruff expects that file to be located at `C:\Users\Alice\AppData\Roaming\ruff\ruff.toml`.
|
||||
!!! note
|
||||
Prior to `v0.5.0`, Ruff would read user-specific configuration from
|
||||
`~/Library/Application Support/ruff/ruff.toml` on macOS. While Ruff will still respect
|
||||
such configuration files, the use of `~/Library/ Application Support` is considered deprecated.
|
||||
|
||||
For more, see the [`dirs`](https://docs.rs/dirs/4.0.0/dirs/fn.config_dir.html) crate.
|
||||
For more, see the [`etcetera`](https://crates.io/crates/etcetera) crate.
|
||||
|
||||
## Ruff tried to fix something — but it broke my code. What's going on?
|
||||
|
||||
|
||||
47
ruff.schema.json
generated
47
ruff.schema.json
generated
@@ -534,7 +534,7 @@
|
||||
"description": "The style in which violation messages should be formatted: `\"full\"` (shows source),`\"concise\"` (default), `\"grouped\"` (group messages by file), `\"json\"` (machine-readable), `\"junit\"` (machine-readable XML), `\"github\"` (GitHub Actions annotations), `\"gitlab\"` (GitLab CI code quality report), `\"pylint\"` (Pylint text format) or `\"azure\"` (Azure Pipeline logging commands).",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SerializationFormat"
|
||||
"$ref": "#/definitions/OutputFormat"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
@@ -670,14 +670,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"show-source": {
|
||||
"description": "Whether to show source code snippets when reporting lint violations (overridden by the `--show-source` command-line flag).",
|
||||
"deprecated": true,
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"src": {
|
||||
"description": "The directories to consider when resolving first- vs. third-party imports.\n\nAs an example: given a Python package structure like:\n\n```text my_project ├── pyproject.toml └── src └── my_package ├── __init__.py ├── foo.py └── bar.py ```\n\nThe `./src` directory should be included in the `src` option (e.g., `src = [\"src\"]`), such that when resolving imports, `my_package.foo` is considered a first-party import.\n\nWhen omitted, the `src` directory will typically default to the directory containing the nearest `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file (the \"project root\"), unless a configuration file is explicitly provided (e.g., via the `--config` command-line flag).\n\nThis field supports globs. For example, if you have a series of Python packages in a `python_modules` directory, `src = [\"python_modules/*\"]` would expand to incorporate all of the packages in that directory. User home directory and environment variables will also be expanded.",
|
||||
"type": [
|
||||
@@ -2301,6 +2293,24 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OutputFormat": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"text",
|
||||
"concise",
|
||||
"full",
|
||||
"json",
|
||||
"json-lines",
|
||||
"junit",
|
||||
"grouped",
|
||||
"github",
|
||||
"gitlab",
|
||||
"pylint",
|
||||
"rdjson",
|
||||
"azure",
|
||||
"sarif"
|
||||
]
|
||||
},
|
||||
"ParametrizeNameType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -2978,7 +2988,6 @@
|
||||
"F506",
|
||||
"F507",
|
||||
"F508",
|
||||
"F509",
|
||||
"F52",
|
||||
"F521",
|
||||
"F522",
|
||||
@@ -3939,24 +3948,6 @@
|
||||
"YTT303"
|
||||
]
|
||||
},
|
||||
"SerializationFormat": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"text",
|
||||
"concise",
|
||||
"full",
|
||||
"json",
|
||||
"json-lines",
|
||||
"junit",
|
||||
"grouped",
|
||||
"github",
|
||||
"gitlab",
|
||||
"pylint",
|
||||
"rdjson",
|
||||
"azure",
|
||||
"sarif"
|
||||
]
|
||||
},
|
||||
"Strictness": {
|
||||
"oneOf": [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user