@@ -10,10 +10,10 @@ use rustc_hash::FxHashMap;
1010
1111use ruff_diagnostics:: Diagnostic ;
1212use ruff_notebook:: Notebook ;
13- use ruff_python_ast:: { ModModule , PySourceType } ;
13+ use ruff_python_ast:: { ModModule , PySourceType , PythonVersion } ;
1414use ruff_python_codegen:: Stylist ;
1515use ruff_python_index:: Indexer ;
16- use ruff_python_parser:: { ParseError , Parsed , SyntaxError } ;
16+ use ruff_python_parser:: { ParseError , ParseOptions , Parsed , SyntaxError } ;
1717use ruff_source_file:: SourceFileBuilder ;
1818use 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 {
683685impl 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) ]
697716mod tests {
698717 use std:: path:: Path ;
0 commit comments