Unify OldDiagnostic and Message (#18391)
Some checks are pending
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions

Summary
--

This PR unifies the remaining differences between `OldDiagnostic` and
`Message` (`OldDiagnostic` was only missing an optional `noqa_offset`
field) and
replaces `Message` with `OldDiagnostic`.

The biggest functional difference is that the combined `OldDiagnostic`
kind no
longer implements `AsRule` for an infallible conversion to `Rule`. This
was
pretty easy to work around with `is_some_and` and `is_none_or` in the
few places
it was needed. In `LintContext::report_diagnostic_if_enabled` we can
just use
the new `Violation::rule` method, which takes care of most cases.

Most of the interesting changes are in [this
range](8156992540)
before I started renaming.

Test Plan
--

Existing tests

Future Work
--

I think it's time to start shifting some of these fields to the new
`Diagnostic`
kind. I believe we want `Fix` for sure, but I'm less sure about the
others. We
may want to keep a thin wrapper type here anyway to implement a `rule`
method,
so we could leave some of these fields on that too.
This commit is contained in:
Brent Westbrook 2025-06-19 09:37:58 -04:00 committed by GitHub
parent 4e83db4d40
commit 10a1d9f01e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
96 changed files with 902 additions and 914 deletions

View file

@ -19,7 +19,7 @@ use tempfile::NamedTempFile;
use ruff_cache::{CacheKey, CacheKeyHasher}; use ruff_cache::{CacheKey, CacheKeyHasher};
use ruff_diagnostics::Fix; use ruff_diagnostics::Fix;
use ruff_linter::message::Message; use ruff_linter::message::OldDiagnostic;
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::{VERSION, warn_user}; use ruff_linter::{VERSION, warn_user};
use ruff_macros::CacheKey; use ruff_macros::CacheKey;
@ -341,16 +341,16 @@ impl FileCache {
/// Convert the file cache into `Diagnostics`, using `path` as file name. /// Convert the file cache into `Diagnostics`, using `path` as file name.
pub(crate) fn to_diagnostics(&self, path: &Path) -> Option<Diagnostics> { pub(crate) fn to_diagnostics(&self, path: &Path) -> Option<Diagnostics> {
self.data.lint.as_ref().map(|lint| { self.data.lint.as_ref().map(|lint| {
let messages = if lint.messages.is_empty() { let diagnostics = if lint.messages.is_empty() {
Vec::new() Vec::new()
} else { } else {
let file = SourceFileBuilder::new(path.to_string_lossy(), &*lint.source).finish(); let file = SourceFileBuilder::new(path.to_string_lossy(), &*lint.source).finish();
lint.messages lint.messages
.iter() .iter()
.map(|msg| { .map(|msg| {
Message::diagnostic( OldDiagnostic::lint(
msg.body.clone(), &msg.body,
msg.suggestion.clone(), msg.suggestion.as_ref(),
msg.range, msg.range,
msg.fix.clone(), msg.fix.clone(),
msg.parent, msg.parent,
@ -366,7 +366,7 @@ impl FileCache {
} else { } else {
FxHashMap::default() FxHashMap::default()
}; };
Diagnostics::new(messages, notebook_indexes) Diagnostics::new(diagnostics, notebook_indexes)
}) })
} }
} }
@ -427,27 +427,27 @@ pub(crate) struct LintCacheData {
} }
impl LintCacheData { impl LintCacheData {
pub(crate) fn from_messages( pub(crate) fn from_diagnostics(
messages: &[Message], diagnostics: &[OldDiagnostic],
notebook_index: Option<NotebookIndex>, notebook_index: Option<NotebookIndex>,
) -> Self { ) -> Self {
let source = if let Some(msg) = messages.first() { let source = if let Some(msg) = diagnostics.first() {
msg.source_file().source_text().to_owned() msg.source_file().source_text().to_owned()
} else { } else {
String::new() // No messages, no need to keep the source! String::new() // No messages, no need to keep the source!
}; };
let messages = messages let messages = diagnostics
.iter() .iter()
// Parse the kebab-case rule name into a `Rule`. This will fail for syntax errors, so // Parse the kebab-case rule name into a `Rule`. This will fail for syntax errors, so
// this also serves to filter them out, but we shouldn't be caching files with syntax // this also serves to filter them out, but we shouldn't be caching files with syntax
// errors anyway. // errors anyway.
.filter_map(|msg| Some((msg.name().parse().ok()?, msg))) .filter_map(|msg| Some((msg.noqa_code().and_then(|code| code.rule())?, msg)))
.map(|(rule, msg)| { .map(|(rule, msg)| {
// Make sure that all message use the same source file. // Make sure that all message use the same source file.
assert_eq!( assert_eq!(
msg.source_file(), msg.source_file(),
messages.first().unwrap().source_file(), diagnostics.first().unwrap().source_file(),
"message uses a different source file" "message uses a different source file"
); );
CacheMessage { CacheMessage {
@ -612,7 +612,7 @@ mod tests {
use test_case::test_case; use test_case::test_case;
use ruff_cache::CACHE_DIR_NAME; use ruff_cache::CACHE_DIR_NAME;
use ruff_linter::message::Message; use ruff_linter::message::OldDiagnostic;
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::settings::flags; use ruff_linter::settings::flags;
use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::types::UnsafeFixes;
@ -680,7 +680,7 @@ mod tests {
UnsafeFixes::Enabled, UnsafeFixes::Enabled,
) )
.unwrap(); .unwrap();
if diagnostics.messages.iter().any(Message::is_syntax_error) { if diagnostics.inner.iter().any(OldDiagnostic::is_syntax_error) {
parse_errors.push(path.clone()); parse_errors.push(path.clone());
} }
paths.push(path); paths.push(path);

View file

@ -13,7 +13,6 @@ use rustc_hash::FxHashMap;
use ruff_db::panic::catch_unwind; use ruff_db::panic::catch_unwind;
use ruff_linter::OldDiagnostic; use ruff_linter::OldDiagnostic;
use ruff_linter::message::Message;
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::registry::Rule; use ruff_linter::registry::Rule;
use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::types::UnsafeFixes;
@ -130,9 +129,10 @@ pub(crate) fn check(
SourceFileBuilder::new(path.to_string_lossy().as_ref(), "").finish(); SourceFileBuilder::new(path.to_string_lossy().as_ref(), "").finish();
Diagnostics::new( Diagnostics::new(
vec![Message::from_diagnostic( vec![OldDiagnostic::new(
OldDiagnostic::new(IOError { message }, TextRange::default(), &dummy), IOError { message },
None, TextRange::default(),
&dummy,
)], )],
FxHashMap::default(), FxHashMap::default(),
) )
@ -166,7 +166,7 @@ pub(crate) fn check(
|a, b| (a.0 + b.0, a.1 + b.1), |a, b| (a.0 + b.0, a.1 + b.1),
); );
all_diagnostics.messages.sort(); all_diagnostics.inner.sort();
// Store the caches. // Store the caches.
caches.persist()?; caches.persist()?;
@ -283,7 +283,7 @@ mod test {
.with_show_fix_status(true) .with_show_fix_status(true)
.emit( .emit(
&mut output, &mut output,
&diagnostics.messages, &diagnostics.inner,
&EmitterContext::new(&FxHashMap::default()), &EmitterContext::new(&FxHashMap::default()),
) )
.unwrap(); .unwrap();

View file

@ -52,6 +52,6 @@ pub(crate) fn check_stdin(
noqa, noqa,
fix_mode, fix_mode,
)?; )?;
diagnostics.messages.sort_unstable(); diagnostics.inner.sort_unstable();
Ok(diagnostics) Ok(diagnostics)
} }

View file

@ -15,7 +15,6 @@ use rustc_hash::FxHashMap;
use ruff_linter::OldDiagnostic; use ruff_linter::OldDiagnostic;
use ruff_linter::codes::Rule; use ruff_linter::codes::Rule;
use ruff_linter::linter::{FixTable, FixerResult, LinterResult, ParseSource, lint_fix, lint_only}; use ruff_linter::linter::{FixTable, FixerResult, LinterResult, ParseSource, lint_fix, lint_only};
use ruff_linter::message::Message;
use ruff_linter::package::PackageRoot; use ruff_linter::package::PackageRoot;
use ruff_linter::pyproject_toml::lint_pyproject_toml; use ruff_linter::pyproject_toml::lint_pyproject_toml;
use ruff_linter::settings::types::UnsafeFixes; use ruff_linter::settings::types::UnsafeFixes;
@ -32,18 +31,18 @@ use crate::cache::{Cache, FileCacheKey, LintCacheData};
#[derive(Debug, Default, PartialEq)] #[derive(Debug, Default, PartialEq)]
pub(crate) struct Diagnostics { pub(crate) struct Diagnostics {
pub(crate) messages: Vec<Message>, pub(crate) inner: Vec<OldDiagnostic>,
pub(crate) fixed: FixMap, pub(crate) fixed: FixMap,
pub(crate) notebook_indexes: FxHashMap<String, NotebookIndex>, pub(crate) notebook_indexes: FxHashMap<String, NotebookIndex>,
} }
impl Diagnostics { impl Diagnostics {
pub(crate) fn new( pub(crate) fn new(
messages: Vec<Message>, diagnostics: Vec<OldDiagnostic>,
notebook_indexes: FxHashMap<String, NotebookIndex>, notebook_indexes: FxHashMap<String, NotebookIndex>,
) -> Self { ) -> Self {
Self { Self {
messages, inner: diagnostics,
fixed: FixMap::default(), fixed: FixMap::default(),
notebook_indexes, notebook_indexes,
} }
@ -63,15 +62,12 @@ impl Diagnostics {
let name = path.map_or_else(|| "-".into(), Path::to_string_lossy); let name = path.map_or_else(|| "-".into(), Path::to_string_lossy);
let source_file = SourceFileBuilder::new(name, "").finish(); let source_file = SourceFileBuilder::new(name, "").finish();
Self::new( Self::new(
vec![Message::from_diagnostic( vec![OldDiagnostic::new(
OldDiagnostic::new( IOError {
IOError { message: err.to_string(),
message: err.to_string(), },
}, TextRange::default(),
TextRange::default(), &source_file,
&source_file,
),
None,
)], )],
FxHashMap::default(), FxHashMap::default(),
) )
@ -102,7 +98,11 @@ impl Diagnostics {
let name = path.map_or_else(|| "-".into(), Path::to_string_lossy); let name = path.map_or_else(|| "-".into(), Path::to_string_lossy);
let dummy = SourceFileBuilder::new(name, "").finish(); let dummy = SourceFileBuilder::new(name, "").finish();
Self::new( Self::new(
vec![Message::syntax_error(err, TextRange::default(), dummy)], vec![OldDiagnostic::syntax_error(
err,
TextRange::default(),
dummy,
)],
FxHashMap::default(), FxHashMap::default(),
) )
} }
@ -121,7 +121,7 @@ impl Add for Diagnostics {
impl AddAssign for Diagnostics { impl AddAssign for Diagnostics {
fn add_assign(&mut self, other: Self) { fn add_assign(&mut self, other: Self) {
self.messages.extend(other.messages); self.inner.extend(other.inner);
self.fixed += other.fixed; self.fixed += other.fixed;
self.notebook_indexes.extend(other.notebook_indexes); self.notebook_indexes.extend(other.notebook_indexes);
} }
@ -202,7 +202,7 @@ pub(crate) fn lint_path(
if match fix_mode { if match fix_mode {
flags::FixMode::Generate => true, flags::FixMode::Generate => true,
flags::FixMode::Apply | flags::FixMode::Diff => { flags::FixMode::Apply | flags::FixMode::Diff => {
diagnostics.messages.is_empty() && diagnostics.fixed.is_empty() diagnostics.inner.is_empty() && diagnostics.fixed.is_empty()
} }
} { } {
return Ok(diagnostics); return Ok(diagnostics);
@ -222,7 +222,7 @@ pub(crate) fn lint_path(
Some(source_type) => source_type, Some(source_type) => source_type,
None => match SourceType::from(path) { None => match SourceType::from(path) {
SourceType::Toml(TomlSourceType::Pyproject) => { SourceType::Toml(TomlSourceType::Pyproject) => {
let messages = if settings let diagnostics = if settings
.rules .rules
.iter_enabled() .iter_enabled()
.any(|rule_code| rule_code.lint_source().is_pyproject_toml()) .any(|rule_code| rule_code.lint_source().is_pyproject_toml())
@ -240,7 +240,7 @@ pub(crate) fn lint_path(
vec![] vec![]
}; };
return Ok(Diagnostics { return Ok(Diagnostics {
messages, inner: diagnostics,
..Diagnostics::default() ..Diagnostics::default()
}); });
} }
@ -324,7 +324,7 @@ pub(crate) fn lint_path(
}; };
let has_error = result.has_syntax_errors(); let has_error = result.has_syntax_errors();
let messages = result.messages; let diagnostics = result.diagnostics;
if let Some((cache, relative_path, key)) = caching { if let Some((cache, relative_path, key)) = caching {
// We don't cache parsing errors. // We don't cache parsing errors.
@ -335,14 +335,14 @@ pub(crate) fn lint_path(
if match fix_mode { if match fix_mode {
flags::FixMode::Generate => true, flags::FixMode::Generate => true,
flags::FixMode::Apply | flags::FixMode::Diff => { flags::FixMode::Apply | flags::FixMode::Diff => {
messages.is_empty() && fixed.is_empty() diagnostics.is_empty() && fixed.is_empty()
} }
} { } {
cache.update_lint( cache.update_lint(
relative_path.to_owned(), relative_path.to_owned(),
&key, &key,
LintCacheData::from_messages( LintCacheData::from_diagnostics(
&messages, &diagnostics,
transformed.as_ipy_notebook().map(Notebook::index).cloned(), transformed.as_ipy_notebook().map(Notebook::index).cloned(),
), ),
); );
@ -357,7 +357,7 @@ pub(crate) fn lint_path(
}; };
Ok(Diagnostics { Ok(Diagnostics {
messages, inner: diagnostics,
fixed: FixMap::from_iter([(fs::relativize_path(path), fixed)]), fixed: FixMap::from_iter([(fs::relativize_path(path), fixed)]),
notebook_indexes, notebook_indexes,
}) })
@ -396,7 +396,7 @@ pub(crate) fn lint_stdin(
} }
return Ok(Diagnostics { return Ok(Diagnostics {
messages: lint_pyproject_toml(&source_file, &settings.linter), inner: lint_pyproject_toml(&source_file, &settings.linter),
fixed: FixMap::from_iter([(fs::relativize_path(path), FixTable::default())]), fixed: FixMap::from_iter([(fs::relativize_path(path), FixTable::default())]),
notebook_indexes: FxHashMap::default(), notebook_indexes: FxHashMap::default(),
}); });
@ -417,7 +417,7 @@ pub(crate) fn lint_stdin(
}; };
// Lint the inputs. // Lint the inputs.
let (LinterResult { messages, .. }, transformed, fixed) = let (LinterResult { diagnostics, .. }, transformed, fixed) =
if matches!(fix_mode, flags::FixMode::Apply | flags::FixMode::Diff) { if matches!(fix_mode, flags::FixMode::Apply | flags::FixMode::Diff) {
if let Ok(FixerResult { if let Ok(FixerResult {
result, result,
@ -501,7 +501,7 @@ pub(crate) fn lint_stdin(
}; };
Ok(Diagnostics { Ok(Diagnostics {
messages, inner: diagnostics,
fixed: FixMap::from_iter([( fixed: FixMap::from_iter([(
fs::relativize_path(path.unwrap_or_else(|| Path::new("-"))), fs::relativize_path(path.unwrap_or_else(|| Path::new("-"))),
fixed, fixed,

View file

@ -363,7 +363,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
Printer::clear_screen()?; Printer::clear_screen()?;
printer.write_to_user("Starting linter in watch mode...\n"); printer.write_to_user("Starting linter in watch mode...\n");
let messages = commands::check::check( let diagnostics = commands::check::check(
&files, &files,
&pyproject_config, &pyproject_config,
&config_arguments, &config_arguments,
@ -372,7 +372,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
fix_mode, fix_mode,
unsafe_fixes, unsafe_fixes,
)?; )?;
printer.write_continuously(&mut writer, &messages, preview)?; printer.write_continuously(&mut writer, &diagnostics, preview)?;
// In watch mode, we may need to re-resolve the configuration. // In watch mode, we may need to re-resolve the configuration.
// TODO(charlie): Re-compute other derivative values, like the `printer`. // TODO(charlie): Re-compute other derivative values, like the `printer`.
@ -392,7 +392,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
Printer::clear_screen()?; Printer::clear_screen()?;
printer.write_to_user("File change detected...\n"); printer.write_to_user("File change detected...\n");
let messages = commands::check::check( let diagnostics = commands::check::check(
&files, &files,
&pyproject_config, &pyproject_config,
&config_arguments, &config_arguments,
@ -401,7 +401,7 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
fix_mode, fix_mode,
unsafe_fixes, unsafe_fixes,
)?; )?;
printer.write_continuously(&mut writer, &messages, preview)?; printer.write_continuously(&mut writer, &diagnostics, preview)?;
} }
Err(err) => return Err(err.into()), Err(err) => return Err(err.into()),
} }
@ -463,11 +463,11 @@ pub fn check(args: CheckCommand, global_options: GlobalConfigArgs) -> Result<Exi
// there are any violations, unless we're explicitly asked to exit zero on // there are any violations, unless we're explicitly asked to exit zero on
// fix. // fix.
if cli.exit_non_zero_on_fix { if cli.exit_non_zero_on_fix {
if !diagnostics.fixed.is_empty() || !diagnostics.messages.is_empty() { if !diagnostics.fixed.is_empty() || !diagnostics.inner.is_empty() {
return Ok(ExitStatus::Failure); return Ok(ExitStatus::Failure);
} }
} else { } else {
if !diagnostics.messages.is_empty() { if !diagnostics.inner.is_empty() {
return Ok(ExitStatus::Failure); return Ok(ExitStatus::Failure);
} }
} }

View file

@ -14,7 +14,7 @@ use ruff_linter::fs::relativize_path;
use ruff_linter::logging::LogLevel; use ruff_linter::logging::LogLevel;
use ruff_linter::message::{ use ruff_linter::message::{
AzureEmitter, Emitter, EmitterContext, GithubEmitter, GitlabEmitter, GroupedEmitter, AzureEmitter, Emitter, EmitterContext, GithubEmitter, GitlabEmitter, GroupedEmitter,
JsonEmitter, JsonLinesEmitter, JunitEmitter, Message, PylintEmitter, RdjsonEmitter, JsonEmitter, JsonLinesEmitter, JunitEmitter, OldDiagnostic, PylintEmitter, RdjsonEmitter,
SarifEmitter, TextEmitter, SarifEmitter, TextEmitter,
}; };
use ruff_linter::notify_user; use ruff_linter::notify_user;
@ -85,7 +85,7 @@ impl Printer {
.sum::<usize>(); .sum::<usize>();
if self.flags.intersects(Flags::SHOW_VIOLATIONS) { if self.flags.intersects(Flags::SHOW_VIOLATIONS) {
let remaining = diagnostics.messages.len(); let remaining = diagnostics.inner.len();
let total = fixed + remaining; let total = fixed + remaining;
if fixed > 0 { if fixed > 0 {
let s = if total == 1 { "" } else { "s" }; let s = if total == 1 { "" } else { "s" };
@ -229,16 +229,16 @@ impl Printer {
match self.format { match self.format {
OutputFormat::Json => { OutputFormat::Json => {
JsonEmitter.emit(writer, &diagnostics.messages, &context)?; JsonEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::Rdjson => { OutputFormat::Rdjson => {
RdjsonEmitter.emit(writer, &diagnostics.messages, &context)?; RdjsonEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::JsonLines => { OutputFormat::JsonLines => {
JsonLinesEmitter.emit(writer, &diagnostics.messages, &context)?; JsonLinesEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::Junit => { OutputFormat::Junit => {
JunitEmitter.emit(writer, &diagnostics.messages, &context)?; JunitEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::Concise | OutputFormat::Full => { OutputFormat::Concise | OutputFormat::Full => {
TextEmitter::default() TextEmitter::default()
@ -246,7 +246,7 @@ impl Printer {
.with_show_fix_diff(self.flags.intersects(Flags::SHOW_FIX_DIFF)) .with_show_fix_diff(self.flags.intersects(Flags::SHOW_FIX_DIFF))
.with_show_source(self.format == OutputFormat::Full) .with_show_source(self.format == OutputFormat::Full)
.with_unsafe_fixes(self.unsafe_fixes) .with_unsafe_fixes(self.unsafe_fixes)
.emit(writer, &diagnostics.messages, &context)?; .emit(writer, &diagnostics.inner, &context)?;
if self.flags.intersects(Flags::SHOW_FIX_SUMMARY) { if self.flags.intersects(Flags::SHOW_FIX_SUMMARY) {
if !diagnostics.fixed.is_empty() { if !diagnostics.fixed.is_empty() {
@ -262,7 +262,7 @@ impl Printer {
GroupedEmitter::default() GroupedEmitter::default()
.with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref())) .with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref()))
.with_unsafe_fixes(self.unsafe_fixes) .with_unsafe_fixes(self.unsafe_fixes)
.emit(writer, &diagnostics.messages, &context)?; .emit(writer, &diagnostics.inner, &context)?;
if self.flags.intersects(Flags::SHOW_FIX_SUMMARY) { if self.flags.intersects(Flags::SHOW_FIX_SUMMARY) {
if !diagnostics.fixed.is_empty() { if !diagnostics.fixed.is_empty() {
@ -274,19 +274,19 @@ impl Printer {
self.write_summary_text(writer, diagnostics)?; self.write_summary_text(writer, diagnostics)?;
} }
OutputFormat::Github => { OutputFormat::Github => {
GithubEmitter.emit(writer, &diagnostics.messages, &context)?; GithubEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::Gitlab => { OutputFormat::Gitlab => {
GitlabEmitter::default().emit(writer, &diagnostics.messages, &context)?; GitlabEmitter::default().emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::Pylint => { OutputFormat::Pylint => {
PylintEmitter.emit(writer, &diagnostics.messages, &context)?; PylintEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::Azure => { OutputFormat::Azure => {
AzureEmitter.emit(writer, &diagnostics.messages, &context)?; AzureEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
OutputFormat::Sarif => { OutputFormat::Sarif => {
SarifEmitter.emit(writer, &diagnostics.messages, &context)?; SarifEmitter.emit(writer, &diagnostics.inner, &context)?;
} }
} }
@ -301,13 +301,13 @@ impl Printer {
writer: &mut dyn Write, writer: &mut dyn Write,
) -> Result<()> { ) -> Result<()> {
let statistics: Vec<ExpandedStatistics> = diagnostics let statistics: Vec<ExpandedStatistics> = diagnostics
.messages .inner
.iter() .iter()
.map(|message| (message.noqa_code(), message)) .map(|message| (message.noqa_code(), message))
.sorted_by_key(|(code, message)| (*code, message.fixable())) .sorted_by_key(|(code, message)| (*code, message.fixable()))
.fold( .fold(
vec![], vec![],
|mut acc: Vec<((Option<NoqaCode>, &Message), usize)>, (code, message)| { |mut acc: Vec<((Option<NoqaCode>, &OldDiagnostic), usize)>, (code, message)| {
if let Some(((prev_code, _prev_message), count)) = acc.last_mut() { if let Some(((prev_code, _prev_message), count)) = acc.last_mut() {
if *prev_code == code { if *prev_code == code {
*count += 1; *count += 1;
@ -416,20 +416,20 @@ impl Printer {
} }
if self.log_level >= LogLevel::Default { if self.log_level >= LogLevel::Default {
let s = if diagnostics.messages.len() == 1 { let s = if diagnostics.inner.len() == 1 {
"" ""
} else { } else {
"s" "s"
}; };
notify_user!( notify_user!(
"Found {} error{s}. Watching for file changes.", "Found {} error{s}. Watching for file changes.",
diagnostics.messages.len() diagnostics.inner.len()
); );
} }
let fixables = FixableStatistics::try_from(diagnostics, self.unsafe_fixes); let fixables = FixableStatistics::try_from(diagnostics, self.unsafe_fixes);
if !diagnostics.messages.is_empty() { if !diagnostics.inner.is_empty() {
if self.log_level >= LogLevel::Default { if self.log_level >= LogLevel::Default {
writeln!(writer)?; writeln!(writer)?;
} }
@ -439,7 +439,7 @@ impl Printer {
.with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref())) .with_show_fix_status(show_fix_status(self.fix_mode, fixables.as_ref()))
.with_show_source(preview) .with_show_source(preview)
.with_unsafe_fixes(self.unsafe_fixes) .with_unsafe_fixes(self.unsafe_fixes)
.emit(writer, &diagnostics.messages, &context)?; .emit(writer, &diagnostics.inner, &context)?;
} }
writer.flush()?; writer.flush()?;
@ -522,7 +522,7 @@ impl FixableStatistics {
let mut applicable = 0; let mut applicable = 0;
let mut inapplicable_unsafe = 0; let mut inapplicable_unsafe = 0;
for message in &diagnostics.messages { for message in &diagnostics.inner {
if let Some(fix) = message.fix() { if let Some(fix) = message.fix() {
if fix.applies(unsafe_fixes.required_applicability()) { if fix.applies(unsafe_fixes.required_applicability()) {
applicable += 1; applicable += 1;

View file

@ -66,7 +66,7 @@ use crate::importer::{ImportRequest, Importer, ResolutionError};
use crate::noqa::NoqaMapping; use crate::noqa::NoqaMapping;
use crate::package::PackageRoot; use crate::package::PackageRoot;
use crate::preview::is_undefined_export_in_dunder_init_enabled; use crate::preview::is_undefined_export_in_dunder_init_enabled;
use crate::registry::{AsRule, Rule}; use crate::registry::Rule;
use crate::rules::pyflakes::rules::{ use crate::rules::pyflakes::rules::{
LateFutureImport, ReturnOutsideFunction, YieldOutsideFunction, LateFutureImport, ReturnOutsideFunction, YieldOutsideFunction,
}; };
@ -3147,11 +3147,10 @@ impl<'a> LintContext<'a> {
kind: T, kind: T,
range: TextRange, range: TextRange,
) -> Option<DiagnosticGuard<'chk, 'a>> { ) -> Option<DiagnosticGuard<'chk, 'a>> {
let diagnostic = OldDiagnostic::new(kind, range, self.source_file); if self.settings.rules.enabled(T::rule()) {
if self.settings.rules.enabled(diagnostic.rule()) {
Some(DiagnosticGuard { Some(DiagnosticGuard {
context: self, context: self,
diagnostic: Some(diagnostic), diagnostic: Some(OldDiagnostic::new(kind, range, self.source_file)),
}) })
} else { } else {
None None

View file

@ -12,7 +12,7 @@ use crate::fix::edits::delete_comment;
use crate::noqa::{ use crate::noqa::{
Code, Directive, FileExemption, FileNoqaDirectives, NoqaDirectives, NoqaMapping, Code, Directive, FileExemption, FileNoqaDirectives, NoqaDirectives, NoqaMapping,
}; };
use crate::registry::{AsRule, Rule, RuleSet}; use crate::registry::{Rule, RuleSet};
use crate::rule_redirects::get_redirect_target; use crate::rule_redirects::get_redirect_target;
use crate::rules::pygrep_hooks; use crate::rules::pygrep_hooks;
use crate::rules::ruff; use crate::rules::ruff;
@ -47,14 +47,15 @@ pub(crate) fn check_noqa(
// Remove any ignored diagnostics. // Remove any ignored diagnostics.
'outer: for (index, diagnostic) in context.iter().enumerate() { 'outer: for (index, diagnostic) in context.iter().enumerate() {
let rule = diagnostic.rule(); // Can't ignore syntax errors.
let Some(code) = diagnostic.noqa_code() else {
continue;
};
if matches!(rule, Rule::BlanketNOQA) { if code == Rule::BlanketNOQA.noqa_code() {
continue; continue;
} }
let code = rule.noqa_code();
match &exemption { match &exemption {
FileExemption::All(_) => { FileExemption::All(_) => {
// If the file is exempted, ignore all diagnostics. // If the file is exempted, ignore all diagnostics.
@ -148,7 +149,9 @@ pub(crate) fn check_noqa(
if seen_codes.insert(original_code) { if seen_codes.insert(original_code) {
let is_code_used = if is_file_level { let is_code_used = if is_file_level {
context.iter().any(|diag| diag.rule().noqa_code() == code) context
.iter()
.any(|diag| diag.noqa_code().is_some_and(|noqa| noqa == code))
} else { } else {
matches.iter().any(|match_| *match_ == code) matches.iter().any(|match_| *match_ == code)
} || settings } || settings

View file

@ -1,104 +0,0 @@
use anyhow::Result;
use log::debug;
use ruff_source_file::SourceFile;
use ruff_text_size::{Ranged, TextRange, TextSize};
use crate::registry::AsRule;
use crate::violation::Violation;
use crate::{Fix, codes::Rule};
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct OldDiagnostic {
/// The message body to display to the user, to explain the diagnostic.
pub body: String,
/// The message to display to the user, to explain the suggested fix.
pub suggestion: Option<String>,
pub range: TextRange,
pub fix: Option<Fix>,
pub parent: Option<TextSize>,
pub(crate) rule: Rule,
pub(crate) file: SourceFile,
}
impl OldDiagnostic {
// TODO(brent) We temporarily allow this to avoid updating all of the call sites to add
// references. I expect this method to go away or change significantly with the rest of the
// diagnostic refactor, but if it still exists in this form at the end of the refactor, we
// should just update the call sites.
#[expect(clippy::needless_pass_by_value)]
pub fn new<T: Violation>(kind: T, range: TextRange, file: &SourceFile) -> Self {
Self {
body: Violation::message(&kind),
suggestion: Violation::fix_title(&kind),
range,
fix: None,
parent: None,
rule: T::rule(),
file: file.clone(),
}
}
/// Consumes `self` and returns a new `Diagnostic` with the given `fix`.
#[inline]
#[must_use]
pub fn with_fix(mut self, fix: Fix) -> Self {
self.set_fix(fix);
self
}
/// Set the [`Fix`] used to fix the diagnostic.
#[inline]
pub fn set_fix(&mut self, fix: Fix) {
self.fix = Some(fix);
}
/// Set the [`Fix`] used to fix the diagnostic, if the provided function returns `Ok`.
/// Otherwise, log the error.
#[inline]
pub fn try_set_fix(&mut self, func: impl FnOnce() -> Result<Fix>) {
match func() {
Ok(fix) => self.fix = Some(fix),
Err(err) => debug!("Failed to create fix for {}: {}", self.rule, err),
}
}
/// Set the [`Fix`] used to fix the diagnostic, if the provided function returns `Ok`.
/// Otherwise, log the error.
#[inline]
pub fn try_set_optional_fix(&mut self, func: impl FnOnce() -> Result<Option<Fix>>) {
match func() {
Ok(None) => {}
Ok(Some(fix)) => self.fix = Some(fix),
Err(err) => debug!("Failed to create fix for {}: {}", self.rule, err),
}
}
/// Consumes `self` and returns a new `Diagnostic` with the given parent node.
#[inline]
#[must_use]
pub fn with_parent(mut self, parent: TextSize) -> Self {
self.set_parent(parent);
self
}
/// Set the location of the diagnostic's parent node.
#[inline]
pub fn set_parent(&mut self, parent: TextSize) {
self.parent = Some(parent);
}
}
impl AsRule for OldDiagnostic {
fn rule(&self) -> Rule {
self.rule
}
}
impl Ranged for OldDiagnostic {
fn range(&self) -> TextRange {
self.range
}
}

View file

@ -608,7 +608,6 @@ mod tests {
use crate::fix::edits::{ use crate::fix::edits::{
add_to_dunder_all, make_redundant_alias, next_stmt_break, trailing_semicolon, add_to_dunder_all, make_redundant_alias, next_stmt_break, trailing_semicolon,
}; };
use crate::message::Message;
use crate::{Edit, Fix, Locator, OldDiagnostic}; use crate::{Edit, Fix, Locator, OldDiagnostic};
/// Parse the given source using [`Mode::Module`] and return the first statement. /// Parse the given source using [`Mode::Module`] and return the first statement.
@ -740,7 +739,7 @@ x = 1 \
let diag = { let diag = {
use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile; use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile;
let mut iter = edits.into_iter(); let mut iter = edits.into_iter();
let diag = OldDiagnostic::new( OldDiagnostic::new(
MissingNewlineAtEndOfFile, // The choice of rule here is arbitrary. MissingNewlineAtEndOfFile, // The choice of rule here is arbitrary.
TextRange::default(), TextRange::default(),
&SourceFileBuilder::new("<filename>", "<code>").finish(), &SourceFileBuilder::new("<filename>", "<code>").finish(),
@ -748,8 +747,7 @@ x = 1 \
.with_fix(Fix::safe_edits( .with_fix(Fix::safe_edits(
iter.next().ok_or(anyhow!("expected edits nonempty"))?, iter.next().ok_or(anyhow!("expected edits nonempty"))?,
iter, iter,
)); ))
Message::from_diagnostic(diag, None)
}; };
assert_eq!(apply_fixes([diag].iter(), &locator).code, expect); assert_eq!(apply_fixes([diag].iter(), &locator).code, expect);
Ok(()) Ok(())

View file

@ -8,7 +8,7 @@ use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use crate::Locator; use crate::Locator;
use crate::linter::FixTable; use crate::linter::FixTable;
use crate::message::Message; use crate::message::OldDiagnostic;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
use crate::{Edit, Fix}; use crate::{Edit, Fix};
@ -28,13 +28,13 @@ pub(crate) struct FixResult {
/// Fix errors in a file, and write the fixed source code to disk. /// Fix errors in a file, and write the fixed source code to disk.
pub(crate) fn fix_file( pub(crate) fn fix_file(
messages: &[Message], diagnostics: &[OldDiagnostic],
locator: &Locator, locator: &Locator,
unsafe_fixes: UnsafeFixes, unsafe_fixes: UnsafeFixes,
) -> Option<FixResult> { ) -> Option<FixResult> {
let required_applicability = unsafe_fixes.required_applicability(); let required_applicability = unsafe_fixes.required_applicability();
let mut with_fixes = messages let mut with_fixes = diagnostics
.iter() .iter()
.filter(|message| { .filter(|message| {
message message
@ -52,7 +52,7 @@ pub(crate) fn fix_file(
/// Apply a series of fixes. /// Apply a series of fixes.
fn apply_fixes<'a>( fn apply_fixes<'a>(
diagnostics: impl Iterator<Item = &'a Message>, diagnostics: impl Iterator<Item = &'a OldDiagnostic>,
locator: &'a Locator<'a>, locator: &'a Locator<'a>,
) -> FixResult { ) -> FixResult {
let mut output = String::with_capacity(locator.len()); let mut output = String::with_capacity(locator.len());
@ -173,9 +173,8 @@ mod tests {
use ruff_text_size::{Ranged, TextSize}; use ruff_text_size::{Ranged, TextSize};
use crate::Locator; use crate::Locator;
use crate::diagnostic::OldDiagnostic; use crate::OldDiagnostic;
use crate::fix::{FixResult, apply_fixes}; use crate::fix::{FixResult, apply_fixes};
use crate::message::Message;
use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile; use crate::rules::pycodestyle::rules::MissingNewlineAtEndOfFile;
use crate::{Edit, Fix}; use crate::{Edit, Fix};
@ -183,7 +182,7 @@ mod tests {
filename: &str, filename: &str,
source: &str, source: &str,
edit: impl IntoIterator<Item = Edit>, edit: impl IntoIterator<Item = Edit>,
) -> Vec<Message> { ) -> Vec<OldDiagnostic> {
edit.into_iter() edit.into_iter()
.map(|edit| { .map(|edit| {
// The choice of rule here is arbitrary. // The choice of rule here is arbitrary.
@ -192,7 +191,7 @@ mod tests {
edit.range(), edit.range(),
&SourceFileBuilder::new(filename, source).finish(), &SourceFileBuilder::new(filename, source).finish(),
); );
Message::from_diagnostic(diagnostic.with_fix(Fix::safe_edit(edit)), None) diagnostic.with_fix(Fix::safe_edit(edit))
}) })
.collect() .collect()
} }

View file

@ -14,7 +14,7 @@ pub use rule_selector::RuleSelector;
pub use rule_selector::clap_completion::RuleSelectorParser; pub use rule_selector::clap_completion::RuleSelectorParser;
pub use rules::pycodestyle::rules::IOError; pub use rules::pycodestyle::rules::IOError;
pub use diagnostic::OldDiagnostic; pub use message::OldDiagnostic;
pub(crate) use ruff_diagnostics::{Applicability, Edit, Fix}; pub(crate) use ruff_diagnostics::{Applicability, Edit, Fix};
pub use violation::{AlwaysFixableViolation, FixAvailability, Violation, ViolationMetadata}; pub use violation::{AlwaysFixableViolation, FixAvailability, Violation, ViolationMetadata};
@ -24,7 +24,6 @@ mod checkers;
pub mod codes; pub mod codes;
mod comments; mod comments;
mod cst; mod cst;
mod diagnostic;
pub mod directives; pub mod directives;
mod doc_lines; mod doc_lines;
mod docstrings; mod docstrings;

View file

@ -27,11 +27,10 @@ use crate::codes::NoqaCode;
use crate::directives::Directives; use crate::directives::Directives;
use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens}; use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens};
use crate::fix::{FixResult, fix_file}; use crate::fix::{FixResult, fix_file};
use crate::message::Message;
use crate::noqa::add_noqa; use crate::noqa::add_noqa;
use crate::package::PackageRoot; use crate::package::PackageRoot;
use crate::preview::is_py314_support_enabled; use crate::preview::is_py314_support_enabled;
use crate::registry::{AsRule, Rule, RuleSet}; use crate::registry::{Rule, RuleSet};
#[cfg(any(feature = "test-rules", test))] #[cfg(any(feature = "test-rules", test))]
use crate::rules::ruff::rules::test_rules::{self, TEST_RULES, TestRule}; use crate::rules::ruff::rules::test_rules::{self, TEST_RULES, TestRule};
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
@ -43,7 +42,7 @@ pub(crate) mod float;
pub struct LinterResult { pub struct LinterResult {
/// A collection of diagnostic messages generated by the linter. /// A collection of diagnostic messages generated by the linter.
pub messages: Vec<Message>, pub diagnostics: Vec<OldDiagnostic>,
/// Flag indicating that the parsed source code does not contain any /// Flag indicating that the parsed source code does not contain any
/// [`ParseError`]s /// [`ParseError`]s
has_valid_syntax: bool, has_valid_syntax: bool,
@ -145,7 +144,7 @@ pub struct FixerResult<'a> {
pub fixed: FixTable, pub fixed: FixTable,
} }
/// Generate [`Message`]s from the source code contents at the given `Path`. /// Generate [`OldDiagnostic`]s from the source code contents at the given `Path`.
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub fn check_path( pub fn check_path(
path: &Path, path: &Path,
@ -160,7 +159,7 @@ pub fn check_path(
source_type: PySourceType, source_type: PySourceType,
parsed: &Parsed<ModModule>, parsed: &Parsed<ModModule>,
target_version: TargetVersion, target_version: TargetVersion,
) -> Vec<Message> { ) -> Vec<OldDiagnostic> {
let source_file = let source_file =
SourceFileBuilder::new(path.to_string_lossy().as_ref(), locator.contents()).finish(); SourceFileBuilder::new(path.to_string_lossy().as_ref(), locator.contents()).finish();
@ -392,9 +391,12 @@ pub fn check_path(
RuleSet::empty() RuleSet::empty()
}; };
if !per_file_ignores.is_empty() { if !per_file_ignores.is_empty() {
diagnostics diagnostics.as_mut_vec().retain(|diagnostic| {
.as_mut_vec() diagnostic
.retain(|diagnostic| !per_file_ignores.contains(diagnostic.rule())); .noqa_code()
.and_then(|code| code.rule())
.is_none_or(|rule| !per_file_ignores.contains(rule))
});
} }
// Enforce `noqa` directives. // Enforce `noqa` directives.
@ -426,7 +428,11 @@ pub fn check_path(
if parsed.has_valid_syntax() { if parsed.has_valid_syntax() {
// Remove fixes for any rules marked as unfixable. // Remove fixes for any rules marked as unfixable.
for diagnostic in &mut diagnostics { for diagnostic in &mut diagnostics {
if !settings.rules.should_fix(diagnostic.rule()) { if diagnostic
.noqa_code()
.and_then(|code| code.rule())
.is_none_or(|rule| !settings.rules.should_fix(rule))
{
diagnostic.fix = None; diagnostic.fix = None;
} }
} }
@ -435,10 +441,12 @@ pub fn check_path(
if !settings.fix_safety.is_empty() { if !settings.fix_safety.is_empty() {
for diagnostic in &mut diagnostics { for diagnostic in &mut diagnostics {
if let Some(fix) = diagnostic.fix.take() { if let Some(fix) = diagnostic.fix.take() {
let fixed_applicability = settings if let Some(rule) = diagnostic.noqa_code().and_then(|code| code.rule()) {
.fix_safety let fixed_applicability = settings
.resolve_applicability(diagnostic.rule(), fix.applicability()); .fix_safety
diagnostic.set_fix(fix.with_applicability(fixed_applicability)); .resolve_applicability(rule, fix.applicability());
diagnostic.set_fix(fix.with_applicability(fixed_applicability));
}
} }
} }
} }
@ -494,7 +502,7 @@ pub fn add_noqa_to_path(
); );
// Generate diagnostics, ignoring any existing `noqa` directives. // Generate diagnostics, ignoring any existing `noqa` directives.
let messages = check_path( let diagnostics = check_path(
path, path,
package, package,
&locator, &locator,
@ -513,7 +521,7 @@ pub fn add_noqa_to_path(
// TODO(dhruvmanila): Add support for Jupyter Notebooks // TODO(dhruvmanila): Add support for Jupyter Notebooks
add_noqa( add_noqa(
path, path,
&messages, &diagnostics,
&locator, &locator,
indexer.comment_ranges(), indexer.comment_ranges(),
&settings.external, &settings.external,
@ -522,8 +530,7 @@ pub fn add_noqa_to_path(
) )
} }
/// Generate a [`Message`] for each [`OldDiagnostic`] triggered by the given source /// Generate an [`OldDiagnostic`] for each diagnostic triggered by the given source code.
/// code.
pub fn lint_only( pub fn lint_only(
path: &Path, path: &Path,
package: Option<PackageRoot<'_>>, package: Option<PackageRoot<'_>>,
@ -563,7 +570,7 @@ pub fn lint_only(
); );
// Generate diagnostics. // Generate diagnostics.
let messages = check_path( let diagnostics = check_path(
path, path,
package, package,
&locator, &locator,
@ -580,12 +587,14 @@ pub fn lint_only(
LinterResult { LinterResult {
has_valid_syntax: parsed.has_valid_syntax(), has_valid_syntax: parsed.has_valid_syntax(),
has_no_syntax_errors: !messages.iter().any(Message::is_syntax_error), has_no_syntax_errors: !diagnostics.iter().any(OldDiagnostic::is_syntax_error),
messages, diagnostics,
} }
} }
/// Convert from diagnostics to messages. /// Convert various error types into a single collection of diagnostics.
///
/// Also use `directives` to attach noqa offsets to lint diagnostics.
fn diagnostics_to_messages( fn diagnostics_to_messages(
diagnostics: Vec<OldDiagnostic>, diagnostics: Vec<OldDiagnostic>,
parse_errors: &[ParseError], parse_errors: &[ParseError],
@ -594,21 +603,23 @@ fn diagnostics_to_messages(
locator: &Locator, locator: &Locator,
directives: &Directives, directives: &Directives,
source_file: &SourceFile, source_file: &SourceFile,
) -> Vec<Message> { ) -> Vec<OldDiagnostic> {
parse_errors parse_errors
.iter() .iter()
.map(|parse_error| Message::from_parse_error(parse_error, locator, source_file.clone())) .map(|parse_error| {
OldDiagnostic::from_parse_error(parse_error, locator, source_file.clone())
})
.chain(unsupported_syntax_errors.iter().map(|syntax_error| { .chain(unsupported_syntax_errors.iter().map(|syntax_error| {
Message::from_unsupported_syntax_error(syntax_error, source_file.clone()) OldDiagnostic::from_unsupported_syntax_error(syntax_error, source_file.clone())
})) }))
.chain( .chain(
semantic_syntax_errors semantic_syntax_errors
.iter() .iter()
.map(|error| Message::from_semantic_syntax_error(error, source_file.clone())), .map(|error| OldDiagnostic::from_semantic_syntax_error(error, source_file.clone())),
) )
.chain(diagnostics.into_iter().map(|diagnostic| { .chain(diagnostics.into_iter().map(|diagnostic| {
let noqa_offset = directives.noqa_line_for.resolve(diagnostic.start()); let noqa_offset = directives.noqa_line_for.resolve(diagnostic.start());
Message::from_diagnostic(diagnostic, Some(noqa_offset)) diagnostic.with_noqa_offset(noqa_offset)
})) }))
.collect() .collect()
} }
@ -672,7 +683,7 @@ pub fn lint_fix<'a>(
); );
// Generate diagnostics. // Generate diagnostics.
let messages = check_path( let diagnostics = check_path(
path, path,
package, package,
&locator, &locator,
@ -689,7 +700,7 @@ pub fn lint_fix<'a>(
if iterations == 0 { if iterations == 0 {
has_valid_syntax = parsed.has_valid_syntax(); has_valid_syntax = parsed.has_valid_syntax();
has_no_syntax_errors = !messages.iter().any(Message::is_syntax_error); has_no_syntax_errors = !diagnostics.iter().any(OldDiagnostic::is_syntax_error);
} else { } else {
// If the source code had no syntax errors on the first pass, but // If the source code had no syntax errors on the first pass, but
// does on a subsequent pass, then we've introduced a // does on a subsequent pass, then we've introduced a
@ -707,7 +718,7 @@ pub fn lint_fix<'a>(
code: fixed_contents, code: fixed_contents,
fixes: applied, fixes: applied,
source_map, source_map,
}) = fix_file(&messages, &locator, unsafe_fixes) }) = fix_file(&diagnostics, &locator, unsafe_fixes)
{ {
if iterations < MAX_ITERATIONS { if iterations < MAX_ITERATIONS {
// Count the number of fixed errors. // Count the number of fixed errors.
@ -724,12 +735,12 @@ pub fn lint_fix<'a>(
continue; continue;
} }
report_failed_to_converge_error(path, transformed.source_code(), &messages); report_failed_to_converge_error(path, transformed.source_code(), &diagnostics);
} }
return Ok(FixerResult { return Ok(FixerResult {
result: LinterResult { result: LinterResult {
messages, diagnostics,
has_valid_syntax, has_valid_syntax,
has_no_syntax_errors, has_no_syntax_errors,
}, },
@ -749,8 +760,8 @@ fn collect_rule_codes(rules: impl IntoIterator<Item = NoqaCode>) -> String {
} }
#[expect(clippy::print_stderr)] #[expect(clippy::print_stderr)]
fn report_failed_to_converge_error(path: &Path, transformed: &str, messages: &[Message]) { fn report_failed_to_converge_error(path: &Path, transformed: &str, diagnostics: &[OldDiagnostic]) {
let codes = collect_rule_codes(messages.iter().filter_map(Message::noqa_code)); let codes = collect_rule_codes(diagnostics.iter().filter_map(OldDiagnostic::noqa_code));
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
eprintln!( eprintln!(
"{}{} Failed to converge after {} iterations in `{}` with rule codes {}:---\n{}\n---", "{}{} Failed to converge after {} iterations in `{}` with rule codes {}:---\n{}\n---",
@ -874,12 +885,12 @@ mod tests {
use ruff_notebook::{Notebook, NotebookError}; use ruff_notebook::{Notebook, NotebookError};
use crate::linter::check_path; use crate::linter::check_path;
use crate::message::Message; use crate::message::OldDiagnostic;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::source_kind::SourceKind; use crate::source_kind::SourceKind;
use crate::test::{TestedNotebook, assert_notebook_path, test_contents, test_snippet}; use crate::test::{TestedNotebook, assert_notebook_path, test_contents, test_snippet};
use crate::{Locator, assert_messages, directives, settings}; use crate::{Locator, assert_diagnostics, directives, settings};
/// Construct a path to a Jupyter notebook in the `resources/test/fixtures/jupyter` directory. /// Construct a path to a Jupyter notebook in the `resources/test/fixtures/jupyter` directory.
fn notebook_path(path: impl AsRef<Path>) -> std::path::PathBuf { fn notebook_path(path: impl AsRef<Path>) -> std::path::PathBuf {
@ -891,7 +902,7 @@ mod tests {
let actual = notebook_path("isort.ipynb"); let actual = notebook_path("isort.ipynb");
let expected = notebook_path("isort_expected.ipynb"); let expected = notebook_path("isort_expected.ipynb");
let TestedNotebook { let TestedNotebook {
messages, diagnostics,
source_notebook, source_notebook,
.. ..
} = assert_notebook_path( } = assert_notebook_path(
@ -899,7 +910,7 @@ mod tests {
expected, expected,
&LinterSettings::for_rule(Rule::UnsortedImports), &LinterSettings::for_rule(Rule::UnsortedImports),
)?; )?;
assert_messages!(messages, actual, source_notebook); assert_diagnostics!(diagnostics, actual, source_notebook);
Ok(()) Ok(())
} }
@ -908,7 +919,7 @@ mod tests {
let actual = notebook_path("ipy_escape_command.ipynb"); let actual = notebook_path("ipy_escape_command.ipynb");
let expected = notebook_path("ipy_escape_command_expected.ipynb"); let expected = notebook_path("ipy_escape_command_expected.ipynb");
let TestedNotebook { let TestedNotebook {
messages, diagnostics,
source_notebook, source_notebook,
.. ..
} = assert_notebook_path( } = assert_notebook_path(
@ -916,7 +927,7 @@ mod tests {
expected, expected,
&LinterSettings::for_rule(Rule::UnusedImport), &LinterSettings::for_rule(Rule::UnusedImport),
)?; )?;
assert_messages!(messages, actual, source_notebook); assert_diagnostics!(diagnostics, actual, source_notebook);
Ok(()) Ok(())
} }
@ -925,7 +936,7 @@ mod tests {
let actual = notebook_path("unused_variable.ipynb"); let actual = notebook_path("unused_variable.ipynb");
let expected = notebook_path("unused_variable_expected.ipynb"); let expected = notebook_path("unused_variable_expected.ipynb");
let TestedNotebook { let TestedNotebook {
messages, diagnostics,
source_notebook, source_notebook,
.. ..
} = assert_notebook_path( } = assert_notebook_path(
@ -933,7 +944,7 @@ mod tests {
expected, expected,
&LinterSettings::for_rule(Rule::UnusedVariable), &LinterSettings::for_rule(Rule::UnusedVariable),
)?; )?;
assert_messages!(messages, actual, source_notebook); assert_diagnostics!(diagnostics, actual, source_notebook);
Ok(()) Ok(())
} }
@ -942,7 +953,7 @@ mod tests {
let actual = notebook_path("undefined_name.ipynb"); let actual = notebook_path("undefined_name.ipynb");
let expected = notebook_path("undefined_name.ipynb"); let expected = notebook_path("undefined_name.ipynb");
let TestedNotebook { let TestedNotebook {
messages, diagnostics,
source_notebook, source_notebook,
.. ..
} = assert_notebook_path( } = assert_notebook_path(
@ -950,7 +961,7 @@ mod tests {
expected, expected,
&LinterSettings::for_rule(Rule::UndefinedName), &LinterSettings::for_rule(Rule::UndefinedName),
)?; )?;
assert_messages!(messages, actual, source_notebook); assert_diagnostics!(diagnostics, actual, source_notebook);
Ok(()) Ok(())
} }
@ -980,7 +991,7 @@ mod tests {
let actual = notebook_path("vscode_language_id.ipynb"); let actual = notebook_path("vscode_language_id.ipynb");
let expected = notebook_path("vscode_language_id_expected.ipynb"); let expected = notebook_path("vscode_language_id_expected.ipynb");
let TestedNotebook { let TestedNotebook {
messages, diagnostics,
source_notebook, source_notebook,
.. ..
} = assert_notebook_path( } = assert_notebook_path(
@ -988,7 +999,7 @@ mod tests {
expected, expected,
&LinterSettings::for_rule(Rule::UnusedImport), &LinterSettings::for_rule(Rule::UnusedImport),
)?; )?;
assert_messages!(messages, actual, source_notebook); assert_diagnostics!(diagnostics, actual, source_notebook);
Ok(()) Ok(())
} }
@ -1032,7 +1043,7 @@ mod tests {
/// Wrapper around `test_contents_syntax_errors` for testing a snippet of code instead of a /// Wrapper around `test_contents_syntax_errors` for testing a snippet of code instead of a
/// file. /// file.
fn test_snippet_syntax_errors(contents: &str, settings: &LinterSettings) -> Vec<Message> { fn test_snippet_syntax_errors(contents: &str, settings: &LinterSettings) -> Vec<OldDiagnostic> {
let contents = dedent(contents); let contents = dedent(contents);
test_contents_syntax_errors( test_contents_syntax_errors(
&SourceKind::Python(contents.to_string()), &SourceKind::Python(contents.to_string()),
@ -1047,7 +1058,7 @@ mod tests {
source_kind: &SourceKind, source_kind: &SourceKind,
path: &Path, path: &Path,
settings: &LinterSettings, settings: &LinterSettings,
) -> Vec<Message> { ) -> Vec<OldDiagnostic> {
let source_type = PySourceType::from(path); let source_type = PySourceType::from(path);
let target_version = settings.resolve_target_version(path); let target_version = settings.resolve_target_version(path);
let options = let options =
@ -1064,7 +1075,7 @@ mod tests {
&locator, &locator,
&indexer, &indexer,
); );
let mut messages = check_path( let mut diagnostics = check_path(
path, path,
None, None,
&locator, &locator,
@ -1078,8 +1089,8 @@ mod tests {
&parsed, &parsed,
target_version, target_version,
); );
messages.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
messages diagnostics
} }
#[test_case( #[test_case(
@ -1284,7 +1295,7 @@ mod tests {
error_type: &str, error_type: &str,
) { ) {
let snapshot = format!("semantic_syntax_error_{error_type}_{name}_{python_version}"); let snapshot = format!("semantic_syntax_error_{error_type}_{name}_{python_version}");
let messages = test_snippet_syntax_errors( let diagnostics = test_snippet_syntax_errors(
contents, contents,
&LinterSettings { &LinterSettings {
rules: settings::rule_table::RuleTable::empty(), rules: settings::rule_table::RuleTable::empty(),
@ -1293,7 +1304,7 @@ mod tests {
..Default::default() ..Default::default()
}, },
); );
assert_messages!(snapshot, messages); assert_diagnostics!(snapshot, diagnostics);
} }
#[test_case(PythonVersion::PY310)] #[test_case(PythonVersion::PY310)]
@ -1302,7 +1313,7 @@ mod tests {
let snapshot = let snapshot =
format!("async_comprehension_in_sync_comprehension_notebook_{python_version}"); format!("async_comprehension_in_sync_comprehension_notebook_{python_version}");
let path = Path::new("resources/test/fixtures/syntax_errors/async_comprehension.ipynb"); let path = Path::new("resources/test/fixtures/syntax_errors/async_comprehension.ipynb");
let messages = test_contents_syntax_errors( let diagnostics = test_contents_syntax_errors(
&SourceKind::ipy_notebook(Notebook::from_path(path)?), &SourceKind::ipy_notebook(Notebook::from_path(path)?),
path, path,
&LinterSettings { &LinterSettings {
@ -1312,7 +1323,7 @@ mod tests {
..Default::default() ..Default::default()
}, },
); );
assert_messages!(snapshot, messages); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1329,13 +1340,13 @@ mod tests {
fn test_syntax_errors(rule: Rule, path: &Path) -> Result<()> { fn test_syntax_errors(rule: Rule, path: &Path) -> Result<()> {
let snapshot = path.to_string_lossy().to_string(); let snapshot = path.to_string_lossy().to_string();
let path = Path::new("resources/test/fixtures/syntax_errors").join(path); let path = Path::new("resources/test/fixtures/syntax_errors").join(path);
let messages = test_contents_syntax_errors( let diagnostics = test_contents_syntax_errors(
&SourceKind::Python(std::fs::read_to_string(&path)?), &SourceKind::Python(std::fs::read_to_string(&path)?),
&path, &path,
&LinterSettings::for_rule(rule), &LinterSettings::for_rule(rule),
); );
insta::with_settings!({filters => vec![(r"\\", "/")]}, { insta::with_settings!({filters => vec![(r"\\", "/")]}, {
assert_messages!(snapshot, messages); assert_diagnostics!(snapshot, diagnostics);
}); });
Ok(()) Ok(())
@ -1345,7 +1356,7 @@ mod tests {
fn test_await_scope_notebook() -> Result<()> { fn test_await_scope_notebook() -> Result<()> {
let path = Path::new("resources/test/fixtures/syntax_errors/await_scope.ipynb"); let path = Path::new("resources/test/fixtures/syntax_errors/await_scope.ipynb");
let TestedNotebook { let TestedNotebook {
messages, diagnostics,
source_notebook, source_notebook,
.. ..
} = assert_notebook_path( } = assert_notebook_path(
@ -1353,7 +1364,7 @@ mod tests {
path, path,
&LinterSettings::for_rule(Rule::YieldOutsideFunction), &LinterSettings::for_rule(Rule::YieldOutsideFunction),
)?; )?;
assert_messages!(messages, path, source_notebook); assert_diagnostics!(diagnostics, path, source_notebook);
Ok(()) Ok(())
} }
@ -1435,8 +1446,8 @@ mod tests {
)] )]
fn test_disabled_typing_extensions(name: &str, contents: &str, settings: &LinterSettings) { fn test_disabled_typing_extensions(name: &str, contents: &str, settings: &LinterSettings) {
let snapshot = format!("disabled_typing_extensions_{name}"); let snapshot = format!("disabled_typing_extensions_{name}");
let messages = test_snippet(contents, settings); let diagnostics = test_snippet(contents, settings);
assert_messages!(snapshot, messages); assert_diagnostics!(snapshot, diagnostics);
} }
#[test_case( #[test_case(
@ -1452,7 +1463,8 @@ mod tests {
let snapshot = format!("disabled_typing_extensions_pyi_{name}"); let snapshot = format!("disabled_typing_extensions_pyi_{name}");
let path = Path::new("<filename>.pyi"); let path = Path::new("<filename>.pyi");
let contents = dedent(contents); let contents = dedent(contents);
let messages = test_contents(&SourceKind::Python(contents.into_owned()), path, settings).0; let diagnostics =
assert_messages!(snapshot, messages); test_contents(&SourceKind::Python(contents.into_owned()), path, settings).0;
assert_diagnostics!(snapshot, diagnostics);
} }
} }

View file

@ -2,7 +2,7 @@ use std::io::Write;
use ruff_source_file::LineColumn; use ruff_source_file::LineColumn;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
/// Generate error logging commands for Azure Pipelines format. /// Generate error logging commands for Azure Pipelines format.
/// See [documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash#logissue-log-an-error-or-warning) /// See [documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash#logissue-log-an-error-or-warning)
@ -13,29 +13,29 @@ impl Emitter for AzureEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for message in messages { for diagnostic in diagnostics {
let location = if context.is_notebook(&message.filename()) { let location = if context.is_notebook(&diagnostic.filename()) {
// We can't give a reasonable location for the structured formats, // We can't give a reasonable location for the structured formats,
// so we show one that's clearly a fallback // so we show one that's clearly a fallback
LineColumn::default() LineColumn::default()
} else { } else {
message.compute_start_location() diagnostic.compute_start_location()
}; };
writeln!( writeln!(
writer, writer,
"##vso[task.logissue type=error\ "##vso[task.logissue type=error\
;sourcepath={filename};linenumber={line};columnnumber={col};{code}]{body}", ;sourcepath={filename};linenumber={line};columnnumber={col};{code}]{body}",
filename = message.filename(), filename = diagnostic.filename(),
line = location.line, line = location.line,
col = location.column, col = location.column,
code = message code = diagnostic
.noqa_code() .noqa_code()
.map_or_else(String::new, |code| format!("code={code};")), .map_or_else(String::new, |code| format!("code={code};")),
body = message.body(), body = diagnostic.body(),
)?; )?;
} }
@ -49,13 +49,13 @@ mod tests {
use crate::message::AzureEmitter; use crate::message::AzureEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = AzureEmitter; let mut emitter = AzureEmitter;
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -63,7 +63,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = AzureEmitter; let mut emitter = AzureEmitter;
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -8,7 +8,7 @@ use similar::{ChangeTag, TextDiff};
use ruff_source_file::{OneIndexed, SourceFile}; use ruff_source_file::{OneIndexed, SourceFile};
use crate::message::Message; use crate::message::OldDiagnostic;
use crate::text_helpers::ShowNonprinting; use crate::text_helpers::ShowNonprinting;
use crate::{Applicability, Fix}; use crate::{Applicability, Fix};
@ -26,7 +26,7 @@ pub(super) struct Diff<'a> {
} }
impl<'a> Diff<'a> { impl<'a> Diff<'a> {
pub(crate) fn from_message(message: &'a Message) -> Option<Diff<'a>> { pub(crate) fn from_message(message: &'a OldDiagnostic) -> Option<Diff<'a>> {
message.fix().map(|fix| Diff { message.fix().map(|fix| Diff {
source_code: message.source_file(), source_code: message.source_file(),
fix, fix,

View file

@ -3,7 +3,7 @@ use std::io::Write;
use ruff_source_file::LineColumn; use ruff_source_file::LineColumn;
use crate::fs::relativize_path; use crate::fs::relativize_path;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
/// Generate error workflow command in GitHub Actions format. /// Generate error workflow command in GitHub Actions format.
/// See: [GitHub documentation](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message) /// See: [GitHub documentation](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message)
@ -14,12 +14,12 @@ impl Emitter for GithubEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for message in messages { for diagnostic in diagnostics {
let source_location = message.compute_start_location(); let source_location = diagnostic.compute_start_location();
let location = if context.is_notebook(&message.filename()) { let location = if context.is_notebook(&diagnostic.filename()) {
// We can't give a reasonable location for the structured formats, // We can't give a reasonable location for the structured formats,
// so we show one that's clearly a fallback // so we show one that's clearly a fallback
LineColumn::default() LineColumn::default()
@ -27,15 +27,15 @@ impl Emitter for GithubEmitter {
source_location source_location
}; };
let end_location = message.compute_end_location(); let end_location = diagnostic.compute_end_location();
write!( write!(
writer, writer,
"::error title=Ruff{code},file={file},line={row},col={column},endLine={end_row},endColumn={end_column}::", "::error title=Ruff{code},file={file},line={row},col={column},endLine={end_row},endColumn={end_column}::",
code = message code = diagnostic
.noqa_code() .noqa_code()
.map_or_else(String::new, |code| format!(" ({code})")), .map_or_else(String::new, |code| format!(" ({code})")),
file = message.filename(), file = diagnostic.filename(),
row = source_location.line, row = source_location.line,
column = source_location.column, column = source_location.column,
end_row = end_location.line, end_row = end_location.line,
@ -45,16 +45,16 @@ impl Emitter for GithubEmitter {
write!( write!(
writer, writer,
"{path}:{row}:{column}:", "{path}:{row}:{column}:",
path = relativize_path(&*message.filename()), path = relativize_path(&*diagnostic.filename()),
row = location.line, row = location.line,
column = location.column, column = location.column,
)?; )?;
if let Some(code) = message.noqa_code() { if let Some(code) = diagnostic.noqa_code() {
write!(writer, " {code}")?; write!(writer, " {code}")?;
} }
writeln!(writer, " {}", message.body())?; writeln!(writer, " {}", diagnostic.body())?;
} }
Ok(()) Ok(())
@ -67,13 +67,13 @@ mod tests {
use crate::message::GithubEmitter; use crate::message::GithubEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = GithubEmitter; let mut emitter = GithubEmitter;
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -81,7 +81,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = GithubEmitter; let mut emitter = GithubEmitter;
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -8,7 +8,7 @@ use serde::{Serialize, Serializer};
use serde_json::json; use serde_json::json;
use crate::fs::{relativize_path, relativize_path_to}; use crate::fs::{relativize_path, relativize_path_to};
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
/// Generate JSON with violations in GitLab CI format /// Generate JSON with violations in GitLab CI format
// https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-custom-tool // https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-custom-tool
@ -28,13 +28,13 @@ impl Emitter for GitlabEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
serde_json::to_writer_pretty( serde_json::to_writer_pretty(
writer, writer,
&SerializedMessages { &SerializedMessages {
messages, diagnostics,
context, context,
project_dir: self.project_dir.as_deref(), project_dir: self.project_dir.as_deref(),
}, },
@ -45,7 +45,7 @@ impl Emitter for GitlabEmitter {
} }
struct SerializedMessages<'a> { struct SerializedMessages<'a> {
messages: &'a [Message], diagnostics: &'a [OldDiagnostic],
context: &'a EmitterContext<'a>, context: &'a EmitterContext<'a>,
project_dir: Option<&'a str>, project_dir: Option<&'a str>,
} }
@ -55,14 +55,14 @@ impl Serialize for SerializedMessages<'_> {
where where
S: Serializer, S: Serializer,
{ {
let mut s = serializer.serialize_seq(Some(self.messages.len()))?; let mut s = serializer.serialize_seq(Some(self.diagnostics.len()))?;
let mut fingerprints = HashSet::<u64>::with_capacity(self.messages.len()); let mut fingerprints = HashSet::<u64>::with_capacity(self.diagnostics.len());
for message in self.messages { for diagnostic in self.diagnostics {
let start_location = message.compute_start_location(); let start_location = diagnostic.compute_start_location();
let end_location = message.compute_end_location(); let end_location = diagnostic.compute_end_location();
let lines = if self.context.is_notebook(&message.filename()) { let lines = if self.context.is_notebook(&diagnostic.filename()) {
// We can't give a reasonable location for the structured formats, // We can't give a reasonable location for the structured formats,
// so we show one that's clearly a fallback // so we show one that's clearly a fallback
json!({ json!({
@ -77,23 +77,23 @@ impl Serialize for SerializedMessages<'_> {
}; };
let path = self.project_dir.as_ref().map_or_else( let path = self.project_dir.as_ref().map_or_else(
|| relativize_path(&*message.filename()), || relativize_path(&*diagnostic.filename()),
|project_dir| relativize_path_to(&*message.filename(), project_dir), |project_dir| relativize_path_to(&*diagnostic.filename(), project_dir),
); );
let mut message_fingerprint = fingerprint(message, &path, 0); let mut message_fingerprint = fingerprint(diagnostic, &path, 0);
// Make sure that we do not get a fingerprint that is already in use // Make sure that we do not get a fingerprint that is already in use
// by adding in the previously generated one. // by adding in the previously generated one.
while fingerprints.contains(&message_fingerprint) { while fingerprints.contains(&message_fingerprint) {
message_fingerprint = fingerprint(message, &path, message_fingerprint); message_fingerprint = fingerprint(diagnostic, &path, message_fingerprint);
} }
fingerprints.insert(message_fingerprint); fingerprints.insert(message_fingerprint);
let (description, check_name) = if let Some(code) = message.noqa_code() { let (description, check_name) = if let Some(code) = diagnostic.noqa_code() {
(message.body().to_string(), code.to_string()) (diagnostic.body().to_string(), code.to_string())
} else { } else {
let description = message.body(); let description = diagnostic.body();
let description_without_prefix = description let description_without_prefix = description
.strip_prefix("SyntaxError: ") .strip_prefix("SyntaxError: ")
.unwrap_or(description); .unwrap_or(description);
@ -123,7 +123,7 @@ impl Serialize for SerializedMessages<'_> {
} }
/// Generate a unique fingerprint to identify a violation. /// Generate a unique fingerprint to identify a violation.
fn fingerprint(message: &Message, project_path: &str, salt: u64) -> u64 { fn fingerprint(message: &OldDiagnostic, project_path: &str, salt: u64) -> u64 {
let mut hasher = DefaultHasher::new(); let mut hasher = DefaultHasher::new();
salt.hash(&mut hasher); salt.hash(&mut hasher);
@ -139,13 +139,13 @@ mod tests {
use crate::message::GitlabEmitter; use crate::message::GitlabEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = GitlabEmitter::default(); let mut emitter = GitlabEmitter::default();
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(redact_fingerprint(&content)); assert_snapshot!(redact_fingerprint(&content));
} }
@ -153,7 +153,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = GitlabEmitter::default(); let mut emitter = GitlabEmitter::default();
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(redact_fingerprint(&content)); assert_snapshot!(redact_fingerprint(&content));
} }

View file

@ -11,7 +11,7 @@ use crate::fs::relativize_path;
use crate::message::diff::calculate_print_width; use crate::message::diff::calculate_print_width;
use crate::message::text::{MessageCodeFrame, RuleCodeAndBody}; use crate::message::text::{MessageCodeFrame, RuleCodeAndBody};
use crate::message::{ use crate::message::{
Emitter, EmitterContext, Message, MessageWithLocation, group_messages_by_filename, Emitter, EmitterContext, MessageWithLocation, OldDiagnostic, group_diagnostics_by_filename,
}; };
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
@ -46,10 +46,10 @@ impl Emitter for GroupedEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for (filename, messages) in group_messages_by_filename(messages) { for (filename, messages) in group_diagnostics_by_filename(diagnostics) {
// Compute the maximum number of digits in the row and column, for messages in // Compute the maximum number of digits in the row and column, for messages in
// this file. // this file.
@ -207,14 +207,14 @@ mod tests {
use crate::message::GroupedEmitter; use crate::message::GroupedEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
#[test] #[test]
fn default() { fn default() {
let mut emitter = GroupedEmitter::default(); let mut emitter = GroupedEmitter::default();
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -222,7 +222,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = GroupedEmitter::default(); let mut emitter = GroupedEmitter::default();
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -230,7 +230,7 @@ mod tests {
#[test] #[test]
fn show_source() { fn show_source() {
let mut emitter = GroupedEmitter::default().with_show_source(true); let mut emitter = GroupedEmitter::default().with_show_source(true);
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -240,7 +240,7 @@ mod tests {
let mut emitter = GroupedEmitter::default() let mut emitter = GroupedEmitter::default()
.with_show_fix_status(true) .with_show_fix_status(true)
.with_show_source(true); .with_show_source(true);
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -251,7 +251,7 @@ mod tests {
.with_show_fix_status(true) .with_show_fix_status(true)
.with_show_source(true) .with_show_source(true)
.with_unsafe_fixes(UnsafeFixes::Enabled); .with_unsafe_fixes(UnsafeFixes::Enabled);
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -9,7 +9,7 @@ use ruff_source_file::{LineColumn, OneIndexed, SourceCode};
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::Edit; use crate::Edit;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
#[derive(Default)] #[derive(Default)]
pub struct JsonEmitter; pub struct JsonEmitter;
@ -18,17 +18,23 @@ impl Emitter for JsonEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
serde_json::to_writer_pretty(writer, &ExpandedMessages { messages, context })?; serde_json::to_writer_pretty(
writer,
&ExpandedMessages {
diagnostics,
context,
},
)?;
Ok(()) Ok(())
} }
} }
struct ExpandedMessages<'a> { struct ExpandedMessages<'a> {
messages: &'a [Message], diagnostics: &'a [OldDiagnostic],
context: &'a EmitterContext<'a>, context: &'a EmitterContext<'a>,
} }
@ -37,9 +43,9 @@ impl Serialize for ExpandedMessages<'_> {
where where
S: Serializer, S: Serializer,
{ {
let mut s = serializer.serialize_seq(Some(self.messages.len()))?; let mut s = serializer.serialize_seq(Some(self.diagnostics.len()))?;
for message in self.messages { for message in self.diagnostics {
let value = message_to_json_value(message, self.context); let value = message_to_json_value(message, self.context);
s.serialize_element(&value)?; s.serialize_element(&value)?;
} }
@ -48,7 +54,7 @@ impl Serialize for ExpandedMessages<'_> {
} }
} }
pub(crate) fn message_to_json_value(message: &Message, context: &EmitterContext) -> Value { pub(crate) fn message_to_json_value(message: &OldDiagnostic, context: &EmitterContext) -> Value {
let source_file = message.source_file(); let source_file = message.source_file();
let source_code = source_file.to_source_code(); let source_code = source_file.to_source_code();
let notebook_index = context.notebook_index(&message.filename()); let notebook_index = context.notebook_index(&message.filename());
@ -180,14 +186,14 @@ mod tests {
use crate::message::JsonEmitter; use crate::message::JsonEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_notebook_output, capture_emitter_output, create_messages, capture_emitter_notebook_output, capture_emitter_output, create_diagnostics,
create_notebook_messages, create_syntax_error_messages, create_notebook_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = JsonEmitter; let mut emitter = JsonEmitter;
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -195,7 +201,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = JsonEmitter; let mut emitter = JsonEmitter;
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -203,8 +209,9 @@ mod tests {
#[test] #[test]
fn notebook_output() { fn notebook_output() {
let mut emitter = JsonEmitter; let mut emitter = JsonEmitter;
let (messages, notebook_indexes) = create_notebook_messages(); let (diagnostics, notebook_indexes) = create_notebook_diagnostics();
let content = capture_emitter_notebook_output(&mut emitter, &messages, &notebook_indexes); let content =
capture_emitter_notebook_output(&mut emitter, &diagnostics, &notebook_indexes);
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -1,7 +1,7 @@
use std::io::Write; use std::io::Write;
use crate::message::json::message_to_json_value; use crate::message::json::message_to_json_value;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
#[derive(Default)] #[derive(Default)]
pub struct JsonLinesEmitter; pub struct JsonLinesEmitter;
@ -10,11 +10,11 @@ impl Emitter for JsonLinesEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for message in messages { for diagnostic in diagnostics {
serde_json::to_writer(&mut *writer, &message_to_json_value(message, context))?; serde_json::to_writer(&mut *writer, &message_to_json_value(diagnostic, context))?;
writer.write_all(b"\n")?; writer.write_all(b"\n")?;
} }
Ok(()) Ok(())
@ -27,14 +27,14 @@ mod tests {
use crate::message::json_lines::JsonLinesEmitter; use crate::message::json_lines::JsonLinesEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_notebook_output, capture_emitter_output, create_messages, capture_emitter_notebook_output, capture_emitter_output, create_diagnostics,
create_notebook_messages, create_syntax_error_messages, create_notebook_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = JsonLinesEmitter; let mut emitter = JsonLinesEmitter;
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -42,7 +42,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = JsonLinesEmitter; let mut emitter = JsonLinesEmitter;
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -50,7 +50,7 @@ mod tests {
#[test] #[test]
fn notebook_output() { fn notebook_output() {
let mut emitter = JsonLinesEmitter; let mut emitter = JsonLinesEmitter;
let (messages, notebook_indexes) = create_notebook_messages(); let (messages, notebook_indexes) = create_notebook_diagnostics();
let content = capture_emitter_notebook_output(&mut emitter, &messages, &notebook_indexes); let content = capture_emitter_notebook_output(&mut emitter, &messages, &notebook_indexes);
assert_snapshot!(content); assert_snapshot!(content);

View file

@ -6,7 +6,7 @@ use quick_junit::{NonSuccessKind, Report, TestCase, TestCaseStatus, TestSuite, X
use ruff_source_file::LineColumn; use ruff_source_file::LineColumn;
use crate::message::{ use crate::message::{
Emitter, EmitterContext, Message, MessageWithLocation, group_messages_by_filename, Emitter, EmitterContext, MessageWithLocation, OldDiagnostic, group_diagnostics_by_filename,
}; };
#[derive(Default)] #[derive(Default)]
@ -16,12 +16,12 @@ impl Emitter for JunitEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut report = Report::new("ruff"); let mut report = Report::new("ruff");
if messages.is_empty() { if diagnostics.is_empty() {
let mut test_suite = TestSuite::new("ruff"); let mut test_suite = TestSuite::new("ruff");
test_suite test_suite
.extra .extra
@ -31,7 +31,7 @@ impl Emitter for JunitEmitter {
test_suite.add_test_case(case); test_suite.add_test_case(case);
report.add_test_suite(test_suite); report.add_test_suite(test_suite);
} else { } else {
for (filename, messages) in group_messages_by_filename(messages) { for (filename, messages) in group_diagnostics_by_filename(diagnostics) {
let mut test_suite = TestSuite::new(&filename); let mut test_suite = TestSuite::new(&filename);
test_suite test_suite
.extra .extra
@ -97,13 +97,13 @@ mod tests {
use crate::message::JunitEmitter; use crate::message::JunitEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = JunitEmitter; let mut emitter = JunitEmitter;
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -111,7 +111,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = JunitEmitter; let mut emitter = JunitEmitter;
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -1,5 +1,6 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt::Display;
use std::io::Write; use std::io::Write;
use std::ops::Deref; use std::ops::Deref;
@ -23,11 +24,11 @@ use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
pub use sarif::SarifEmitter; pub use sarif::SarifEmitter;
pub use text::TextEmitter; pub use text::TextEmitter;
use crate::Locator; use crate::Fix;
use crate::codes::NoqaCode; use crate::codes::NoqaCode;
use crate::logging::DisplayParseErrorType; use crate::logging::DisplayParseErrorType;
use crate::registry::Rule; use crate::registry::Rule;
use crate::{Fix, OldDiagnostic}; use crate::{Locator, Violation};
mod azure; mod azure;
mod diff; mod diff;
@ -42,33 +43,34 @@ mod rdjson;
mod sarif; mod sarif;
mod text; mod text;
/// Message represents either a diagnostic message corresponding to a rule violation or a syntax /// `OldDiagnostic` represents either a diagnostic message corresponding to a rule violation or a
/// error message. /// syntax error message.
/// ///
/// All of the information for syntax errors is captured in the underlying [`db::Diagnostic`], while /// All of the information for syntax errors is captured in the underlying [`db::Diagnostic`], while
/// rule violations can have the additional optional fields like fixes, suggestions, and (parent) /// rule violations can have the additional optional fields like fixes, suggestions, and (parent)
/// `noqa` offsets. /// `noqa` offsets.
/// ///
/// For diagnostic messages, the [`db::Diagnostic`]'s primary message contains the /// For diagnostic messages, the [`db::Diagnostic`]'s primary message contains the
/// [`OldDiagnostic::body`], and the primary annotation optionally contains the suggestion accompanying /// [`OldDiagnostic::body`], and the primary annotation optionally contains the suggestion
/// a fix. The `db::Diagnostic::id` field contains the kebab-case lint name derived from the `Rule`. /// accompanying a fix. The `db::Diagnostic::id` field contains the kebab-case lint name derived
/// from the `Rule`.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Message { pub struct OldDiagnostic {
pub diagnostic: db::Diagnostic, pub diagnostic: db::Diagnostic,
// these fields are specific to rule violations // these fields are specific to rule violations
pub fix: Option<Fix>, pub fix: Option<Fix>,
pub parent: Option<TextSize>, pub parent: Option<TextSize>,
pub(crate) noqa_offset: Option<TextSize>, pub(crate) noqa_offset: Option<TextSize>,
noqa_code: Option<NoqaCode>, pub(crate) noqa_code: Option<NoqaCode>,
} }
impl Message { impl OldDiagnostic {
pub fn syntax_error( pub fn syntax_error(
message: impl std::fmt::Display, message: impl Display,
range: TextRange, range: TextRange,
file: SourceFile, file: SourceFile,
) -> Message { ) -> OldDiagnostic {
let mut diag = db::Diagnostic::new(DiagnosticId::InvalidSyntax, Severity::Error, message); let mut diag = db::Diagnostic::new(DiagnosticId::InvalidSyntax, Severity::Error, message);
let span = Span::from(file).with_range(range); let span = Span::from(file).with_range(range);
diag.annotate(Annotation::primary(span)); diag.annotate(Annotation::primary(span));
@ -82,16 +84,20 @@ impl Message {
} }
#[expect(clippy::too_many_arguments)] #[expect(clippy::too_many_arguments)]
pub fn diagnostic( pub fn lint<B, S>(
body: String, body: B,
suggestion: Option<String>, suggestion: Option<S>,
range: TextRange, range: TextRange,
fix: Option<Fix>, fix: Option<Fix>,
parent: Option<TextSize>, parent: Option<TextSize>,
file: SourceFile, file: SourceFile,
noqa_offset: Option<TextSize>, noqa_offset: Option<TextSize>,
rule: Rule, rule: Rule,
) -> Message { ) -> OldDiagnostic
where
B: Display,
S: Display,
{
let mut diagnostic = db::Diagnostic::new( let mut diagnostic = db::Diagnostic::new(
DiagnosticId::Lint(LintName::of(rule.into())), DiagnosticId::Lint(LintName::of(rule.into())),
Severity::Error, Severity::Error,
@ -104,7 +110,7 @@ impl Message {
} }
diagnostic.annotate(annotation); diagnostic.annotate(annotation);
Message { OldDiagnostic {
diagnostic, diagnostic,
fix, fix,
parent, parent,
@ -113,35 +119,12 @@ impl Message {
} }
} }
/// Create a [`Message`] from the given [`OldDiagnostic`] corresponding to a rule violation. /// Create an [`OldDiagnostic`] from the given [`ParseError`].
pub fn from_diagnostic(diagnostic: OldDiagnostic, noqa_offset: Option<TextSize>) -> Message {
let OldDiagnostic {
body,
suggestion,
range,
fix,
parent,
rule,
file,
} = diagnostic;
Self::diagnostic(
body,
suggestion,
range,
fix,
parent,
file,
noqa_offset,
rule,
)
}
/// Create a [`Message`] from the given [`ParseError`].
pub fn from_parse_error( pub fn from_parse_error(
parse_error: &ParseError, parse_error: &ParseError,
locator: &Locator, locator: &Locator,
file: SourceFile, file: SourceFile,
) -> Message { ) -> OldDiagnostic {
// Try to create a non-empty range so that the diagnostic can print a caret at the right // Try to create a non-empty range so that the diagnostic can print a caret at the right
// position. This requires that we retrieve the next character, if any, and take its length // position. This requires that we retrieve the next character, if any, and take its length
// to maintain char-boundaries. // to maintain char-boundaries.
@ -151,7 +134,7 @@ impl Message {
.next() .next()
.map_or(TextSize::new(0), TextLen::text_len); .map_or(TextSize::new(0), TextLen::text_len);
Message::syntax_error( OldDiagnostic::syntax_error(
format_args!( format_args!(
"SyntaxError: {}", "SyntaxError: {}",
DisplayParseErrorType::new(&parse_error.error) DisplayParseErrorType::new(&parse_error.error)
@ -161,30 +144,105 @@ impl Message {
) )
} }
/// Create a [`Message`] from the given [`UnsupportedSyntaxError`]. /// Create an [`OldDiagnostic`] from the given [`UnsupportedSyntaxError`].
pub fn from_unsupported_syntax_error( pub fn from_unsupported_syntax_error(
unsupported_syntax_error: &UnsupportedSyntaxError, unsupported_syntax_error: &UnsupportedSyntaxError,
file: SourceFile, file: SourceFile,
) -> Message { ) -> OldDiagnostic {
Message::syntax_error( OldDiagnostic::syntax_error(
format_args!("SyntaxError: {unsupported_syntax_error}"), format_args!("SyntaxError: {unsupported_syntax_error}"),
unsupported_syntax_error.range, unsupported_syntax_error.range,
file, file,
) )
} }
/// Create a [`Message`] from the given [`SemanticSyntaxError`]. /// Create an [`OldDiagnostic`] from the given [`SemanticSyntaxError`].
pub fn from_semantic_syntax_error( pub fn from_semantic_syntax_error(
semantic_syntax_error: &SemanticSyntaxError, semantic_syntax_error: &SemanticSyntaxError,
file: SourceFile, file: SourceFile,
) -> Message { ) -> OldDiagnostic {
Message::syntax_error( OldDiagnostic::syntax_error(
format_args!("SyntaxError: {semantic_syntax_error}"), format_args!("SyntaxError: {semantic_syntax_error}"),
semantic_syntax_error.range, semantic_syntax_error.range,
file, file,
) )
} }
// TODO(brent) We temporarily allow this to avoid updating all of the call sites to add
// references. I expect this method to go away or change significantly with the rest of the
// diagnostic refactor, but if it still exists in this form at the end of the refactor, we
// should just update the call sites.
#[expect(clippy::needless_pass_by_value)]
pub fn new<T: Violation>(kind: T, range: TextRange, file: &SourceFile) -> Self {
Self::lint(
Violation::message(&kind),
Violation::fix_title(&kind),
range,
None,
None,
file.clone(),
None,
T::rule(),
)
}
/// Consumes `self` and returns a new `Diagnostic` with the given `fix`.
#[inline]
#[must_use]
pub fn with_fix(mut self, fix: Fix) -> Self {
self.set_fix(fix);
self
}
/// Set the [`Fix`] used to fix the diagnostic.
#[inline]
pub fn set_fix(&mut self, fix: Fix) {
self.fix = Some(fix);
}
/// Set the [`Fix`] used to fix the diagnostic, if the provided function returns `Ok`.
/// Otherwise, log the error.
#[inline]
pub fn try_set_fix(&mut self, func: impl FnOnce() -> anyhow::Result<Fix>) {
match func() {
Ok(fix) => self.fix = Some(fix),
Err(err) => log::debug!("Failed to create fix for {}: {}", self.name(), err),
}
}
/// Set the [`Fix`] used to fix the diagnostic, if the provided function returns `Ok`.
/// Otherwise, log the error.
#[inline]
pub fn try_set_optional_fix(&mut self, func: impl FnOnce() -> anyhow::Result<Option<Fix>>) {
match func() {
Ok(None) => {}
Ok(Some(fix)) => self.fix = Some(fix),
Err(err) => log::debug!("Failed to create fix for {}: {}", self.name(), err),
}
}
/// Consumes `self` and returns a new `Diagnostic` with the given parent node.
#[inline]
#[must_use]
pub fn with_parent(mut self, parent: TextSize) -> Self {
self.set_parent(parent);
self
}
/// Set the location of the diagnostic's parent node.
#[inline]
pub fn set_parent(&mut self, parent: TextSize) {
self.parent = Some(parent);
}
/// Consumes `self` and returns a new `Diagnostic` with the given noqa offset.
#[inline]
#[must_use]
pub fn with_noqa_offset(mut self, noqa_offset: TextSize) -> Self {
self.noqa_offset = Some(noqa_offset);
self
}
/// Returns `true` if `self` is a syntax error message. /// Returns `true` if `self` is a syntax error message.
pub fn is_syntax_error(&self) -> bool { pub fn is_syntax_error(&self) -> bool {
self.diagnostic.id().is_invalid_syntax() self.diagnostic.id().is_invalid_syntax()
@ -214,12 +272,12 @@ impl Message {
self.noqa_offset self.noqa_offset
} }
/// Returns the [`Fix`] for the message, if there is any. /// Returns the [`Fix`] for the diagnostic, if there is any.
pub fn fix(&self) -> Option<&Fix> { pub fn fix(&self) -> Option<&Fix> {
self.fix.as_ref() self.fix.as_ref()
} }
/// Returns `true` if the message contains a [`Fix`]. /// Returns `true` if the diagnostic contains a [`Fix`].
pub fn fixable(&self) -> bool { pub fn fixable(&self) -> bool {
self.fix().is_some() self.fix().is_some()
} }
@ -278,19 +336,19 @@ impl Message {
} }
} }
impl Ord for Message { impl Ord for OldDiagnostic {
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
(self.source_file(), self.start()).cmp(&(other.source_file(), other.start())) (self.source_file(), self.start()).cmp(&(other.source_file(), other.start()))
} }
} }
impl PartialOrd for Message { impl PartialOrd for OldDiagnostic {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other)) Some(self.cmp(other))
} }
} }
impl Ranged for Message { impl Ranged for OldDiagnostic {
fn range(&self) -> TextRange { fn range(&self) -> TextRange {
self.diagnostic self.diagnostic
.expect_primary_span() .expect_primary_span()
@ -300,41 +358,43 @@ impl Ranged for Message {
} }
struct MessageWithLocation<'a> { struct MessageWithLocation<'a> {
message: &'a Message, message: &'a OldDiagnostic,
start_location: LineColumn, start_location: LineColumn,
} }
impl Deref for MessageWithLocation<'_> { impl Deref for MessageWithLocation<'_> {
type Target = Message; type Target = OldDiagnostic;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.message self.message
} }
} }
fn group_messages_by_filename(messages: &[Message]) -> BTreeMap<String, Vec<MessageWithLocation>> { fn group_diagnostics_by_filename(
diagnostics: &[OldDiagnostic],
) -> BTreeMap<String, Vec<MessageWithLocation>> {
let mut grouped_messages = BTreeMap::default(); let mut grouped_messages = BTreeMap::default();
for message in messages { for diagnostic in diagnostics {
grouped_messages grouped_messages
.entry(message.filename().to_string()) .entry(diagnostic.filename().to_string())
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push(MessageWithLocation { .push(MessageWithLocation {
message, message: diagnostic,
start_location: message.compute_start_location(), start_location: diagnostic.compute_start_location(),
}); });
} }
grouped_messages grouped_messages
} }
/// Display format for a [`Message`]s. /// Display format for [`OldDiagnostic`]s.
/// ///
/// The emitter serializes a slice of [`Message`]'s and writes them to a [`Write`]. /// The emitter serializes a slice of [`OldDiagnostic`]s and writes them to a [`Write`].
pub trait Emitter { pub trait Emitter {
/// Serializes the `messages` and writes the output to `writer`. /// Serializes the `diagnostics` and writes the output to `writer`.
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()>; ) -> anyhow::Result<()>;
} }
@ -371,9 +431,9 @@ mod tests {
use ruff_text_size::{TextRange, TextSize}; use ruff_text_size::{TextRange, TextSize};
use crate::Locator; use crate::Locator;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
pub(super) fn create_syntax_error_messages() -> Vec<Message> { pub(super) fn create_syntax_error_diagnostics() -> Vec<OldDiagnostic> {
let source = r"from os import let source = r"from os import
if call(foo if call(foo
@ -386,12 +446,12 @@ if call(foo
.errors() .errors()
.iter() .iter()
.map(|parse_error| { .map(|parse_error| {
Message::from_parse_error(parse_error, &locator, source_file.clone()) OldDiagnostic::from_parse_error(parse_error, &locator, source_file.clone())
}) })
.collect() .collect()
} }
pub(super) fn create_messages() -> Vec<Message> { pub(super) fn create_diagnostics() -> Vec<OldDiagnostic> {
let fib = r#"import os let fib = r#"import os
@ -409,9 +469,9 @@ def fibonacci(n):
let fib_source = SourceFileBuilder::new("fib.py", fib).finish(); let fib_source = SourceFileBuilder::new("fib.py", fib).finish();
let unused_import_start = TextSize::from(7); let unused_import_start = TextSize::from(7);
let unused_import = Message::diagnostic( let unused_import = OldDiagnostic::lint(
"`os` imported but unused".to_string(), "`os` imported but unused",
Some("Remove unused import: `os`".to_string()), Some("Remove unused import: `os`"),
TextRange::new(unused_import_start, TextSize::from(9)), TextRange::new(unused_import_start, TextSize::from(9)),
Some(Fix::unsafe_edit(Edit::range_deletion(TextRange::new( Some(Fix::unsafe_edit(Edit::range_deletion(TextRange::new(
TextSize::from(0), TextSize::from(0),
@ -424,9 +484,9 @@ def fibonacci(n):
); );
let unused_variable_start = TextSize::from(94); let unused_variable_start = TextSize::from(94);
let unused_variable = Message::diagnostic( let unused_variable = OldDiagnostic::lint(
"Local variable `x` is assigned to but never used".to_string(), "Local variable `x` is assigned to but never used",
Some("Remove assignment to unused variable `x`".to_string()), Some("Remove assignment to unused variable `x`"),
TextRange::new(unused_variable_start, TextSize::from(95)), TextRange::new(unused_variable_start, TextSize::from(95)),
Some(Fix::unsafe_edit(Edit::deletion( Some(Fix::unsafe_edit(Edit::deletion(
TextSize::from(94), TextSize::from(94),
@ -441,9 +501,9 @@ def fibonacci(n):
let file_2 = r"if a == 1: pass"; let file_2 = r"if a == 1: pass";
let undefined_name_start = TextSize::from(3); let undefined_name_start = TextSize::from(3);
let undefined_name = Message::diagnostic( let undefined_name = OldDiagnostic::lint(
"Undefined name `a`".to_string(), "Undefined name `a`",
None, Option::<&'static str>::None,
TextRange::new(undefined_name_start, TextSize::from(4)), TextRange::new(undefined_name_start, TextSize::from(4)),
None, None,
None, None,
@ -455,7 +515,8 @@ def fibonacci(n):
vec![unused_import, unused_variable, undefined_name] vec![unused_import, unused_variable, undefined_name]
} }
pub(super) fn create_notebook_messages() -> (Vec<Message>, FxHashMap<String, NotebookIndex>) { pub(super) fn create_notebook_diagnostics()
-> (Vec<OldDiagnostic>, FxHashMap<String, NotebookIndex>) {
let notebook = r"# cell 1 let notebook = r"# cell 1
import os import os
# cell 2 # cell 2
@ -471,9 +532,9 @@ def foo():
let notebook_source = SourceFileBuilder::new("notebook.ipynb", notebook).finish(); let notebook_source = SourceFileBuilder::new("notebook.ipynb", notebook).finish();
let unused_import_os_start = TextSize::from(16); let unused_import_os_start = TextSize::from(16);
let unused_import_os = Message::diagnostic( let unused_import_os = OldDiagnostic::lint(
"`os` imported but unused".to_string(), "`os` imported but unused",
Some("Remove unused import: `os`".to_string()), Some("Remove unused import: `os`"),
TextRange::new(unused_import_os_start, TextSize::from(18)), TextRange::new(unused_import_os_start, TextSize::from(18)),
Some(Fix::safe_edit(Edit::range_deletion(TextRange::new( Some(Fix::safe_edit(Edit::range_deletion(TextRange::new(
TextSize::from(9), TextSize::from(9),
@ -486,9 +547,9 @@ def foo():
); );
let unused_import_math_start = TextSize::from(35); let unused_import_math_start = TextSize::from(35);
let unused_import_math = Message::diagnostic( let unused_import_math = OldDiagnostic::lint(
"`math` imported but unused".to_string(), "`math` imported but unused",
Some("Remove unused import: `math`".to_string()), Some("Remove unused import: `math`"),
TextRange::new(unused_import_math_start, TextSize::from(39)), TextRange::new(unused_import_math_start, TextSize::from(39)),
Some(Fix::safe_edit(Edit::range_deletion(TextRange::new( Some(Fix::safe_edit(Edit::range_deletion(TextRange::new(
TextSize::from(28), TextSize::from(28),
@ -501,9 +562,9 @@ def foo():
); );
let unused_variable_start = TextSize::from(98); let unused_variable_start = TextSize::from(98);
let unused_variable = Message::diagnostic( let unused_variable = OldDiagnostic::lint(
"Local variable `x` is assigned to but never used".to_string(), "Local variable `x` is assigned to but never used",
Some("Remove assignment to unused variable `x`".to_string()), Some("Remove assignment to unused variable `x`"),
TextRange::new(unused_variable_start, TextSize::from(99)), TextRange::new(unused_variable_start, TextSize::from(99)),
Some(Fix::unsafe_edit(Edit::deletion( Some(Fix::unsafe_edit(Edit::deletion(
TextSize::from(94), TextSize::from(94),
@ -554,24 +615,24 @@ def foo():
pub(super) fn capture_emitter_output( pub(super) fn capture_emitter_output(
emitter: &mut dyn Emitter, emitter: &mut dyn Emitter,
messages: &[Message], diagnostics: &[OldDiagnostic],
) -> String { ) -> String {
let notebook_indexes = FxHashMap::default(); let notebook_indexes = FxHashMap::default();
let context = EmitterContext::new(&notebook_indexes); let context = EmitterContext::new(&notebook_indexes);
let mut output: Vec<u8> = Vec::new(); let mut output: Vec<u8> = Vec::new();
emitter.emit(&mut output, messages, &context).unwrap(); emitter.emit(&mut output, diagnostics, &context).unwrap();
String::from_utf8(output).expect("Output to be valid UTF-8") String::from_utf8(output).expect("Output to be valid UTF-8")
} }
pub(super) fn capture_emitter_notebook_output( pub(super) fn capture_emitter_notebook_output(
emitter: &mut dyn Emitter, emitter: &mut dyn Emitter,
messages: &[Message], diagnostics: &[OldDiagnostic],
notebook_indexes: &FxHashMap<String, NotebookIndex>, notebook_indexes: &FxHashMap<String, NotebookIndex>,
) -> String { ) -> String {
let context = EmitterContext::new(notebook_indexes); let context = EmitterContext::new(notebook_indexes);
let mut output: Vec<u8> = Vec::new(); let mut output: Vec<u8> = Vec::new();
emitter.emit(&mut output, messages, &context).unwrap(); emitter.emit(&mut output, diagnostics, &context).unwrap();
String::from_utf8(output).expect("Output to be valid UTF-8") String::from_utf8(output).expect("Output to be valid UTF-8")
} }

View file

@ -3,7 +3,7 @@ use std::io::Write;
use ruff_source_file::OneIndexed; use ruff_source_file::OneIndexed;
use crate::fs::relativize_path; use crate::fs::relativize_path;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
/// Generate violations in Pylint format. /// Generate violations in Pylint format.
/// See: [Flake8 documentation](https://flake8.pycqa.org/en/latest/internal/formatters.html#pylint-formatter) /// See: [Flake8 documentation](https://flake8.pycqa.org/en/latest/internal/formatters.html#pylint-formatter)
@ -14,28 +14,28 @@ impl Emitter for PylintEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for message in messages { for diagnostic in diagnostics {
let row = if context.is_notebook(&message.filename()) { let row = if context.is_notebook(&diagnostic.filename()) {
// We can't give a reasonable location for the structured formats, // We can't give a reasonable location for the structured formats,
// so we show one that's clearly a fallback // so we show one that's clearly a fallback
OneIndexed::from_zero_indexed(0) OneIndexed::from_zero_indexed(0)
} else { } else {
message.compute_start_location().line diagnostic.compute_start_location().line
}; };
let body = if let Some(code) = message.noqa_code() { let body = if let Some(code) = diagnostic.noqa_code() {
format!("[{code}] {body}", body = message.body()) format!("[{code}] {body}", body = diagnostic.body())
} else { } else {
message.body().to_string() diagnostic.body().to_string()
}; };
writeln!( writeln!(
writer, writer,
"{path}:{row}: {body}", "{path}:{row}: {body}",
path = relativize_path(&*message.filename()), path = relativize_path(&*diagnostic.filename()),
)?; )?;
} }
@ -49,13 +49,13 @@ mod tests {
use crate::message::PylintEmitter; use crate::message::PylintEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = PylintEmitter; let mut emitter = PylintEmitter;
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -63,7 +63,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = PylintEmitter; let mut emitter = PylintEmitter;
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -8,7 +8,7 @@ use ruff_source_file::SourceCode;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::Edit; use crate::Edit;
use crate::message::{Emitter, EmitterContext, LineColumn, Message}; use crate::message::{Emitter, EmitterContext, LineColumn, OldDiagnostic};
#[derive(Default)] #[derive(Default)]
pub struct RdjsonEmitter; pub struct RdjsonEmitter;
@ -17,7 +17,7 @@ impl Emitter for RdjsonEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
_context: &EmitterContext, _context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
serde_json::to_writer_pretty( serde_json::to_writer_pretty(
@ -28,7 +28,7 @@ impl Emitter for RdjsonEmitter {
"url": "https://docs.astral.sh/ruff", "url": "https://docs.astral.sh/ruff",
}, },
"severity": "warning", "severity": "warning",
"diagnostics": &ExpandedMessages{ messages } "diagnostics": &ExpandedMessages{ diagnostics }
}), }),
)?; )?;
@ -37,7 +37,7 @@ impl Emitter for RdjsonEmitter {
} }
struct ExpandedMessages<'a> { struct ExpandedMessages<'a> {
messages: &'a [Message], diagnostics: &'a [OldDiagnostic],
} }
impl Serialize for ExpandedMessages<'_> { impl Serialize for ExpandedMessages<'_> {
@ -45,9 +45,9 @@ impl Serialize for ExpandedMessages<'_> {
where where
S: Serializer, S: Serializer,
{ {
let mut s = serializer.serialize_seq(Some(self.messages.len()))?; let mut s = serializer.serialize_seq(Some(self.diagnostics.len()))?;
for message in self.messages { for message in self.diagnostics {
let value = message_to_rdjson_value(message); let value = message_to_rdjson_value(message);
s.serialize_element(&value)?; s.serialize_element(&value)?;
} }
@ -56,7 +56,7 @@ impl Serialize for ExpandedMessages<'_> {
} }
} }
fn message_to_rdjson_value(message: &Message) -> Value { fn message_to_rdjson_value(message: &OldDiagnostic) -> Value {
let source_file = message.source_file(); let source_file = message.source_file();
let source_code = source_file.to_source_code(); let source_code = source_file.to_source_code();
@ -121,13 +121,13 @@ mod tests {
use crate::message::RdjsonEmitter; use crate::message::RdjsonEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
#[test] #[test]
fn output() { fn output() {
let mut emitter = RdjsonEmitter; let mut emitter = RdjsonEmitter;
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -135,7 +135,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = RdjsonEmitter; let mut emitter = RdjsonEmitter;
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -10,7 +10,7 @@ use ruff_source_file::OneIndexed;
use crate::VERSION; use crate::VERSION;
use crate::codes::NoqaCode; use crate::codes::NoqaCode;
use crate::fs::normalize_path; use crate::fs::normalize_path;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
use crate::registry::{Linter, RuleNamespace}; use crate::registry::{Linter, RuleNamespace};
pub struct SarifEmitter; pub struct SarifEmitter;
@ -19,10 +19,10 @@ impl Emitter for SarifEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
_context: &EmitterContext, _context: &EmitterContext,
) -> Result<()> { ) -> Result<()> {
let results = messages let results = diagnostics
.iter() .iter()
.map(SarifResult::from_message) .map(SarifResult::from_message)
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
@ -124,7 +124,7 @@ struct SarifResult {
impl SarifResult { impl SarifResult {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
fn from_message(message: &Message) -> Result<Self> { fn from_message(message: &OldDiagnostic) -> Result<Self> {
let start_location = message.compute_start_location(); let start_location = message.compute_start_location();
let end_location = message.compute_end_location(); let end_location = message.compute_end_location();
let path = normalize_path(&*message.filename()); let path = normalize_path(&*message.filename());
@ -144,7 +144,7 @@ impl SarifResult {
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
#[expect(clippy::unnecessary_wraps)] #[expect(clippy::unnecessary_wraps)]
fn from_message(message: &Message) -> Result<Self> { fn from_message(message: &OldDiagnostic) -> Result<Self> {
let start_location = message.compute_start_location(); let start_location = message.compute_start_location();
let end_location = message.compute_end_location(); let end_location = message.compute_end_location();
let path = normalize_path(&*message.filename()); let path = normalize_path(&*message.filename());
@ -194,12 +194,12 @@ impl Serialize for SarifResult {
mod tests { mod tests {
use crate::message::SarifEmitter; use crate::message::SarifEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_output, create_messages, create_syntax_error_messages, capture_emitter_output, create_diagnostics, create_syntax_error_diagnostics,
}; };
fn get_output() -> String { fn get_output() -> String {
let mut emitter = SarifEmitter {}; let mut emitter = SarifEmitter {};
capture_emitter_output(&mut emitter, &create_messages()) capture_emitter_output(&mut emitter, &create_diagnostics())
} }
#[test] #[test]
@ -211,7 +211,7 @@ mod tests {
#[test] #[test]
fn valid_syntax_error_json() { fn valid_syntax_error_json() {
let mut emitter = SarifEmitter {}; let mut emitter = SarifEmitter {};
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
serde_json::from_str::<serde_json::Value>(&content).unwrap(); serde_json::from_str::<serde_json::Value>(&content).unwrap();
} }

View file

@ -14,7 +14,7 @@ use crate::Locator;
use crate::fs::relativize_path; use crate::fs::relativize_path;
use crate::line_width::{IndentWidth, LineWidthBuilder}; use crate::line_width::{IndentWidth, LineWidthBuilder};
use crate::message::diff::Diff; use crate::message::diff::Diff;
use crate::message::{Emitter, EmitterContext, Message}; use crate::message::{Emitter, EmitterContext, OldDiagnostic};
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
bitflags! { bitflags! {
@ -66,10 +66,10 @@ impl Emitter for TextEmitter {
fn emit( fn emit(
&mut self, &mut self,
writer: &mut dyn Write, writer: &mut dyn Write,
messages: &[Message], diagnostics: &[OldDiagnostic],
context: &EmitterContext, context: &EmitterContext,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for message in messages { for message in diagnostics {
write!( write!(
writer, writer,
"{path}{sep}", "{path}{sep}",
@ -140,7 +140,7 @@ impl Emitter for TextEmitter {
} }
pub(super) struct RuleCodeAndBody<'a> { pub(super) struct RuleCodeAndBody<'a> {
pub(crate) message: &'a Message, pub(crate) message: &'a OldDiagnostic,
pub(crate) show_fix_status: bool, pub(crate) show_fix_status: bool,
pub(crate) unsafe_fixes: UnsafeFixes, pub(crate) unsafe_fixes: UnsafeFixes,
} }
@ -178,7 +178,7 @@ impl Display for RuleCodeAndBody<'_> {
} }
pub(super) struct MessageCodeFrame<'a> { pub(super) struct MessageCodeFrame<'a> {
pub(crate) message: &'a Message, pub(crate) message: &'a OldDiagnostic,
pub(crate) notebook_index: Option<&'a NotebookIndex>, pub(crate) notebook_index: Option<&'a NotebookIndex>,
} }
@ -409,15 +409,15 @@ mod tests {
use crate::message::TextEmitter; use crate::message::TextEmitter;
use crate::message::tests::{ use crate::message::tests::{
capture_emitter_notebook_output, capture_emitter_output, create_messages, capture_emitter_notebook_output, capture_emitter_output, create_diagnostics,
create_notebook_messages, create_syntax_error_messages, create_notebook_diagnostics, create_syntax_error_diagnostics,
}; };
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
#[test] #[test]
fn default() { fn default() {
let mut emitter = TextEmitter::default().with_show_source(true); let mut emitter = TextEmitter::default().with_show_source(true);
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -427,7 +427,7 @@ mod tests {
let mut emitter = TextEmitter::default() let mut emitter = TextEmitter::default()
.with_show_fix_status(true) .with_show_fix_status(true)
.with_show_source(true); .with_show_source(true);
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -438,7 +438,7 @@ mod tests {
.with_show_fix_status(true) .with_show_fix_status(true)
.with_show_source(true) .with_show_source(true)
.with_unsafe_fixes(UnsafeFixes::Enabled); .with_unsafe_fixes(UnsafeFixes::Enabled);
let content = capture_emitter_output(&mut emitter, &create_messages()); let content = capture_emitter_output(&mut emitter, &create_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }
@ -449,7 +449,7 @@ mod tests {
.with_show_fix_status(true) .with_show_fix_status(true)
.with_show_source(true) .with_show_source(true)
.with_unsafe_fixes(UnsafeFixes::Enabled); .with_unsafe_fixes(UnsafeFixes::Enabled);
let (messages, notebook_indexes) = create_notebook_messages(); let (messages, notebook_indexes) = create_notebook_diagnostics();
let content = capture_emitter_notebook_output(&mut emitter, &messages, &notebook_indexes); let content = capture_emitter_notebook_output(&mut emitter, &messages, &notebook_indexes);
assert_snapshot!(content); assert_snapshot!(content);
@ -458,7 +458,7 @@ mod tests {
#[test] #[test]
fn syntax_errors() { fn syntax_errors() {
let mut emitter = TextEmitter::default().with_show_source(true); let mut emitter = TextEmitter::default().with_show_source(true);
let content = capture_emitter_output(&mut emitter, &create_syntax_error_messages()); let content = capture_emitter_output(&mut emitter, &create_syntax_error_diagnostics());
assert_snapshot!(content); assert_snapshot!(content);
} }

View file

@ -18,7 +18,7 @@ use crate::Edit;
use crate::Locator; use crate::Locator;
use crate::codes::NoqaCode; use crate::codes::NoqaCode;
use crate::fs::relativize_path; use crate::fs::relativize_path;
use crate::message::Message; use crate::message::OldDiagnostic;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rule_redirects::get_redirect_target; use crate::rule_redirects::get_redirect_target;
@ -29,7 +29,7 @@ use crate::rule_redirects::get_redirect_target;
/// simultaneously. /// simultaneously.
pub fn generate_noqa_edits( pub fn generate_noqa_edits(
path: &Path, path: &Path,
messages: &[Message], diagnostics: &[OldDiagnostic],
locator: &Locator, locator: &Locator,
comment_ranges: &CommentRanges, comment_ranges: &CommentRanges,
external: &[String], external: &[String],
@ -39,7 +39,7 @@ pub fn generate_noqa_edits(
let file_directives = FileNoqaDirectives::extract(locator, comment_ranges, external, path); let file_directives = FileNoqaDirectives::extract(locator, comment_ranges, external, path);
let exemption = FileExemption::from(&file_directives); let exemption = FileExemption::from(&file_directives);
let directives = NoqaDirectives::from_commented_ranges(comment_ranges, external, path, locator); let directives = NoqaDirectives::from_commented_ranges(comment_ranges, external, path, locator);
let comments = find_noqa_comments(messages, locator, &exemption, &directives, noqa_line_for); let comments = find_noqa_comments(diagnostics, locator, &exemption, &directives, noqa_line_for);
build_noqa_edits_by_diagnostic(comments, locator, line_ending) build_noqa_edits_by_diagnostic(comments, locator, line_ending)
} }
@ -707,7 +707,7 @@ impl Error for LexicalError {}
/// Adds noqa comments to suppress all messages of a file. /// Adds noqa comments to suppress all messages of a file.
pub(crate) fn add_noqa( pub(crate) fn add_noqa(
path: &Path, path: &Path,
messages: &[Message], diagnostics: &[OldDiagnostic],
locator: &Locator, locator: &Locator,
comment_ranges: &CommentRanges, comment_ranges: &CommentRanges,
external: &[String], external: &[String],
@ -716,7 +716,7 @@ pub(crate) fn add_noqa(
) -> Result<usize> { ) -> Result<usize> {
let (count, output) = add_noqa_inner( let (count, output) = add_noqa_inner(
path, path,
messages, diagnostics,
locator, locator,
comment_ranges, comment_ranges,
external, external,
@ -730,7 +730,7 @@ pub(crate) fn add_noqa(
fn add_noqa_inner( fn add_noqa_inner(
path: &Path, path: &Path,
messages: &[Message], diagnostics: &[OldDiagnostic],
locator: &Locator, locator: &Locator,
comment_ranges: &CommentRanges, comment_ranges: &CommentRanges,
external: &[String], external: &[String],
@ -745,7 +745,7 @@ fn add_noqa_inner(
let directives = NoqaDirectives::from_commented_ranges(comment_ranges, external, path, locator); let directives = NoqaDirectives::from_commented_ranges(comment_ranges, external, path, locator);
let comments = find_noqa_comments(messages, locator, &exemption, &directives, noqa_line_for); let comments = find_noqa_comments(diagnostics, locator, &exemption, &directives, noqa_line_for);
let edits = build_noqa_edits_by_line(comments, locator, line_ending); let edits = build_noqa_edits_by_line(comments, locator, line_ending);
@ -835,7 +835,7 @@ struct NoqaComment<'a> {
} }
fn find_noqa_comments<'a>( fn find_noqa_comments<'a>(
messages: &'a [Message], diagnostics: &'a [OldDiagnostic],
locator: &'a Locator, locator: &'a Locator,
exemption: &'a FileExemption, exemption: &'a FileExemption,
directives: &'a NoqaDirectives, directives: &'a NoqaDirectives,
@ -845,7 +845,7 @@ fn find_noqa_comments<'a>(
let mut comments_by_line: Vec<Option<NoqaComment<'a>>> = vec![]; let mut comments_by_line: Vec<Option<NoqaComment<'a>>> = vec![];
// Mark any non-ignored diagnostics. // Mark any non-ignored diagnostics.
for message in messages { for message in diagnostics {
let Some(code) = message.noqa_code() else { let Some(code) = message.noqa_code() else {
comments_by_line.push(None); comments_by_line.push(None);
continue; continue;
@ -1219,9 +1219,8 @@ mod tests {
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
use ruff_source_file::{LineEnding, SourceFileBuilder}; use ruff_source_file::{LineEnding, SourceFileBuilder};
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_text_size::{TextLen, TextRange, TextSize};
use crate::message::Message;
use crate::noqa::{ use crate::noqa::{
Directive, LexicalError, NoqaLexerOutput, NoqaMapping, add_noqa_inner, lex_codes, Directive, LexicalError, NoqaLexerOutput, NoqaMapping, add_noqa_inner, lex_codes,
lex_file_exemption, lex_inline_noqa, lex_file_exemption, lex_inline_noqa,
@ -1247,12 +1246,6 @@ mod tests {
} }
} }
/// Create a [`Message`] with a placeholder filename and rule code from `diagnostic`.
fn message_from_diagnostic(diagnostic: OldDiagnostic) -> Message {
let noqa_offset = diagnostic.start();
Message::from_diagnostic(diagnostic, Some(noqa_offset))
}
#[test] #[test]
fn noqa_lex_codes() { fn noqa_lex_codes() {
let source = " F401,,F402F403 # and so on"; let source = " F401,,F402F403 # and so on";
@ -2840,8 +2833,7 @@ mod tests {
}, },
TextRange::new(TextSize::from(0), TextSize::from(0)), TextRange::new(TextSize::from(0), TextSize::from(0)),
&source_file, &source_file,
)] )];
.map(message_from_diagnostic);
let contents = "x = 1"; let contents = "x = 1";
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
@ -2871,8 +2863,7 @@ mod tests {
TextRange::new(TextSize::from(0), TextSize::from(0)), TextRange::new(TextSize::from(0), TextSize::from(0)),
&source_file, &source_file,
), ),
] ];
.map(message_from_diagnostic);
let contents = "x = 1 # noqa: E741\n"; let contents = "x = 1 # noqa: E741\n";
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
let comment_ranges = let comment_ranges =
@ -2903,8 +2894,7 @@ mod tests {
TextRange::new(TextSize::from(0), TextSize::from(0)), TextRange::new(TextSize::from(0), TextSize::from(0)),
&source_file, &source_file,
), ),
] ];
.map(message_from_diagnostic);
let contents = "x = 1 # noqa"; let contents = "x = 1 # noqa";
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
let comment_ranges = let comment_ranges =
@ -2940,8 +2930,7 @@ print(
PrintfStringFormatting, PrintfStringFormatting,
TextRange::new(12.into(), 79.into()), TextRange::new(12.into(), 79.into()),
&source_file, &source_file,
)] )];
.map(message_from_diagnostic);
let comment_ranges = CommentRanges::default(); let comment_ranges = CommentRanges::default();
let edits = generate_noqa_edits( let edits = generate_noqa_edits(
path, path,
@ -2974,8 +2963,7 @@ bar =
UselessSemicolon, UselessSemicolon,
TextRange::new(4.into(), 5.into()), TextRange::new(4.into(), 5.into()),
&source_file, &source_file,
)] )];
.map(message_from_diagnostic);
let noqa_line_for = NoqaMapping::default(); let noqa_line_for = NoqaMapping::default();
let comment_ranges = CommentRanges::default(); let comment_ranges = CommentRanges::default();
let edits = generate_noqa_edits( let edits = generate_noqa_edits(

View file

@ -7,12 +7,14 @@ use ruff_source_file::SourceFile;
use crate::IOError; use crate::IOError;
use crate::OldDiagnostic; use crate::OldDiagnostic;
use crate::message::Message;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::ruff::rules::InvalidPyprojectToml; use crate::rules::ruff::rules::InvalidPyprojectToml;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
pub fn lint_pyproject_toml(source_file: &SourceFile, settings: &LinterSettings) -> Vec<Message> { pub fn lint_pyproject_toml(
source_file: &SourceFile,
settings: &LinterSettings,
) -> Vec<OldDiagnostic> {
let Some(err) = toml::from_str::<PyProjectToml>(source_file.source_text()).err() else { let Some(err) = toml::from_str::<PyProjectToml>(source_file.source_text()).err() else {
return Vec::default(); return Vec::default();
}; };
@ -31,7 +33,7 @@ pub fn lint_pyproject_toml(source_file: &SourceFile, settings: &LinterSettings)
if settings.rules.enabled(Rule::IOError) { if settings.rules.enabled(Rule::IOError) {
let diagnostic = let diagnostic =
OldDiagnostic::new(IOError { message }, TextRange::default(), source_file); OldDiagnostic::new(IOError { message }, TextRange::default(), source_file);
messages.push(Message::from_diagnostic(diagnostic, None)); messages.push(diagnostic);
} else { } else {
warn!( warn!(
"{}{}{} {message}", "{}{}{} {message}",
@ -57,7 +59,7 @@ pub fn lint_pyproject_toml(source_file: &SourceFile, settings: &LinterSettings)
range, range,
source_file, source_file,
); );
messages.push(Message::from_diagnostic(diagnostic, None)); messages.push(diagnostic);
} }
messages messages

View file

@ -215,12 +215,6 @@ pub enum Linter {
} }
pub trait RuleNamespace: Sized { pub trait RuleNamespace: Sized {
/// Returns the prefix that every single code that ruff uses to identify
/// rules from this linter starts with. In the case that multiple
/// `#[prefix]`es are configured for the variant in the `Linter` enum
/// definition this is the empty string.
fn common_prefix(&self) -> &'static str;
/// Attempts to parse the given rule code. If the prefix is recognized /// Attempts to parse the given rule code. If the prefix is recognized
/// returns the respective variant along with the code with the common /// returns the respective variant along with the code with the common
/// prefix stripped. /// prefix stripped.

View file

@ -265,7 +265,6 @@ mod schema {
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::RuleSelector; use crate::RuleSelector;
use crate::registry::RuleNamespace;
use crate::rule_selector::{Linter, RuleCodePrefix}; use crate::rule_selector::{Linter, RuleCodePrefix};
impl JsonSchema for RuleSelector { impl JsonSchema for RuleSelector {

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::AirflowVariableNameTaskIdMismatch, Path::new("AIR001.py"))] #[test_case(Rule::AirflowVariableNameTaskIdMismatch, Path::new("AIR001.py"))]
#[test_case(Rule::AirflowDagNoScheduleArgument, Path::new("AIR002.py"))] #[test_case(Rule::AirflowDagNoScheduleArgument, Path::new("AIR002.py"))]
@ -58,7 +58,7 @@ mod tests {
Path::new("airflow").join(path).as_path(), Path::new("airflow").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::CommentedOutCode, Path::new("ERA001.py"))] #[test_case(Rule::CommentedOutCode, Path::new("ERA001.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> { fn rules(rule_code: Rule, path: &Path) -> Result<()> {
@ -20,7 +20,7 @@ mod tests {
Path::new("eradicate").join(path).as_path(), Path::new("eradicate").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::FastApiRedundantResponseModel, Path::new("FAST001.py"))] #[test_case(Rule::FastApiRedundantResponseModel, Path::new("FAST001.py"))]
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_0.py"))] #[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_0.py"))]
@ -22,7 +22,7 @@ mod tests {
Path::new("fastapi").join(path).as_path(), Path::new("fastapi").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -39,7 +39,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::SysVersionSlice3, Path::new("YTT101.py"))] #[test_case(Rule::SysVersionSlice3, Path::new("YTT101.py"))]
#[test_case(Rule::SysVersion2, Path::new("YTT102.py"))] #[test_case(Rule::SysVersion2, Path::new("YTT102.py"))]
@ -29,7 +29,7 @@ mod tests {
Path::new("flake8_2020").join(path).as_path(), Path::new("flake8_2020").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::test_path; use crate::test::test_path;
@ -33,7 +33,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -59,7 +59,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -79,7 +79,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -101,7 +101,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -119,7 +119,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -138,7 +138,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -164,7 +164,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -180,7 +180,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::AnyType]) ..LinterSettings::for_rules(vec![Rule::AnyType])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -198,7 +198,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -216,7 +216,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -226,7 +226,7 @@ mod tests {
Path::new("flake8_annotations/simple_magic_methods.py"), Path::new("flake8_annotations/simple_magic_methods.py"),
&LinterSettings::for_rule(Rule::MissingReturnTypeSpecialMethod), &LinterSettings::for_rule(Rule::MissingReturnTypeSpecialMethod),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::test_path; use crate::test::test_path;
@ -34,7 +34,7 @@ mod tests {
Path::new("flake8_async").join(path).as_path(), Path::new("flake8_async").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -48,7 +48,7 @@ mod tests {
..LinterSettings::for_rule(Rule::AsyncFunctionWithTimeout) ..LinterSettings::for_rule(Rule::AsyncFunctionWithTimeout)
}, },
)?; )?;
assert_messages!(path.file_name().unwrap().to_str().unwrap(), diagnostics); assert_diagnostics!(path.file_name().unwrap().to_str().unwrap(), diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::settings::types::PreviewMode; use crate::settings::types::PreviewMode;
@ -94,7 +94,7 @@ mod tests {
Path::new("flake8_bandit").join(path).as_path(), Path::new("flake8_bandit").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -117,7 +117,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -139,7 +139,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -160,7 +160,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -181,7 +181,7 @@ mod tests {
..LinterSettings::for_rule(Rule::HardcodedTempFile) ..LinterSettings::for_rule(Rule::HardcodedTempFile)
}, },
)?; )?;
assert_messages!("S108_extend", diagnostics); assert_diagnostics!("S108_extend", diagnostics);
Ok(()) Ok(())
} }
@ -197,7 +197,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TryExceptPass) ..LinterSettings::for_rule(Rule::TryExceptPass)
}, },
)?; )?;
assert_messages!("S110_typed", diagnostics); assert_diagnostics!("S110_typed", diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::BlindExcept, Path::new("BLE.py"))] #[test_case(Rule::BlindExcept, Path::new("BLE.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> { fn rules(rule_code: Rule, path: &Path) -> Result<()> {
@ -19,7 +19,7 @@ mod tests {
Path::new("flake8_blind_except").join(path).as_path(), Path::new("flake8_blind_except").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -13,7 +13,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::BooleanTypeHintPositionalArgument, Path::new("FBT.py"))] #[test_case(Rule::BooleanTypeHintPositionalArgument, Path::new("FBT.py"))]
#[test_case(Rule::BooleanDefaultValuePositionalArgument, Path::new("FBT.py"))] #[test_case(Rule::BooleanDefaultValuePositionalArgument, Path::new("FBT.py"))]
@ -24,7 +24,7 @@ mod tests {
Path::new("flake8_boolean_trap").join(path).as_path(), Path::new("flake8_boolean_trap").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -42,7 +42,7 @@ mod tests {
..LinterSettings::for_rule(Rule::BooleanPositionalValueInCall) ..LinterSettings::for_rule(Rule::BooleanPositionalValueInCall)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
@ -76,7 +76,7 @@ mod tests {
Path::new("flake8_bugbear").join(path).as_path(), Path::new("flake8_bugbear").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -104,7 +104,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -115,7 +115,7 @@ mod tests {
Path::new("flake8_bugbear").join(snapshot).as_path(), Path::new("flake8_bugbear").join(snapshot).as_path(),
&LinterSettings::for_rule(Rule::ZipWithoutExplicitStrict), &LinterSettings::for_rule(Rule::ZipWithoutExplicitStrict),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -134,7 +134,7 @@ mod tests {
..LinterSettings::for_rule(Rule::MutableArgumentDefault) ..LinterSettings::for_rule(Rule::MutableArgumentDefault)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -155,7 +155,7 @@ mod tests {
..LinterSettings::for_rule(Rule::FunctionCallInDefaultArgument) ..LinterSettings::for_rule(Rule::FunctionCallInDefaultArgument)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -171,7 +171,7 @@ mod tests {
..LinterSettings::for_rule(Rule::MutableContextvarDefault) ..LinterSettings::for_rule(Rule::MutableContextvarDefault)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::flake8_builtins; use crate::rules::flake8_builtins;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
@ -59,7 +59,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -89,7 +89,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -112,7 +112,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -136,7 +136,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -163,7 +163,7 @@ mod tests {
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -207,7 +207,7 @@ mod tests {
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -221,7 +221,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Path::new("COM81.py"))] #[test_case(Path::new("COM81.py"))]
#[test_case(Path::new("COM81_syntax_error.py"))] #[test_case(Path::new("COM81_syntax_error.py"))]
@ -24,7 +24,7 @@ mod tests {
Rule::ProhibitedTrailingComma, Rule::ProhibitedTrailingComma,
]), ]),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::settings::types::PreviewMode; use crate::settings::types::PreviewMode;
@ -44,7 +44,7 @@ mod tests {
Path::new("flake8_comprehensions").join(path).as_path(), Path::new("flake8_comprehensions").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -63,7 +63,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -83,7 +83,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -7,7 +7,7 @@ pub mod settings;
mod tests { mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_snippet; use crate::test::test_snippet;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test] #[test]
fn notice() { fn notice() {
@ -20,7 +20,7 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -34,7 +34,7 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -48,7 +48,7 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -62,7 +62,7 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -76,7 +76,7 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -90,7 +90,7 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -110,7 +110,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -130,7 +130,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -150,7 +150,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -170,7 +170,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -190,7 +190,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -210,7 +210,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -230,7 +230,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -250,7 +250,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -268,7 +268,7 @@ import os
..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]) ..settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice])
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -331,7 +331,7 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test] #[test]
@ -342,6 +342,6 @@ import os
.trim(), .trim(),
&settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]), &settings::LinterSettings::for_rules(vec![Rule::MissingCopyrightNotice]),
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::CallDatetimeWithoutTzinfo, Path::new("DTZ001.py"))] #[test_case(Rule::CallDatetimeWithoutTzinfo, Path::new("DTZ001.py"))]
#[test_case(Rule::CallDatetimeToday, Path::new("DTZ002.py"))] #[test_case(Rule::CallDatetimeToday, Path::new("DTZ002.py"))]
@ -28,7 +28,7 @@ mod tests {
Path::new("flake8_datetimez").join(path).as_path(), Path::new("flake8_datetimez").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::Debugger, Path::new("T100.py"))] #[test_case(Rule::Debugger, Path::new("T100.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> { fn rules(rule_code: Rule, path: &Path) -> Result<()> {
@ -20,7 +20,7 @@ mod tests {
Path::new("flake8_debugger").join(path).as_path(), Path::new("flake8_debugger").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::DjangoNullableModelStringField, Path::new("DJ001.py"))] #[test_case(Rule::DjangoNullableModelStringField, Path::new("DJ001.py"))]
#[test_case(Rule::DjangoLocalsInRenderFunction, Path::new("DJ003.py"))] #[test_case(Rule::DjangoLocalsInRenderFunction, Path::new("DJ003.py"))]
@ -25,7 +25,7 @@ mod tests {
Path::new("flake8_django").join(path).as_path(), Path::new("flake8_django").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test] #[test]
fn defaults() -> Result<()> { fn defaults() -> Result<()> {
@ -22,7 +22,7 @@ mod tests {
Rule::DotFormatInException, Rule::DotFormatInException,
]), ]),
)?; )?;
assert_messages!("defaults", diagnostics); assert_diagnostics!("defaults", diagnostics);
Ok(()) Ok(())
} }
@ -41,7 +41,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!("custom", diagnostics); assert_diagnostics!("custom", diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -12,7 +12,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Path::new("EXE001_1.py"))] #[test_case(Path::new("EXE001_1.py"))]
#[test_case(Path::new("EXE001_2.py"))] #[test_case(Path::new("EXE001_2.py"))]
@ -41,7 +41,7 @@ mod tests {
Rule::ShebangMissingPython, Rule::ShebangMissingPython,
]), ]),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::LineContainsFixme; "T001")] #[test_case(Rule::LineContainsFixme; "T001")]
#[test_case(Rule::LineContainsHack; "T002")] #[test_case(Rule::LineContainsHack; "T002")]
@ -21,7 +21,7 @@ mod tests {
Path::new("flake8_fixme/T00.py"), Path::new("flake8_fixme/T00.py"),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
use ruff_python_ast::PythonVersion; use ruff_python_ast::PythonVersion;
#[test_case(Path::new("edge_case.py"))] #[test_case(Path::new("edge_case.py"))]
@ -34,7 +34,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::FutureRewritableTypeAnnotation) ..settings::LinterSettings::for_rule(Rule::FutureRewritableTypeAnnotation)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -53,7 +53,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::FutureRequiredTypeAnnotation) ..settings::LinterSettings::for_rule(Rule::FutureRequiredTypeAnnotation)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -23,7 +23,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::FStringInGetTextFuncCall, Path::new("INT001.py"))] #[test_case(Rule::FStringInGetTextFuncCall, Path::new("INT001.py"))]
#[test_case(Rule::FormatInGetTextFuncCall, Path::new("INT002.py"))] #[test_case(Rule::FormatInGetTextFuncCall, Path::new("INT002.py"))]
@ -34,7 +34,7 @@ mod tests {
Path::new("flake8_gettext").join(path).as_path(), Path::new("flake8_gettext").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::SingleLineImplicitStringConcatenation, Path::new("ISC.py"))] #[test_case(Rule::SingleLineImplicitStringConcatenation, Path::new("ISC.py"))]
#[test_case(Rule::MultiLineImplicitStringConcatenation, Path::new("ISC.py"))] #[test_case(Rule::MultiLineImplicitStringConcatenation, Path::new("ISC.py"))]
@ -30,7 +30,7 @@ mod tests {
Path::new("flake8_implicit_str_concat").join(path).as_path(), Path::new("flake8_implicit_str_concat").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -52,7 +52,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::flake8_import_conventions::settings::{BannedAliases, default_aliases}; use crate::rules::flake8_import_conventions::settings::{BannedAliases, default_aliases};
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
@ -21,7 +21,7 @@ mod tests {
Path::new("flake8_import_conventions/defaults.py"), Path::new("flake8_import_conventions/defaults.py"),
&LinterSettings::for_rule(Rule::UnconventionalImportAlias), &LinterSettings::for_rule(Rule::UnconventionalImportAlias),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -43,7 +43,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnconventionalImportAlias) ..LinterSettings::for_rule(Rule::UnconventionalImportAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -77,7 +77,7 @@ mod tests {
..LinterSettings::for_rule(Rule::BannedImportAlias) ..LinterSettings::for_rule(Rule::BannedImportAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -98,7 +98,7 @@ mod tests {
..LinterSettings::for_rule(Rule::BannedImportFrom) ..LinterSettings::for_rule(Rule::BannedImportFrom)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -120,7 +120,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnconventionalImportAlias) ..LinterSettings::for_rule(Rule::UnconventionalImportAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -143,7 +143,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnconventionalImportAlias) ..LinterSettings::for_rule(Rule::UnconventionalImportAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -169,7 +169,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnconventionalImportAlias) ..LinterSettings::for_rule(Rule::UnconventionalImportAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -179,7 +179,7 @@ mod tests {
Path::new("flake8_import_conventions/tricky.py"), Path::new("flake8_import_conventions/tricky.py"),
&LinterSettings::for_rule(Rule::UnconventionalImportAlias), &LinterSettings::for_rule(Rule::UnconventionalImportAlias),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -201,7 +201,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnconventionalImportAlias) ..LinterSettings::for_rule(Rule::UnconventionalImportAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -8,7 +8,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::test_path; use crate::test::test_path;
@ -28,7 +28,7 @@ mod tests {
Path::new("flake8_logging").join(path).as_path(), Path::new("flake8_logging").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Path::new("G_argparse_parser_error_ok.py"))] #[test_case(Path::new("G_argparse_parser_error_ok.py"))]
#[test_case(Path::new("G_extra_ok.py"))] #[test_case(Path::new("G_extra_ok.py"))]
@ -45,7 +45,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::{test_path, test_resource_path}; use crate::test::{test_path, test_resource_path};
@ -40,7 +40,7 @@ mod tests {
}, },
)?; )?;
insta::with_settings!({filters => vec![(r"\\", "/")]}, { insta::with_settings!({filters => vec![(r"\\", "/")]}, {
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
}); });
Ok(()) Ok(())
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::DuplicateClassFieldDefinition, Path::new("PIE794.py"))] #[test_case(Rule::DuplicateClassFieldDefinition, Path::new("PIE794.py"))]
#[test_case(Rule::UnnecessaryDictKwargs, Path::new("PIE804.py"))] #[test_case(Rule::UnnecessaryDictKwargs, Path::new("PIE804.py"))]
@ -27,7 +27,7 @@ mod tests {
Path::new("flake8_pie").join(path).as_path(), Path::new("flake8_pie").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::Print, Path::new("T201.py"))] #[test_case(Rule::Print, Path::new("T201.py"))]
#[test_case(Rule::PPrint, Path::new("T203.py"))] #[test_case(Rule::PPrint, Path::new("T203.py"))]
@ -20,7 +20,7 @@ mod tests {
Path::new("flake8_print").join(path).as_path(), Path::new("flake8_print").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -12,7 +12,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::pep8_naming; use crate::rules::pep8_naming;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::AnyEqNeAnnotation, Path::new("PYI032.py"))] #[test_case(Rule::AnyEqNeAnnotation, Path::new("PYI032.py"))]
#[test_case(Rule::AnyEqNeAnnotation, Path::new("PYI032.pyi"))] #[test_case(Rule::AnyEqNeAnnotation, Path::new("PYI032.pyi"))]
@ -132,7 +132,7 @@ mod tests {
Path::new("flake8_pyi").join(path).as_path(), Path::new("flake8_pyi").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -151,7 +151,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -168,7 +168,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -13,7 +13,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::types::IdentifierPattern; use crate::settings::types::IdentifierPattern;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
use super::settings::Settings; use super::settings::Settings;
use super::types; use super::types;
@ -354,7 +354,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(name, diagnostics); assert_diagnostics!(name, diagnostics);
Ok(()) Ok(())
} }
@ -373,7 +373,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!("PT006_and_PT007", diagnostics); assert_diagnostics!("PT006_and_PT007", diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::test_path; use crate::test::test_path;
@ -46,7 +46,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -65,7 +65,7 @@ mod tests {
.with_target_version(PythonVersion::PY311) .with_target_version(PythonVersion::PY311)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -84,7 +84,7 @@ mod tests {
.with_target_version(PythonVersion::PY311) .with_target_version(PythonVersion::PY311)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -116,7 +116,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -154,7 +154,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -192,7 +192,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -211,7 +211,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::BadQuotesInlineString]) ..LinterSettings::for_rules(vec![Rule::BadQuotesInlineString])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -230,7 +230,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::BadQuotesMultilineString]) ..LinterSettings::for_rules(vec![Rule::BadQuotesMultilineString])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -249,7 +249,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::BadQuotesDocstring]) ..LinterSettings::for_rules(vec![Rule::BadQuotesDocstring])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::UnnecessaryParenOnRaiseException, Path::new("RSE102.py"))] #[test_case(Rule::UnnecessaryParenOnRaiseException, Path::new("RSE102.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> { fn rules(rule_code: Rule, path: &Path) -> Result<()> {
@ -19,7 +19,7 @@ mod tests {
Path::new("flake8_raise").join(path).as_path(), Path::new("flake8_raise").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::test_path; use crate::test::test_path;
@ -30,7 +30,7 @@ mod tests {
Path::new("flake8_return").join(path).as_path(), Path::new("flake8_return").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::flake8_self; use crate::rules::flake8_self;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
use anyhow::Result; use anyhow::Result;
use ruff_python_ast::name::Name; use ruff_python_ast::name::Name;
use test_case::test_case; use test_case::test_case;
@ -22,7 +22,7 @@ mod tests {
Path::new("flake8_self").join(path).as_path(), Path::new("flake8_self").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -37,7 +37,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::PrivateMemberAccess) ..settings::LinterSettings::for_rule(Rule::PrivateMemberAccess)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -12,7 +12,7 @@ mod tests {
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::settings::types::PreviewMode; use crate::settings::types::PreviewMode;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::DuplicateIsinstanceCall, Path::new("SIM101.py"))] #[test_case(Rule::DuplicateIsinstanceCall, Path::new("SIM101.py"))]
#[test_case(Rule::CollapsibleIf, Path::new("SIM102.py"))] #[test_case(Rule::CollapsibleIf, Path::new("SIM102.py"))]
@ -54,7 +54,7 @@ mod tests {
Path::new("flake8_simplify").join(path).as_path(), Path::new("flake8_simplify").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -72,7 +72,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::NoSlotsInStrSubclass, Path::new("SLOT000.py"))] #[test_case(Rule::NoSlotsInStrSubclass, Path::new("SLOT000.py"))]
#[test_case(Rule::NoSlotsInTupleSubclass, Path::new("SLOT001.py"))] #[test_case(Rule::NoSlotsInTupleSubclass, Path::new("SLOT001.py"))]
@ -21,7 +21,7 @@ mod tests {
Path::new("flake8_slots").join(path).as_path(), Path::new("flake8_slots").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -10,7 +10,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::flake8_tidy_imports; use crate::rules::flake8_tidy_imports;
use crate::rules::flake8_tidy_imports::settings::{ApiBan, Strictness}; use crate::rules::flake8_tidy_imports::settings::{ApiBan, Strictness};
@ -42,7 +42,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::BannedApi]) ..LinterSettings::for_rules(vec![Rule::BannedApi])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -72,7 +72,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::BannedApi]) ..LinterSettings::for_rules(vec![Rule::BannedApi])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -88,7 +88,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::RelativeImports]) ..LinterSettings::for_rules(vec![Rule::RelativeImports])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -104,7 +104,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::RelativeImports]) ..LinterSettings::for_rules(vec![Rule::RelativeImports])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -121,7 +121,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::RelativeImports]) ..LinterSettings::for_rules(vec![Rule::RelativeImports])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -140,7 +140,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::BannedModuleLevelImports]) ..LinterSettings::for_rules(vec![Rule::BannedModuleLevelImports])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::InvalidTodoTag, Path::new("TD001.py"))] #[test_case(Rule::InvalidTodoTag, Path::new("TD001.py"))]
#[test_case(Rule::MissingTodoAuthor, Path::new("TD002.py"))] #[test_case(Rule::MissingTodoAuthor, Path::new("TD002.py"))]
@ -24,7 +24,7 @@ mod tests {
Path::new("flake8_todos").join(path).as_path(), Path::new("flake8_todos").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -14,7 +14,7 @@ mod tests {
use crate::registry::{Linter, Rule}; use crate::registry::{Linter, Rule};
use crate::test::{test_path, test_snippet}; use crate::test::{test_path, test_snippet};
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::EmptyTypeCheckingBlock, Path::new("TC005.py"))] #[test_case(Rule::EmptyTypeCheckingBlock, Path::new("TC005.py"))]
#[test_case(Rule::RuntimeCastValue, Path::new("TC006.py"))] #[test_case(Rule::RuntimeCastValue, Path::new("TC006.py"))]
@ -59,7 +59,7 @@ mod tests {
Path::new("flake8_type_checking").join(path).as_path(), Path::new("flake8_type_checking").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -77,7 +77,7 @@ mod tests {
Rule::QuotedTypeAlias, Rule::QuotedTypeAlias,
]), ]),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -91,7 +91,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -113,7 +113,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -132,7 +132,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -148,7 +148,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -177,7 +177,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -216,7 +216,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -248,7 +248,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -270,7 +270,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -297,7 +297,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -518,7 +518,7 @@ mod tests {
contents, contents,
&settings::LinterSettings::for_rules(Linter::Flake8TypeChecking.rules()), &settings::LinterSettings::for_rules(Linter::Flake8TypeChecking.rules()),
); );
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
} }
#[test_case( #[test_case(
@ -570,6 +570,6 @@ mod tests {
..settings::LinterSettings::for_rules(Linter::Flake8TypeChecking.rules()) ..settings::LinterSettings::for_rules(Linter::Flake8TypeChecking.rules())
}, },
); );
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::UnusedFunctionArgument, Path::new("ARG.py"))] #[test_case(Rule::UnusedFunctionArgument, Path::new("ARG.py"))]
#[test_case(Rule::UnusedMethodArgument, Path::new("ARG.py"))] #[test_case(Rule::UnusedMethodArgument, Path::new("ARG.py"))]
@ -24,7 +24,7 @@ mod tests {
Path::new("flake8_unused_arguments").join(path).as_path(), Path::new("flake8_unused_arguments").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -45,7 +45,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -66,7 +66,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings; use crate::settings;
use crate::test::test_path; use crate::test::test_path;
@ -50,7 +50,7 @@ mod tests {
Rule::BuiltinOpen, Rule::BuiltinOpen,
]), ]),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -73,7 +73,7 @@ mod tests {
Path::new("flake8_use_pathlib").join(path).as_path(), Path::new("flake8_use_pathlib").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::StaticJoinToFString, Path::new("FLY002.py"))] #[test_case(Rule::StaticJoinToFString, Path::new("FLY002.py"))]
fn rules(rule_code: Rule, path: &Path) -> Result<()> { fn rules(rule_code: Rule, path: &Path) -> Result<()> {
@ -20,7 +20,7 @@ mod tests {
Path::new("flynt").join(path).as_path(), Path::new("flynt").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -292,7 +292,7 @@ mod tests {
use ruff_python_semantic::{MemberNameImport, ModuleNameImport, NameImport}; use ruff_python_semantic::{MemberNameImport, ModuleNameImport, NameImport};
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::isort::categorize::{ImportSection, KnownModules}; use crate::rules::isort::categorize::{ImportSection, KnownModules};
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
@ -363,7 +363,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -391,7 +391,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -415,7 +415,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -439,7 +439,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -454,7 +454,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
crate::assert_messages!(snapshot, diagnostics); crate::assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -478,7 +478,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -503,7 +503,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -521,7 +521,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -545,7 +545,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -563,7 +563,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -582,7 +582,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -600,7 +600,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -622,7 +622,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -640,7 +640,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -659,7 +659,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -687,7 +687,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -717,7 +717,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -745,7 +745,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -767,7 +767,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -787,7 +787,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -820,7 +820,7 @@ mod tests {
..LinterSettings::for_rule(Rule::MissingRequiredImport) ..LinterSettings::for_rule(Rule::MissingRequiredImport)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -854,7 +854,7 @@ mod tests {
..LinterSettings::for_rule(Rule::MissingRequiredImport) ..LinterSettings::for_rule(Rule::MissingRequiredImport)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -882,7 +882,7 @@ mod tests {
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -905,7 +905,7 @@ mod tests {
..LinterSettings::for_rules([Rule::MissingRequiredImport, Rule::UselessImportAlias]) ..LinterSettings::for_rules([Rule::MissingRequiredImport, Rule::UselessImportAlias])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -935,7 +935,7 @@ mod tests {
..LinterSettings::for_rule(Rule::MissingRequiredImport) ..LinterSettings::for_rule(Rule::MissingRequiredImport)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -958,7 +958,7 @@ mod tests {
..LinterSettings::for_rule(Rule::MissingRequiredImport) ..LinterSettings::for_rule(Rule::MissingRequiredImport)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -992,7 +992,7 @@ mod tests {
..LinterSettings::for_rules([Rule::MissingRequiredImport, Rule::UnusedImport]) ..LinterSettings::for_rules([Rule::MissingRequiredImport, Rule::UnusedImport])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1011,7 +1011,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1029,7 +1029,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1047,7 +1047,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1082,7 +1082,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1106,7 +1106,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1131,7 +1131,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1156,7 +1156,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1178,7 +1178,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1199,7 +1199,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(&*snapshot, diagnostics); assert_diagnostics!(&*snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1218,7 +1218,7 @@ mod tests {
}, },
)?; )?;
diagnostics.sort_by_key(Ranged::start); diagnostics.sort_by_key(Ranged::start);
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1241,7 +1241,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1274,7 +1274,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1306,7 +1306,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1330,7 +1330,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1347,7 +1347,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -1364,7 +1364,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -1387,7 +1387,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -1407,7 +1407,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnsortedImports) ..LinterSettings::for_rule(Rule::UnsortedImports)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use anyhow::Result; use anyhow::Result;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::test::test_path; use crate::test::test_path;
@ -26,7 +26,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::ComplexStructure]) ..LinterSettings::for_rules(vec![Rule::ComplexStructure])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::NumpyDeprecatedTypeAlias, Path::new("NPY001.py"))] #[test_case(Rule::NumpyDeprecatedTypeAlias, Path::new("NPY001.py"))]
#[test_case(Rule::NumpyLegacyRandom, Path::new("NPY002.py"))] #[test_case(Rule::NumpyLegacyRandom, Path::new("NPY002.py"))]
@ -26,7 +26,7 @@ mod tests {
Path::new("numpy").join(path).as_path(), Path::new("numpy").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::{Linter, Rule}; use crate::registry::{Linter, Rule};
use crate::test::{test_path, test_snippet}; use crate::test::{test_path, test_snippet};
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case( #[test_case(
r#" r#"
@ -355,7 +355,7 @@ mod tests {
contents, contents,
&settings::LinterSettings::for_rules(Linter::PandasVet.rules()), &settings::LinterSettings::for_rules(Linter::PandasVet.rules()),
); );
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
} }
#[test_case( #[test_case(
@ -370,7 +370,7 @@ mod tests {
Path::new("pandas_vet").join(path).as_path(), Path::new("pandas_vet").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -15,7 +15,7 @@ mod tests {
use crate::rules::pep8_naming::settings::IgnoreNames; use crate::rules::pep8_naming::settings::IgnoreNames;
use crate::rules::{flake8_import_conventions, pep8_naming}; use crate::rules::{flake8_import_conventions, pep8_naming};
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::InvalidClassName, Path::new("N801.py"))] #[test_case(Rule::InvalidClassName, Path::new("N801.py"))]
#[test_case(Rule::InvalidFunctionName, Path::new("N802.py"))] #[test_case(Rule::InvalidFunctionName, Path::new("N802.py"))]
@ -85,7 +85,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -104,7 +104,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::CamelcaseImportedAsAcronym) ..settings::LinterSettings::for_rule(Rule::CamelcaseImportedAsAcronym)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -124,7 +124,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::InvalidFirstArgumentNameForMethod) ..settings::LinterSettings::for_rule(Rule::InvalidFirstArgumentNameForMethod)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -143,7 +143,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::InvalidFirstArgumentNameForMethod) ..settings::LinterSettings::for_rule(Rule::InvalidFirstArgumentNameForMethod)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -181,7 +181,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -9,7 +9,7 @@ mod tests {
use ruff_python_ast::PythonVersion; use ruff_python_ast::PythonVersion;
use test_case::test_case; use test_case::test_case;
use crate::assert_messages; use crate::assert_diagnostics;
use crate::registry::Rule; use crate::registry::Rule;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::settings::types::PreviewMode; use crate::settings::types::PreviewMode;
@ -27,7 +27,7 @@ mod tests {
Path::new("perflint").join(path).as_path(), Path::new("perflint").join(path).as_path(),
&LinterSettings::for_rule(rule_code).with_target_version(PythonVersion::PY310), &LinterSettings::for_rule(rule_code).with_target_version(PythonVersion::PY310),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -48,7 +48,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -19,7 +19,7 @@ mod tests {
use crate::rules::{isort, pycodestyle}; use crate::rules::{isort, pycodestyle};
use crate::settings::types::PreviewMode; use crate::settings::types::PreviewMode;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
use super::settings::Settings; use super::settings::Settings;
@ -71,7 +71,7 @@ mod tests {
Path::new("pycodestyle").join(path).as_path(), Path::new("pycodestyle").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -95,7 +95,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -106,7 +106,7 @@ mod tests {
&settings::LinterSettings::for_rule(Rule::MissingNewlineAtEndOfFile), &settings::LinterSettings::for_rule(Rule::MissingNewlineAtEndOfFile),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -155,7 +155,7 @@ mod tests {
Path::new("pycodestyle").join(path).as_path(), Path::new("pycodestyle").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -172,7 +172,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -190,7 +190,7 @@ mod tests {
Path::new("pycodestyle").join(path).as_path(), Path::new("pycodestyle").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -214,7 +214,7 @@ mod tests {
Path::new("pycodestyle").join(path).as_path(), Path::new("pycodestyle").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -244,7 +244,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -274,7 +274,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -290,7 +290,7 @@ mod tests {
Path::new("pycodestyle").join("E30.pyi"), Path::new("pycodestyle").join("E30.pyi"),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -306,7 +306,7 @@ mod tests {
Path::new("pycodestyle").join("E30.ipynb"), Path::new("pycodestyle").join("E30.ipynb"),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -322,7 +322,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -336,7 +336,7 @@ mod tests {
Rule::IsLiteral, Rule::IsLiteral,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -351,7 +351,7 @@ mod tests {
Rule::MultipleLeadingHashesForBlockComment, Rule::MultipleLeadingHashesForBlockComment,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -369,7 +369,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::LineTooLong) ..settings::LinterSettings::for_rule(Rule::LineTooLong)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -385,7 +385,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::DocLineTooLong) ..settings::LinterSettings::for_rule(Rule::DocLineTooLong)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -401,7 +401,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::DocLineTooLong) ..settings::LinterSettings::for_rule(Rule::DocLineTooLong)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -422,7 +422,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::LineTooLong) ..settings::LinterSettings::for_rule(Rule::LineTooLong)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -13,7 +13,7 @@ mod tests {
use crate::rules::pydocstyle; use crate::rules::pydocstyle;
use crate::rules::pydocstyle::settings::Convention; use crate::rules::pydocstyle::settings::Convention;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
use super::settings::Settings; use super::settings::Settings;
@ -24,7 +24,7 @@ mod tests {
Path::new("pydoclint").join(path).as_path(), Path::new("pydoclint").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -46,7 +46,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -68,7 +68,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -94,7 +94,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -14,7 +14,7 @@ mod tests {
use super::settings::{Convention, Settings}; use super::settings::{Convention, Settings};
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::MissingBlankLineAfterLastSection, Path::new("sections.py"))] #[test_case(Rule::MissingBlankLineAfterLastSection, Path::new("sections.py"))]
#[test_case(Rule::NoBlankLineAfterSection, Path::new("sections.py"))] #[test_case(Rule::NoBlankLineAfterSection, Path::new("sections.py"))]
@ -109,7 +109,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -119,7 +119,7 @@ mod tests {
Path::new("pydocstyle/bom.py"), Path::new("pydocstyle/bom.py"),
&settings::LinterSettings::for_rule(Rule::TripleSingleQuotes), &settings::LinterSettings::for_rule(Rule::TripleSingleQuotes),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -134,7 +134,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::UndocumentedParam) ..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -147,7 +147,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::UndocumentedParam) ..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -164,7 +164,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::UndocumentedParam) ..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -181,7 +181,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::UndocumentedParam) ..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -198,7 +198,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::UndocumentedParam) ..settings::LinterSettings::for_rule(Rule::UndocumentedParam)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -211,7 +211,7 @@ mod tests {
Rule::MissingTrailingPeriod, Rule::MissingTrailingPeriod,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -230,7 +230,7 @@ mod tests {
Rule::UndocumentedPublicInit, Rule::UndocumentedPublicInit,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -21,9 +21,7 @@ mod tests {
use ruff_python_trivia::textwrap::dedent; use ruff_python_trivia::textwrap::dedent;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::Locator;
use crate::linter::check_path; use crate::linter::check_path;
use crate::message::Message;
use crate::registry::{Linter, Rule}; use crate::registry::{Linter, Rule};
use crate::rules::isort; use crate::rules::isort;
use crate::rules::pyflakes; use crate::rules::pyflakes;
@ -31,7 +29,7 @@ mod tests {
use crate::settings::{LinterSettings, flags}; use crate::settings::{LinterSettings, flags};
use crate::source_kind::SourceKind; use crate::source_kind::SourceKind;
use crate::test::{test_contents, test_path, test_snippet}; use crate::test::{test_contents, test_path, test_snippet};
use crate::{assert_messages, directives}; use crate::{Locator, OldDiagnostic, assert_diagnostics, directives};
#[test_case(Rule::UnusedImport, Path::new("F401_0.py"))] #[test_case(Rule::UnusedImport, Path::new("F401_0.py"))]
#[test_case(Rule::UnusedImport, Path::new("F401_1.py"))] #[test_case(Rule::UnusedImport, Path::new("F401_1.py"))]
@ -187,7 +185,7 @@ mod tests {
Path::new("pyflakes").join(path).as_path(), Path::new("pyflakes").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -210,7 +208,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -223,7 +221,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UndefinedName) ..LinterSettings::for_rule(Rule::UndefinedName)
}, },
); );
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
} }
#[test_case(Rule::UnusedImport, Path::new("__init__.py"))] #[test_case(Rule::UnusedImport, Path::new("__init__.py"))]
@ -247,7 +245,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -286,7 +284,7 @@ mod tests {
}, },
) )
.0; .0;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
} }
// Regression test for https://github.com/astral-sh/ruff/issues/12897 // Regression test for https://github.com/astral-sh/ruff/issues/12897
@ -314,7 +312,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}; };
let diagnostics = test_path(Path::new("pyflakes").join(path).as_path(), &settings)?; let diagnostics = test_path(Path::new("pyflakes").join(path).as_path(), &settings)?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -334,7 +332,7 @@ mod tests {
Path::new("pyflakes").join(path).as_path(), Path::new("pyflakes").join(path).as_path(),
&LinterSettings::for_rule(rule_code), &LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -358,7 +356,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -374,7 +372,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -387,7 +385,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnusedVariable) ..LinterSettings::for_rule(Rule::UnusedVariable)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -401,7 +399,7 @@ mod tests {
Rule::UnusedImport, Rule::UnusedImport,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -411,7 +409,7 @@ mod tests {
Path::new("pyflakes/builtins.py"), Path::new("pyflakes/builtins.py"),
&LinterSettings::for_rules(vec![Rule::UndefinedName]), &LinterSettings::for_rules(vec![Rule::UndefinedName]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -424,7 +422,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::UndefinedName]) ..LinterSettings::for_rules(vec![Rule::UndefinedName])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -434,7 +432,7 @@ mod tests {
Path::new("pyflakes/typing_modules.py"), Path::new("pyflakes/typing_modules.py"),
&LinterSettings::for_rules(vec![Rule::UndefinedName]), &LinterSettings::for_rules(vec![Rule::UndefinedName]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -447,7 +445,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::UndefinedName]) ..LinterSettings::for_rules(vec![Rule::UndefinedName])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -457,7 +455,7 @@ mod tests {
Path::new("pyflakes/future_annotations.py"), Path::new("pyflakes/future_annotations.py"),
&LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UndefinedName]), &LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UndefinedName]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -467,7 +465,7 @@ mod tests {
Path::new("pyflakes/multi_statement_lines.py"), Path::new("pyflakes/multi_statement_lines.py"),
&LinterSettings::for_rule(Rule::UnusedImport), &LinterSettings::for_rule(Rule::UnusedImport),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -480,7 +478,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UndefinedName) ..LinterSettings::for_rule(Rule::UndefinedName)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -493,7 +491,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UndefinedName) ..LinterSettings::for_rule(Rule::UndefinedName)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -510,7 +508,7 @@ mod tests {
..LinterSettings::for_rule(Rule::UnusedImport) ..LinterSettings::for_rule(Rule::UnusedImport)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -734,7 +732,7 @@ mod tests {
contents, contents,
&LinterSettings::for_rules(Linter::Pyflakes.rules()), &LinterSettings::for_rules(Linter::Pyflakes.rules()),
); );
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
} }
/// A re-implementation of the Pyflakes test runner. /// A re-implementation of the Pyflakes test runner.
@ -776,10 +774,9 @@ mod tests {
messages.sort_by_key(Ranged::start); messages.sort_by_key(Ranged::start);
let actual = messages let actual = messages
.iter() .iter()
.filter(|msg| !msg.is_syntax_error()) .filter_map(OldDiagnostic::noqa_code)
.map(Message::name)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let expected: Vec<_> = expected.iter().map(|rule| rule.name().as_str()).collect(); let expected: Vec<_> = expected.iter().map(Rule::noqa_code).collect();
assert_eq!(actual, expected); assert_eq!(actual, expected);
} }

View file

@ -11,7 +11,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::BlanketTypeIgnore, Path::new("PGH003_0.py"))] #[test_case(Rule::BlanketTypeIgnore, Path::new("PGH003_0.py"))]
#[test_case(Rule::BlanketTypeIgnore, Path::new("PGH003_1.py"))] #[test_case(Rule::BlanketTypeIgnore, Path::new("PGH003_1.py"))]
@ -26,7 +26,7 @@ mod tests {
Path::new("pygrep_hooks").join(path).as_path(), Path::new("pygrep_hooks").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -16,7 +16,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::rules::{flake8_tidy_imports, pylint}; use crate::rules::{flake8_tidy_imports, pylint};
use crate::assert_messages; use crate::assert_diagnostics;
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::settings::types::PreviewMode; use crate::settings::types::PreviewMode;
use crate::test::test_path; use crate::test::test_path;
@ -246,7 +246,7 @@ mod tests {
..LinterSettings::for_rule(rule_code) ..LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -257,7 +257,7 @@ mod tests {
&LinterSettings::for_rule(Rule::ContinueInFinally) &LinterSettings::for_rule(Rule::ContinueInFinally)
.with_target_version(PythonVersion::PY37), .with_target_version(PythonVersion::PY37),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -273,7 +273,7 @@ mod tests {
..LinterSettings::for_rule(Rule::MagicValueComparison) ..LinterSettings::for_rule(Rule::MagicValueComparison)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -289,7 +289,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TooManyArguments) ..LinterSettings::for_rule(Rule::TooManyArguments)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -302,7 +302,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TooManyArguments) ..LinterSettings::for_rule(Rule::TooManyArguments)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -318,7 +318,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TooManyPositionalArguments) ..LinterSettings::for_rule(Rule::TooManyPositionalArguments)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -334,7 +334,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TooManyBranches) ..LinterSettings::for_rule(Rule::TooManyBranches)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -350,7 +350,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TooManyBooleanExpressions) ..LinterSettings::for_rule(Rule::TooManyBooleanExpressions)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -366,7 +366,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TooManyStatements) ..LinterSettings::for_rule(Rule::TooManyStatements)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -382,7 +382,7 @@ mod tests {
..LinterSettings::for_rule(Rule::TooManyReturnStatements) ..LinterSettings::for_rule(Rule::TooManyReturnStatements)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -398,7 +398,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::TooManyPublicMethods]) ..LinterSettings::for_rules(vec![Rule::TooManyPublicMethods])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -414,7 +414,7 @@ mod tests {
..LinterSettings::for_rules(vec![Rule::TooManyLocals]) ..LinterSettings::for_rules(vec![Rule::TooManyLocals])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -438,7 +438,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -17,7 +17,7 @@ mod tests {
use crate::rules::pyupgrade; use crate::rules::pyupgrade;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::ConvertNamedTupleFunctionalToClass, Path::new("UP014.py"))] #[test_case(Rule::ConvertNamedTupleFunctionalToClass, Path::new("UP014.py"))]
#[test_case(Rule::ConvertTypedDictFunctionalToClass, Path::new("UP013.py"))] #[test_case(Rule::ConvertTypedDictFunctionalToClass, Path::new("UP013.py"))]
@ -118,7 +118,7 @@ mod tests {
Path::new("pyupgrade").join(path).as_path(), Path::new("pyupgrade").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -131,7 +131,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::TimeoutErrorAlias) ..settings::LinterSettings::for_rule(Rule::TimeoutErrorAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -144,7 +144,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::NonPEP695TypeAlias) ..settings::LinterSettings::for_rule(Rule::NonPEP695TypeAlias)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -160,7 +160,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation) ..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -176,7 +176,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation) ..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -189,7 +189,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation) ..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -202,7 +202,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation) ..settings::LinterSettings::for_rule(Rule::NonPEP585Annotation)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -218,7 +218,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -234,7 +234,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -247,7 +247,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::DatetimeTimezoneUTC) ..settings::LinterSettings::for_rule(Rule::DatetimeTimezoneUTC)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -260,7 +260,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::NonPEP646Unpack) ..settings::LinterSettings::for_rule(Rule::NonPEP646Unpack)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -13,7 +13,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::ReadWholeFile, Path::new("FURB101.py"))] #[test_case(Rule::ReadWholeFile, Path::new("FURB101.py"))]
#[test_case(Rule::RepeatedAppend, Path::new("FURB113.py"))] #[test_case(Rule::RepeatedAppend, Path::new("FURB113.py"))]
@ -58,7 +58,7 @@ mod tests {
Path::new("refurb").join(path).as_path(), Path::new("refurb").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -69,7 +69,7 @@ mod tests {
&settings::LinterSettings::for_rule(Rule::WriteWholeFile) &settings::LinterSettings::for_rule(Rule::WriteWholeFile)
.with_target_version(PythonVersion::PY39), .with_target_version(PythonVersion::PY39),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -80,7 +80,7 @@ mod tests {
&settings::LinterSettings::for_rule(Rule::FStringNumberFormat) &settings::LinterSettings::for_rule(Rule::FStringNumberFormat)
.with_target_version(PythonVersion::PY311), .with_target_version(PythonVersion::PY311),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -21,7 +21,7 @@ mod tests {
use crate::settings::LinterSettings; use crate::settings::LinterSettings;
use crate::settings::types::{CompiledPerFileIgnoreList, PerFileIgnore, PreviewMode}; use crate::settings::types::{CompiledPerFileIgnoreList, PerFileIgnore, PreviewMode};
use crate::test::{test_path, test_resource_path}; use crate::test::{test_path, test_resource_path};
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::CollectionLiteralConcatenation, Path::new("RUF005.py"))] #[test_case(Rule::CollectionLiteralConcatenation, Path::new("RUF005.py"))]
#[test_case(Rule::CollectionLiteralConcatenation, Path::new("RUF005_slices.py"))] #[test_case(Rule::CollectionLiteralConcatenation, Path::new("RUF005_slices.py"))]
@ -119,7 +119,7 @@ mod tests {
Path::new("ruff").join(path).as_path(), Path::new("ruff").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -134,7 +134,7 @@ mod tests {
..LinterSettings::for_rule(Rule::IncorrectlyParenthesizedTupleInSubscript) ..LinterSettings::for_rule(Rule::IncorrectlyParenthesizedTupleInSubscript)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -150,7 +150,7 @@ mod tests {
..LinterSettings::for_rule(Rule::IncorrectlyParenthesizedTupleInSubscript) ..LinterSettings::for_rule(Rule::IncorrectlyParenthesizedTupleInSubscript)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -167,7 +167,7 @@ mod tests {
&settings::LinterSettings::for_rule(Rule::ImplicitOptional) &settings::LinterSettings::for_rule(Rule::ImplicitOptional)
.with_target_version(PythonVersion::PY39), .with_target_version(PythonVersion::PY39),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -184,7 +184,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -202,7 +202,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -215,7 +215,7 @@ mod tests {
Rule::AmbiguousVariableName, Rule::AmbiguousVariableName,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -236,7 +236,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -257,7 +257,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -267,7 +267,7 @@ mod tests {
Path::new("ruff/RUF100_1.py"), Path::new("ruff/RUF100_1.py"),
&settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]), &settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -284,7 +284,7 @@ mod tests {
.unwrap(); .unwrap();
let diagnostics = test_path(Path::new("ruff/RUF100_2.py"), &settings)?; let diagnostics = test_path(Path::new("ruff/RUF100_2.py"), &settings)?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -298,7 +298,7 @@ mod tests {
Rule::UndefinedName, Rule::UndefinedName,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -308,7 +308,7 @@ mod tests {
Path::new("ruff/RUF100_4.py"), Path::new("ruff/RUF100_4.py"),
&settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]), &settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA, Rule::UnusedImport]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -324,7 +324,7 @@ mod tests {
]) ])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -334,7 +334,7 @@ mod tests {
Path::new("ruff/RUF100_6.py"), Path::new("ruff/RUF100_6.py"),
&settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA]), &settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -349,7 +349,7 @@ mod tests {
Rule::UnusedVariable, Rule::UnusedVariable,
]), ]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -362,7 +362,7 @@ mod tests {
..settings::LinterSettings::for_rule(Rule::InvalidRuleCode) ..settings::LinterSettings::for_rule(Rule::InvalidRuleCode)
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -380,7 +380,7 @@ mod tests {
..settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedNOQA]) ..settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedNOQA])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -398,7 +398,7 @@ mod tests {
..settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA]) ..settings::LinterSettings::for_rules(vec![Rule::UnusedNOQA])
}, },
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -408,7 +408,7 @@ mod tests {
Path::new("ruff/flake8_noqa.py"), Path::new("ruff/flake8_noqa.py"),
&settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]), &settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -418,7 +418,7 @@ mod tests {
Path::new("ruff/ruff_noqa_all.py"), Path::new("ruff/ruff_noqa_all.py"),
&settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]), &settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -428,7 +428,7 @@ mod tests {
Path::new("ruff/ruff_noqa_codes.py"), Path::new("ruff/ruff_noqa_codes.py"),
&settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]), &settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -438,7 +438,7 @@ mod tests {
Path::new("ruff/ruff_noqa_invalid.py"), Path::new("ruff/ruff_noqa_invalid.py"),
&settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]), &settings::LinterSettings::for_rules(vec![Rule::UnusedImport, Rule::UnusedVariable]),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -448,7 +448,7 @@ mod tests {
Path::new("ruff/redirects.py"), Path::new("ruff/redirects.py"),
&settings::LinterSettings::for_rule(Rule::NonPEP604AnnotationUnion), &settings::LinterSettings::for_rule(Rule::NonPEP604AnnotationUnion),
)?; )?;
assert_messages!(diagnostics); assert_diagnostics!(diagnostics);
Ok(()) Ok(())
} }
@ -470,7 +470,7 @@ mod tests {
&source_file, &source_file,
&settings::LinterSettings::for_rule(Rule::InvalidPyprojectToml), &settings::LinterSettings::for_rule(Rule::InvalidPyprojectToml),
); );
assert_messages!(snapshot, messages); assert_diagnostics!(snapshot, messages);
Ok(()) Ok(())
} }
@ -495,7 +495,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
@ -523,7 +523,7 @@ mod tests {
..settings::LinterSettings::for_rule(rule_code) ..settings::LinterSettings::for_rule(rule_code)
}, },
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -12,7 +12,7 @@ mod tests {
use crate::registry::Rule; use crate::registry::Rule;
use crate::test::test_path; use crate::test::test_path;
use crate::{assert_messages, settings}; use crate::{assert_diagnostics, settings};
#[test_case(Rule::RaiseVanillaClass, Path::new("TRY002.py"))] #[test_case(Rule::RaiseVanillaClass, Path::new("TRY002.py"))]
#[test_case(Rule::RaiseVanillaArgs, Path::new("TRY003.py"))] #[test_case(Rule::RaiseVanillaArgs, Path::new("TRY003.py"))]
@ -29,7 +29,7 @@ mod tests {
Path::new("tryceratops").join(path).as_path(), Path::new("tryceratops").join(path).as_path(),
&settings::LinterSettings::for_rule(rule_code), &settings::LinterSettings::for_rule(rule_code),
)?; )?;
assert_messages!(snapshot, diagnostics); assert_diagnostics!(snapshot, diagnostics);
Ok(()) Ok(())
} }
} }

View file

@ -23,7 +23,7 @@ use ruff_source_file::SourceFileBuilder;
use crate::codes::Rule; use crate::codes::Rule;
use crate::fix::{FixResult, fix_file}; use crate::fix::{FixResult, fix_file};
use crate::linter::check_path; use crate::linter::check_path;
use crate::message::{Emitter, EmitterContext, Message, TextEmitter}; use crate::message::{Emitter, EmitterContext, OldDiagnostic, TextEmitter};
use crate::package::PackageRoot; use crate::package::PackageRoot;
use crate::packaging::detect_package_root; use crate::packaging::detect_package_root;
use crate::settings::types::UnsafeFixes; use crate::settings::types::UnsafeFixes;
@ -39,7 +39,10 @@ pub(crate) fn test_resource_path(path: impl AsRef<Path>) -> std::path::PathBuf {
/// Run [`check_path`] on a Python file in the `resources/test/fixtures` directory. /// Run [`check_path`] on a Python file in the `resources/test/fixtures` directory.
#[cfg(not(fuzzing))] #[cfg(not(fuzzing))]
pub(crate) fn test_path(path: impl AsRef<Path>, settings: &LinterSettings) -> Result<Vec<Message>> { pub(crate) fn test_path(
path: impl AsRef<Path>,
settings: &LinterSettings,
) -> Result<Vec<OldDiagnostic>> {
let path = test_resource_path("fixtures").join(path); let path = test_resource_path("fixtures").join(path);
let source_type = PySourceType::from(&path); let source_type = PySourceType::from(&path);
let source_kind = SourceKind::from_path(path.as_ref(), source_type)?.expect("valid source"); let source_kind = SourceKind::from_path(path.as_ref(), source_type)?.expect("valid source");
@ -48,7 +51,7 @@ pub(crate) fn test_path(path: impl AsRef<Path>, settings: &LinterSettings) -> Re
#[cfg(not(fuzzing))] #[cfg(not(fuzzing))]
pub(crate) struct TestedNotebook { pub(crate) struct TestedNotebook {
pub(crate) messages: Vec<Message>, pub(crate) diagnostics: Vec<OldDiagnostic>,
pub(crate) source_notebook: Notebook, pub(crate) source_notebook: Notebook,
pub(crate) linted_notebook: Notebook, pub(crate) linted_notebook: Notebook,
} }
@ -77,14 +80,14 @@ pub(crate) fn assert_notebook_path(
); );
Ok(TestedNotebook { Ok(TestedNotebook {
messages, diagnostics: messages,
source_notebook: source_kind.expect_ipy_notebook(), source_notebook: source_kind.expect_ipy_notebook(),
linted_notebook, linted_notebook,
}) })
} }
/// Run [`check_path`] on a snippet of Python code. /// Run [`check_path`] on a snippet of Python code.
pub fn test_snippet(contents: &str, settings: &LinterSettings) -> Vec<Message> { pub fn test_snippet(contents: &str, settings: &LinterSettings) -> Vec<OldDiagnostic> {
let path = Path::new("<filename>"); let path = Path::new("<filename>");
let contents = dedent(contents); let contents = dedent(contents);
test_contents(&SourceKind::Python(contents.into_owned()), path, settings).0 test_contents(&SourceKind::Python(contents.into_owned()), path, settings).0
@ -108,7 +111,7 @@ pub(crate) fn test_contents<'a>(
source_kind: &'a SourceKind, source_kind: &'a SourceKind,
path: &Path, path: &Path,
settings: &LinterSettings, settings: &LinterSettings,
) -> (Vec<Message>, Cow<'a, SourceKind>) { ) -> (Vec<OldDiagnostic>, Cow<'a, SourceKind>) {
let source_type = PySourceType::from(path); let source_type = PySourceType::from(path);
let target_version = settings.resolve_target_version(path); let target_version = settings.resolve_target_version(path);
let options = let options =
@ -288,7 +291,7 @@ Either ensure you always emit a fix or change `Violation::FIX_AVAILABILITY` to e
diagnostic diagnostic
}) })
.chain(parsed.errors().iter().map(|parse_error| { .chain(parsed.errors().iter().map(|parse_error| {
Message::from_parse_error(parse_error, &locator, source_code.clone()) OldDiagnostic::from_parse_error(parse_error, &locator, source_code.clone())
})) }))
.sorted() .sorted()
.collect(); .collect();
@ -306,7 +309,9 @@ fn print_syntax_errors(
let messages: Vec<_> = errors let messages: Vec<_> = errors
.iter() .iter()
.map(|parse_error| Message::from_parse_error(parse_error, locator, source_file.clone())) .map(|parse_error| {
OldDiagnostic::from_parse_error(parse_error, locator, source_file.clone())
})
.collect(); .collect();
if let Some(notebook) = source.as_ipy_notebook() { if let Some(notebook) = source.as_ipy_notebook() {
@ -317,18 +322,22 @@ fn print_syntax_errors(
} }
/// Print the [`Message::Diagnostic`]s in `messages`. /// Print the [`Message::Diagnostic`]s in `messages`.
fn print_diagnostics(mut messages: Vec<Message>, path: &Path, source: &SourceKind) -> String { fn print_diagnostics(
messages.retain(|msg| !msg.is_syntax_error()); mut diagnostics: Vec<OldDiagnostic>,
path: &Path,
source: &SourceKind,
) -> String {
diagnostics.retain(|msg| !msg.is_syntax_error());
if let Some(notebook) = source.as_ipy_notebook() { if let Some(notebook) = source.as_ipy_notebook() {
print_jupyter_messages(&messages, path, notebook) print_jupyter_messages(&diagnostics, path, notebook)
} else { } else {
print_messages(&messages) print_messages(&diagnostics)
} }
} }
pub(crate) fn print_jupyter_messages( pub(crate) fn print_jupyter_messages(
messages: &[Message], diagnostics: &[OldDiagnostic],
path: &Path, path: &Path,
notebook: &Notebook, notebook: &Notebook,
) -> String { ) -> String {
@ -341,7 +350,7 @@ pub(crate) fn print_jupyter_messages(
.with_unsafe_fixes(UnsafeFixes::Enabled) .with_unsafe_fixes(UnsafeFixes::Enabled)
.emit( .emit(
&mut output, &mut output,
messages, diagnostics,
&EmitterContext::new(&FxHashMap::from_iter([( &EmitterContext::new(&FxHashMap::from_iter([(
path.file_name().unwrap().to_string_lossy().to_string(), path.file_name().unwrap().to_string_lossy().to_string(),
notebook.index().clone(), notebook.index().clone(),
@ -352,7 +361,7 @@ pub(crate) fn print_jupyter_messages(
String::from_utf8(output).unwrap() String::from_utf8(output).unwrap()
} }
pub(crate) fn print_messages(messages: &[Message]) -> String { pub(crate) fn print_messages(diagnostics: &[OldDiagnostic]) -> String {
let mut output = Vec::new(); let mut output = Vec::new();
TextEmitter::default() TextEmitter::default()
@ -362,7 +371,7 @@ pub(crate) fn print_messages(messages: &[Message]) -> String {
.with_unsafe_fixes(UnsafeFixes::Enabled) .with_unsafe_fixes(UnsafeFixes::Enabled)
.emit( .emit(
&mut output, &mut output,
messages, diagnostics,
&EmitterContext::new(&FxHashMap::default()), &EmitterContext::new(&FxHashMap::default()),
) )
.unwrap(); .unwrap();
@ -371,7 +380,7 @@ pub(crate) fn print_messages(messages: &[Message]) -> String {
} }
#[macro_export] #[macro_export]
macro_rules! assert_messages { macro_rules! assert_diagnostics {
($value:expr, $path:expr, $notebook:expr) => {{ ($value:expr, $path:expr, $notebook:expr) => {{
insta::with_settings!({ omit_expression => true }, { insta::with_settings!({ omit_expression => true }, {
insta::assert_snapshot!( insta::assert_snapshot!(

View file

@ -254,9 +254,11 @@ fn generate_rule_to_code(linter_to_rules: &BTreeMap<Ident, BTreeMap<String, Rule
} }
let mut rule_noqa_code_match_arms = quote!(); let mut rule_noqa_code_match_arms = quote!();
let mut noqa_code_rule_match_arms = quote!();
let mut rule_group_match_arms = quote!(); let mut rule_group_match_arms = quote!();
let mut noqa_code_consts = quote!();
for (rule, codes) in rule_to_codes { for (i, (rule, codes)) in rule_to_codes.into_iter().enumerate() {
let rule_name = rule.segments.last().unwrap(); let rule_name = rule.segments.last().unwrap();
assert_eq!( assert_eq!(
codes.len(), codes.len(),
@ -292,6 +294,14 @@ See also https://github.com/astral-sh/ruff/issues/2186.
#(#attrs)* Rule::#rule_name => NoqaCode(crate::registry::Linter::#linter.common_prefix(), #code), #(#attrs)* Rule::#rule_name => NoqaCode(crate::registry::Linter::#linter.common_prefix(), #code),
}); });
let const_ident = quote::format_ident!("NOQA_PREFIX_{}", i);
noqa_code_consts.extend(quote! {
const #const_ident: &str = crate::registry::Linter::#linter.common_prefix();
});
noqa_code_rule_match_arms.extend(quote! {
#(#attrs)* NoqaCode(#const_ident, #code) => Some(Rule::#rule_name),
});
rule_group_match_arms.extend(quote! { rule_group_match_arms.extend(quote! {
#(#attrs)* Rule::#rule_name => #group, #(#attrs)* Rule::#rule_name => #group,
}); });
@ -340,6 +350,16 @@ See also https://github.com/astral-sh/ruff/issues/2186.
} }
} }
} }
impl NoqaCode {
pub fn rule(&self) -> Option<Rule> {
#noqa_code_consts
match self {
#noqa_code_rule_match_arms
_ => None
}
}
}
}; };
rule_to_code rule_to_code
} }

View file

@ -118,10 +118,6 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenS
None None
} }
fn common_prefix(&self) -> &'static str {
match self { #common_prefix_match_arms }
}
fn name(&self) -> &'static str { fn name(&self) -> &'static str {
match self { #name_match_arms } match self { #name_match_arms }
} }
@ -130,6 +126,16 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenS
match self { #url_match_arms } match self { #url_match_arms }
} }
} }
impl #ident {
/// Returns the prefix that every single code that ruff uses to identify
/// rules from this linter starts with. In the case that multiple
/// `#[prefix]`es are configured for the variant in the `Linter` enum
/// definition this is the empty string.
pub const fn common_prefix(&self) -> &'static str {
match self { #common_prefix_match_arms }
}
}
}) })
} }

View file

@ -15,7 +15,7 @@ use ruff_linter::{
directives::{Flags, extract_directives}, directives::{Flags, extract_directives},
generate_noqa_edits, generate_noqa_edits,
linter::check_path, linter::check_path,
message::Message, message::OldDiagnostic,
package::PackageRoot, package::PackageRoot,
packaging::detect_package_root, packaging::detect_package_root,
settings::flags, settings::flags,
@ -122,7 +122,7 @@ pub(crate) fn check(
let directives = extract_directives(parsed.tokens(), Flags::all(), &locator, &indexer); let directives = extract_directives(parsed.tokens(), Flags::all(), &locator, &indexer);
// Generate checks. // Generate checks.
let messages = check_path( let diagnostics = check_path(
&query.virtual_file_path(), &query.virtual_file_path(),
package, package,
&locator, &locator,
@ -139,7 +139,7 @@ pub(crate) fn check(
let noqa_edits = generate_noqa_edits( let noqa_edits = generate_noqa_edits(
&query.virtual_file_path(), &query.virtual_file_path(),
&messages, &diagnostics,
&locator, &locator,
indexer.comment_ranges(), indexer.comment_ranges(),
&settings.linter.external, &settings.linter.external,
@ -162,7 +162,7 @@ pub(crate) fn check(
} }
let lsp_diagnostics = let lsp_diagnostics =
messages diagnostics
.into_iter() .into_iter()
.zip(noqa_edits) .zip(noqa_edits)
.filter_map(|(message, noqa_edit)| { .filter_map(|(message, noqa_edit)| {
@ -231,7 +231,7 @@ pub(crate) fn fixes_for_diagnostics(
/// Generates an LSP diagnostic with an associated cell index for the diagnostic to go in. /// Generates an LSP diagnostic with an associated cell index for the diagnostic to go in.
/// If the source kind is a text document, the cell index will always be `0`. /// If the source kind is a text document, the cell index will always be `0`.
fn to_lsp_diagnostic( fn to_lsp_diagnostic(
diagnostic: &Message, diagnostic: &OldDiagnostic,
noqa_edit: Option<Edit>, noqa_edit: Option<Edit>,
source_kind: &SourceKind, source_kind: &SourceKind,
index: &LineIndex, index: &LineIndex,

View file

@ -188,7 +188,7 @@ impl Workspace {
); );
// Generate checks. // Generate checks.
let messages = check_path( let diagnostics = check_path(
Path::new("<filename>"), Path::new("<filename>"),
None, None,
&locator, &locator,
@ -205,7 +205,7 @@ impl Workspace {
let source_code = locator.to_source_code(); let source_code = locator.to_source_code();
let messages: Vec<ExpandedMessage> = messages let messages: Vec<ExpandedMessage> = diagnostics
.into_iter() .into_iter()
.map(|msg| ExpandedMessage { .map(|msg| ExpandedMessage {
code: msg.noqa_code().map(|code| code.to_string()), code: msg.noqa_code().map(|code| code.to_string()),

View file

@ -22,7 +22,6 @@ use ruff_cache::cache_dir;
use ruff_formatter::IndentStyle; use ruff_formatter::IndentStyle;
use ruff_graph::{AnalyzeSettings, Direction}; use ruff_graph::{AnalyzeSettings, Direction};
use ruff_linter::line_width::{IndentWidth, LineLength}; use ruff_linter::line_width::{IndentWidth, LineLength};
use ruff_linter::registry::RuleNamespace;
use ruff_linter::registry::{INCOMPATIBLE_CODES, Rule, RuleSet}; use ruff_linter::registry::{INCOMPATIBLE_CODES, Rule, RuleSet};
use ruff_linter::rule_selector::{PreviewOptions, Specificity}; use ruff_linter::rule_selector::{PreviewOptions, Specificity};
use ruff_linter::rules::{flake8_import_conventions, isort, pycodestyle}; use ruff_linter::rules::{flake8_import_conventions, isort, pycodestyle};

View file

@ -43,7 +43,7 @@ fn do_fuzz(case: &[u8]) -> Corpus {
let mut warnings = HashMap::new(); let mut warnings = HashMap::new();
for msg in &linter_result.messages { for msg in &linter_result.diagnostics {
let count: &mut usize = warnings.entry(msg.name()).or_default(); let count: &mut usize = warnings.entry(msg.name()).or_default();
*count += 1; *count += 1;
} }
@ -67,7 +67,7 @@ fn do_fuzz(case: &[u8]) -> Corpus {
"formatter introduced a parse error" "formatter introduced a parse error"
); );
for msg in &linter_result.messages { for msg in &linter_result.diagnostics {
if let Some(count) = warnings.get_mut(msg.name()) { if let Some(count) = warnings.get_mut(msg.name()) {
if let Some(decremented) = count.checked_sub(1) { if let Some(decremented) = count.checked_sub(1) {
*count = decremented; *count = decremented;