Skip to content

Commit 4dba857

Browse files
committed
pass ParseOptions::target_version in the linter
1 parent a0efadd commit 4dba857

3 files changed

Lines changed: 42 additions & 15 deletions

File tree

crates/ruff_linter/src/linter.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ use rustc_hash::FxHashMap;
1010

1111
use ruff_diagnostics::Diagnostic;
1212
use ruff_notebook::Notebook;
13-
use ruff_python_ast::{ModModule, PySourceType};
13+
use ruff_python_ast::{ModModule, PySourceType, PythonVersion};
1414
use ruff_python_codegen::Stylist;
1515
use ruff_python_index::Indexer;
16-
use ruff_python_parser::{ParseError, Parsed, SyntaxError};
16+
use ruff_python_parser::{ParseError, ParseOptions, Parsed, SyntaxError};
1717
use ruff_source_file::SourceFileBuilder;
1818
use ruff_text_size::Ranged;
1919

@@ -330,7 +330,8 @@ pub fn add_noqa_to_path(
330330
settings: &LinterSettings,
331331
) -> Result<usize> {
332332
// Parse once.
333-
let parsed = ruff_python_parser::parse_unchecked_source(source_kind.source_code(), source_type);
333+
// TODO(brent) resolve_target_version(path) here
334+
let parsed = parse_unchecked_source(source_kind, source_type, settings.target_version);
334335

335336
// Map row and column locations to byte slices (lazily).
336337
let locator = Locator::new(source_kind.source_code());
@@ -388,7 +389,8 @@ pub fn lint_only(
388389
source_type: PySourceType,
389390
source: ParseSource,
390391
) -> LinterResult {
391-
let parsed = source.into_parsed(source_kind, source_type);
392+
// TODO(brent) resolve_target_version(path) here
393+
let parsed = source.into_parsed(source_kind, source_type, settings.target_version);
392394

393395
// Map row and column locations to byte slices (lazily).
394396
let locator = Locator::new(source_kind.source_code());
@@ -496,8 +498,8 @@ pub fn lint_fix<'a>(
496498
// Continuously fix until the source code stabilizes.
497499
loop {
498500
// Parse once.
499-
let parsed =
500-
ruff_python_parser::parse_unchecked_source(transformed.source_code(), source_type);
501+
// TODO(brent) resolve_target_version(path) here
502+
let parsed = parse_unchecked_source(&transformed, source_type, settings.target_version);
501503

502504
// Map row and column locations to byte slices (lazily).
503505
let locator = Locator::new(transformed.source_code());
@@ -683,16 +685,33 @@ pub enum ParseSource {
683685
impl ParseSource {
684686
/// Consumes the [`ParseSource`] and returns the parsed [`Parsed`], parsing the source code if
685687
/// necessary.
686-
fn into_parsed(self, source_kind: &SourceKind, source_type: PySourceType) -> Parsed<ModModule> {
688+
fn into_parsed(
689+
self,
690+
source_kind: &SourceKind,
691+
source_type: PySourceType,
692+
target_version: PythonVersion,
693+
) -> Parsed<ModModule> {
687694
match self {
688-
ParseSource::None => {
689-
ruff_python_parser::parse_unchecked_source(source_kind.source_code(), source_type)
690-
}
695+
ParseSource::None => parse_unchecked_source(source_kind, source_type, target_version),
691696
ParseSource::Precomputed(parsed) => parsed,
692697
}
693698
}
694699
}
695700

701+
fn parse_unchecked_source(
702+
source_kind: &SourceKind,
703+
source_type: PySourceType,
704+
target_version: PythonVersion,
705+
) -> Parsed<ModModule> {
706+
let options = ParseOptions::from(source_type).with_target_version(target_version);
707+
// SAFETY: Safe because `PySourceType` always parses to a `ModModule`. See
708+
// `ruff_python_parser::parse_unchecked_source`. We use `parse_unchecked` (and thus
709+
// have to unwrap) in order to pass the `PythonVersion` via `ParseOptions`.
710+
ruff_python_parser::parse_unchecked(source_kind.source_code(), options)
711+
.try_into_module()
712+
.expect("PySourceType always parses into a module")
713+
}
714+
696715
#[cfg(test)]
697716
mod tests {
698717
use std::path::Path;

crates/ruff_linter/src/rules/pyflakes/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod tests {
1111

1212
use anyhow::Result;
1313
use regex::Regex;
14+
use ruff_python_parser::ParseOptions;
1415
use rustc_hash::FxHashMap;
1516
use test_case::test_case;
1617

@@ -744,8 +745,10 @@ mod tests {
744745
let source_type = PySourceType::default();
745746
let source_kind = SourceKind::Python(contents.to_string());
746747
let settings = LinterSettings::for_rules(Linter::Pyflakes.rules());
747-
let parsed =
748-
ruff_python_parser::parse_unchecked_source(source_kind.source_code(), source_type);
748+
let options = ParseOptions::from(source_type).with_target_version(settings.target_version);
749+
let parsed = ruff_python_parser::parse_unchecked(source_kind.source_code(), options)
750+
.try_into_module()
751+
.expect("PySourceType always parses into a module");
749752
let locator = Locator::new(&contents);
750753
let stylist = Stylist::from_tokens(parsed.tokens(), locator.contents());
751754
let indexer = Indexer::from_tokens(parsed.tokens(), locator.contents());

crates/ruff_linter/src/test.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use ruff_notebook::NotebookError;
1616
use ruff_python_ast::PySourceType;
1717
use ruff_python_codegen::Stylist;
1818
use ruff_python_index::Indexer;
19-
use ruff_python_parser::ParseError;
19+
use ruff_python_parser::{ParseError, ParseOptions};
2020
use ruff_python_trivia::textwrap::dedent;
2121
use ruff_source_file::SourceFileBuilder;
2222
use ruff_text_size::Ranged;
@@ -110,7 +110,10 @@ pub(crate) fn test_contents<'a>(
110110
settings: &LinterSettings,
111111
) -> (Vec<Message>, Cow<'a, SourceKind>) {
112112
let source_type = PySourceType::from(path);
113-
let parsed = ruff_python_parser::parse_unchecked_source(source_kind.source_code(), source_type);
113+
let options = ParseOptions::from(source_type).with_target_version(settings.target_version);
114+
let parsed = ruff_python_parser::parse_unchecked(source_kind.source_code(), options.clone())
115+
.try_into_module()
116+
.expect("PySourceType always parses into a module");
114117
let locator = Locator::new(source_kind.source_code());
115118
let stylist = Stylist::from_tokens(parsed.tokens(), locator.contents());
116119
let indexer = Indexer::from_tokens(parsed.tokens(), locator.contents());
@@ -174,7 +177,9 @@ pub(crate) fn test_contents<'a>(
174177
transformed = Cow::Owned(transformed.updated(fixed_contents, &source_map));
175178

176179
let parsed =
177-
ruff_python_parser::parse_unchecked_source(transformed.source_code(), source_type);
180+
ruff_python_parser::parse_unchecked(transformed.source_code(), options.clone())
181+
.try_into_module()
182+
.expect("PySourceType always parses into a module");
178183
let locator = Locator::new(transformed.source_code());
179184
let stylist = Stylist::from_tokens(parsed.tokens(), locator.contents());
180185
let indexer = Indexer::from_tokens(parsed.tokens(), locator.contents());

0 commit comments

Comments
 (0)