diff --git a/resources/test/fixtures/pylint/used_prior_global_declaration.py b/resources/test/fixtures/pylint/used_prior_global_declaration.py index 32085ebfbf..5ca672e1a1 100644 --- a/resources/test/fixtures/pylint/used_prior_global_declaration.py +++ b/resources/test/fixtures/pylint/used_prior_global_declaration.py @@ -109,6 +109,11 @@ def f(): del x +def f(): + print(f"{x=}") + global x + + ### # Non-errors. ### @@ -146,3 +151,8 @@ def f(): global x, y del x + + +def f(): + global x + print(f"{x=}") diff --git a/src/checkers/ast.rs b/src/checkers/ast.rs index 51d447b684..8de8a63103 100644 --- a/src/checkers/ast.rs +++ b/src/checkers/ast.rs @@ -156,19 +156,14 @@ impl<'a> Checker<'a> { } /// Add a `Check` to the `Checker`. - pub(crate) fn add_check(&mut self, check: Check) { + pub(crate) fn add_check(&mut self, mut check: Check) { // If we're in an f-string, override the location. RustPython doesn't produce // reliable locations for expressions within f-strings, so we use the // span of the f-string itself as a best-effort default. - let check = if let Some(range) = self.in_f_string { - Check { - location: range.location, - end_location: range.end_location, - ..check - } - } else { - check - }; + if let Some(range) = self.in_f_string { + check.location = range.location; + check.end_location = range.end_location; + } self.checks.push(check); } @@ -189,6 +184,13 @@ impl<'a> Checker<'a> { && self.settings.fixable.contains(code) } + /// Return the amended `Range` from a `Located`. + pub fn range_for(&self, located: &Located) -> Range { + // If we're in an f-string, override the location. + self.in_f_string + .unwrap_or_else(|| Range::from_located(located)) + } + /// Return `true` if the `Expr` is a reference to `typing.${target}`. pub fn match_typing_expr(&self, expr: &Expr, target: &str) -> bool { let call_path = dealias_call_path(collect_call_paths(expr), &self.import_aliases); diff --git a/src/pylint/plugins/used_prior_global_declaration.rs b/src/pylint/plugins/used_prior_global_declaration.rs index 37d1207c32..1e24a67298 100644 --- a/src/pylint/plugins/used_prior_global_declaration.rs +++ b/src/pylint/plugins/used_prior_global_declaration.rs @@ -13,7 +13,7 @@ pub fn used_prior_global_declaration(checker: &mut Checker, name: &str, expr: &E _ => return, }; if let Some(stmt) = globals.get(name) { - if expr.location < stmt.location { + if checker.range_for(expr).location < stmt.location { checker.add_check(Check::new( CheckKind::UsedPriorGlobalDeclaration(name.to_string(), stmt.location.row()), Range::from_located(expr), diff --git a/src/pylint/snapshots/ruff__pylint__tests__PLE0118_used_prior_global_declaration.py.snap b/src/pylint/snapshots/ruff__pylint__tests__PLE0118_used_prior_global_declaration.py.snap index 36fe1848ed..f564574943 100644 --- a/src/pylint/snapshots/ruff__pylint__tests__PLE0118_used_prior_global_declaration.py.snap +++ b/src/pylint/snapshots/ruff__pylint__tests__PLE0118_used_prior_global_declaration.py.snap @@ -134,4 +134,15 @@ expression: checks row: 105 column: 9 fix: ~ +- kind: + UsedPriorGlobalDeclaration: + - x + - 114 + location: + row: 113 + column: 10 + end_location: + row: 113 + column: 17 + fix: ~