Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F821 false positive for .pyi #3011

Closed
JonathanPlasse opened this issue Feb 18, 2023 · 14 comments · Fixed by #10779
Closed

F821 false positive for .pyi #3011

JonathanPlasse opened this issue Feb 18, 2023 · 14 comments · Fixed by #10779
Assignees
Labels
rule Implementing or modifying a lint rule

Comments

@JonathanPlasse
Copy link
Contributor

class Distribution(IMetadataProvider): ...
class IMetadataProvider: ...

ruff detects the F821 while flake8 with flake8-pyi does not (flake8-pyi must be installed otherwise it will also detect an error).

Link to the playground

@ngnpope
Copy link
Contributor

ngnpope commented Feb 18, 2023

Surely this is correct though? At the time of declaration of Distribution it is necessary for IMetadataProvider to have been already declared.

@JonathanPlasse
Copy link
Contributor Author

JonathanPlasse commented Feb 18, 2023

No, it is allowed in stub files, this is taken from typeshed. Stub files are only read by linters never executed.

@ngnpope
Copy link
Contributor

ngnpope commented Feb 18, 2023

Ok. Fair enough, I know declarations in stub files can be out of order. I guess I'm wondering why the declarations cannot just be reordered?

@JonathanPlasse
Copy link
Contributor Author

You are right even if it is allowed does not mean it should be done.
Should it be fixed?

@JonathanPlasse
Copy link
Contributor Author

I vote fixing it.

@charliermarsh
Copy link
Member

Can you look into how flake8-pyi suppresses these? What mechanism is it using? I'm surprised.

@charliermarsh charliermarsh added the question Asking for support or clarification label Feb 19, 2023
@JonathanPlasse
Copy link
Contributor Author

This is done here.
When you run flake8 with flake8-pyi installed with --verbose you can see this

flake8 stubs/setuptools/pkg_resources/__init__.pyi --verbose
flake8.checker            MainProcess     91 INFO     Making checkers
flake8.bugbear            MainProcess    107 INFO     Optional warning B950 not present in selected warnings: None. Not firing it at all.
flake8.pyi                MainProcess    119 INFO     Replacing FlakesChecker with PyiAwareFlakesChecker while checking 'stubs/setuptools/pkg_resources/__init__.pyi'
flake8.main.application   MainProcess    194 INFO     Finished running
flake8.main.application   MainProcess    194 INFO     Reporting errors
flake8.main.application   MainProcess    195 INFO     Found a total of 209 violations and reported 0

@charliermarsh
Copy link
Member

Woah that's wild!

@charliermarsh
Copy link
Member

Yeah, we should probably just change the behavior of ast.rs on pyi files to match whatever they do there then.

Avasam added a commit to Toufool/AutoSplit that referenced this issue Apr 21, 2023
https://beta.ruff.rs/docs/
https://github.com/charliermarsh/ruff

Massively simplify configurations and speedup linting thanks to Ruff. Adds more autofixes too.
Using `pathlib` instead of `os.path` is the modern way to go. However fixing this could introduce a bug if not careful. So I'm leaving it for later.

Existing related Ruff requests (nothing here is a blocker, just future improvements):
- astral-sh/ruff#1256
- astral-sh/ruff#3011
- astral-sh/ruff#3072
- astral-sh/ruff#3910
- astral-sh/ruff#2419
- astral-sh/ruff#3115
- astral-sh/ruff#1904
@charliermarsh charliermarsh added core Related to core functionality and removed question Asking for support or clarification labels May 8, 2023
Avasam added a commit to Toufool/AutoSplit that referenced this issue May 23, 2023
https://beta.ruff.rs/docs/
https://github.com/charliermarsh/ruff

Massively simplify configurations and speedup linting thanks to Ruff. Adds more autofixes too.
Using `pathlib` instead of `os.path` is the modern way to go. However fixing this could introduce a bug if not careful. So I'm leaving it for later.

Existing related Ruff requests (nothing here is a blocker, just future improvements):
- astral-sh/ruff#1256
- astral-sh/ruff#3011
- astral-sh/ruff#3072
- astral-sh/ruff#3910
- astral-sh/ruff#2419
- astral-sh/ruff#3115
- astral-sh/ruff#1904
Avasam added a commit to Toufool/AutoSplit that referenced this issue May 23, 2023
https://beta.ruff.rs/docs/
https://github.com/charliermarsh/ruff

Massively simplify configurations and speedup linting thanks to Ruff. Adds more autofixes too.
Using `pathlib` instead of `os.path` is the modern way to go. However fixing this could introduce a bug if not careful. So I'm leaving it for later.

Existing related Ruff requests (nothing here is a blocker, just future improvements):
- astral-sh/ruff#1256
- astral-sh/ruff#3011
- astral-sh/ruff#3072
- astral-sh/ruff#3910
- astral-sh/ruff#2419
- astral-sh/ruff#3115
- astral-sh/ruff#1904
@GabDug
Copy link

GabDug commented Sep 17, 2023

Hey!

Are there any plans for this issue, now that flake8-pyi has been fully integrated?

Thanks and have a great day!

@AlexWaygood
Copy link
Member

AlexWaygood commented Mar 12, 2024

In #10341, I fixed the following F821 false positive on .pyi files:

x: int
y = x  # F821 previously incorrectly emitted here in a `.pyi` file

But Ruff still emits an error on the original snippet in this issue if it's linting a .pyi file:

class Distribution(IMetadataProvider): ...  # F821 still emitted here currently due to the forward reference
class IMetadataProvider: ...

However, with the latest version of flake8-monkeypatched-by-flake8-pyi, flake8 also emits an F821 error on that snippet. This is due to changes we made in flake8-pyi in PyCQA/flake8-pyi#364. The motivation for the flake8-pyi changes were:

  • We wanted to reduce the amount of monkeypatching we were doing to a core minimum.
  • We concluded that, although this kind of forward reference is legal in a stub file, it is never necessary when it comes to base classes (and other similar situations), and should probably be considered bad style -- so forbidding it was probably a good thing anyway.

I'm not sure that ruff should necessarily make the same decisions that flake8-pyi made, however:

  • We don't have the same concerns about keeping monkeypatching to a minimum, since we're not doing any monkeypatching at all
  • F821 is a rule that's concerned with correctness, and a forward reference like this isn't a correctness issue in a stub -- unlike in a .py file, it's perfectly legal; it's just bad style. So maybe we should avoid emitting F821 here, and emit a diagnostic with a different error code instead, to make it clear that we're banning it out of stylistic concerns rather than correctness concerns?

Curious for @charliermarsh's opinion here!

@charliermarsh
Copy link
Member

Thanks for the clear write-up. I think my preference would be...

  1. Not emitting anything.
  2. Emitting a new, dedicated rule.
  3. Emitting F821 (which feels incorrect, as you point out above).

@AlexWaygood
Copy link
Member

I'd definitely prefer it if we emitted something on these constructs in a stub file -- type checkers don't flag them (since they're legal in .pyi files), and it's honestly pretty confusing if you come across a class in a stub file that inherits from a class that hasn't been defined yet 😄

So that implies (2). I'll start off by making a PR that stops ruff from emitting F821 on this kind of construct, and then look at implementing a new rule for this.

Should the new rule go in the RUF ruleset?

@charliermarsh
Copy link
Member

Sounds good. Yeah, unless we want to add it to PYI and coordinate with flake8-pyi to reserve that code.

@dhruvmanila dhruvmanila added rule Implementing or modifying a lint rule and removed core Related to core functionality labels Mar 13, 2024
AlexWaygood added a commit that referenced this issue Apr 7, 2024
…F821`) (#10779)

## Summary

Fixes #3011.

Type checkers currently allow forward references in all contexts in stub
files, and stubs frequently make use of this capability (although it
doesn't actually seem to be specc'd anywhere --neither in PEP 484, nor
https://typing.readthedocs.io/en/latest/source/stubs.html#id6, nor the
CPython typing docs). Implementing it so that Ruff allows forward
references in _all contexts_ in stub files seems non-trivial, however
(or at least, I couldn't figure out how to do it easily), so this PR
does not do that. Perhaps it _should_; if we think this apporach isn't
principled enough, I'm happy to close it and postpone changing anything
here.

However, this does reduce the number of F821 errors Ruff emits on
typeshed down from 76 to 2, which would mean that we could enable the
rule at typeshed. The remaining 2 F821 errors can be trivially fixed at
typeshed by moving definitions around; forward references in class bases
were really the only remaining places where there was a real _use case_
for forward references in stub files that Ruff wasn't yet allowing.

## Test plan

`cargo test`. I also ran this PR branch on typeshed to check to see if
there were any new false positives caused by the changes here; there
were none.
Glyphack pushed a commit to Glyphack/ruff that referenced this issue Apr 12, 2024
…F821`) (astral-sh#10779)

## Summary

Fixes astral-sh#3011.

Type checkers currently allow forward references in all contexts in stub
files, and stubs frequently make use of this capability (although it
doesn't actually seem to be specc'd anywhere --neither in PEP 484, nor
https://typing.readthedocs.io/en/latest/source/stubs.html#id6, nor the
CPython typing docs). Implementing it so that Ruff allows forward
references in _all contexts_ in stub files seems non-trivial, however
(or at least, I couldn't figure out how to do it easily), so this PR
does not do that. Perhaps it _should_; if we think this apporach isn't
principled enough, I'm happy to close it and postpone changing anything
here.

However, this does reduce the number of F821 errors Ruff emits on
typeshed down from 76 to 2, which would mean that we could enable the
rule at typeshed. The remaining 2 F821 errors can be trivially fixed at
typeshed by moving definitions around; forward references in class bases
were really the only remaining places where there was a real _use case_
for forward references in stub files that Ruff wasn't yet allowing.

## Test plan

`cargo test`. I also ran this PR branch on typeshed to check to see if
there were any new false positives caused by the changes here; there
were none.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rule Implementing or modifying a lint rule
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants