-
-
Notifications
You must be signed in to change notification settings - Fork 717
Simplify ruff configuration #41259
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
base: develop
Are you sure you want to change the base?
Simplify ruff configuration #41259
Changes from all commits
a99f822
feea4ab
8025e2e
2f00d98
e44886c
5e4de08
572ebf9
0024305
2202a87
92cf8f1
a8e04e8
9b2924c
2519d31
3b467a7
a58fcf9
9858891
e1f8a9b
fe61df1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Configuration for GitHub Action running ruff | ||
| extend = "../../pyproject.toml" # Start with the project configuration | ||
|
|
||
| [lint] | ||
| # Remove rules that we do not yet follow across the whole codebase. | ||
| # Roughly sorted by how easy these should be to fix. | ||
| extend-ignore = [ | ||
| "E742", # 2 failures | ||
| "PLW3301", # 3 failures, should be easy to autofix | ||
| "PLW1510", # 18 failures, should be easy to autofix | ||
| "PLC3002", # 3 failures | ||
| "PLE0302", # 3 failures | ||
| "E721", # 5 failures | ||
| "PLR0124", # 7 failures | ||
| "PLW1508", # 8 failures | ||
| "PLR0402", # 90 failures, should be easy to autofix | ||
| "PLR5501", # 375 failures, should be easy to autofix | ||
| "PLC0206", # 39 | ||
| "PLW0602", # 43 failures | ||
| "PLR1704", # 56 failures | ||
| "PLW0642", # 61 failures | ||
| "F841", # 61 failures | ||
| "PLW0603", # 94 failures | ||
| "F403", # 142 failures | ||
| "F405", # 163 failures | ||
| "E731", # 370 failures | ||
| "PLW0211", # 495 failures | ||
| "PLW2901", # 474 failures | ||
| "F821", # 2271 failures | ||
| "E231", # 49042 failures, could be autofixed but would change too many files for one PR | ||
| "E226", # 29323 failures, could be autofixed but would change too many files for one PR | ||
| "F401", # 583 failures | ||
| "I001", # 2888 failures | ||
|
|
||
| # The remaining failing rules were in ruff preview mode only when added to this file. | ||
| "PLW3201", | ||
| "PLR6301", | ||
| "E241", | ||
| "E203", | ||
| "E265", | ||
| "E201", | ||
| "E261", | ||
| "PLR6104", | ||
| "E202", | ||
| "PLR6201", | ||
| "E266", | ||
| "PLR1702", | ||
| "E262", | ||
| "PLW1514", | ||
| "PLC1901", | ||
| "PLC2801", | ||
| "E116", | ||
| "E114", | ||
| "PLC2701", | ||
| "E251", | ||
| "PLW0108", | ||
| "E302", | ||
| "PLE4703", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -235,24 +235,54 @@ test = ["coverage", "pytest", "pytest-xdist"] | |
| # Python 3.12 is the minimum supported version | ||
| target-version = "py312" | ||
|
|
||
| # This directory is full of old autogenerated files. | ||
| # Linting it would just get in the way of adding stricter linter rules | ||
| # to our actual code | ||
| exclude = ["src/doc/"] | ||
| exclude = [ | ||
| # This directory is full of old autogenerated files. | ||
| # Linting it would just get in the way of adding stricter linter rules | ||
| # to our actual code. | ||
| "src/doc/", | ||
| # This directory handles the build process, | ||
| # and some parts allow Python versions as old as 2.6, so we don't both linting. | ||
| "build/", | ||
| ] | ||
|
|
||
| [tool.ruff.lint] | ||
|
|
||
| # Rules that we deliberately do not attempt to follow, either because we | ||
| # disagree with them or because following them is not currently practical. | ||
| ignore = [ | ||
| "E501", # Line too long - hard to avoid in doctests, and better handled by black. | ||
|
|
||
| # Variable/function names I, O, l - common in math, and not an issue for most monospace fonts | ||
| "E741", | ||
| "E743", | ||
|
|
||
| "PLC2401", # Non-ASCII variables - we deliberately use Greek letters (albeit sparingly) | ||
|
|
||
| # The following rules are good in spirit but require some common sense, better enforced through code review. | ||
| "PLR09", # Rules about code complexity - better enforced through code review process. | ||
| "PLR1714", # Repeated equality comparison - too picky when only doing a couple comparisons. | ||
| "PLR2004", # Comparison to magic values - better enforced through code review process. | ||
| "PLW1641", # __eq__ without __hash__ - implementations of equivalence classes may have a well-defined notion of equality without a well-defined canonical representation that can be used to compute a hash | ||
|
|
||
| # Imports at top-level of file - we can't follow this because we intentionally defer imports for various reasons. | ||
| # maybe once we can use PEP 810 this can be fixed. | ||
| "PLC0415", | ||
|
|
||
| # Module level import not at top of file. | ||
| # ruff is not aware of our lazy_imports, we may be able to remove this ignore after adopting PEP 810 | ||
| "E402", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't quite understand the (We might want to defer this rule until there is a decision on how
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sure, but I don't think it's worth the amount of effort to do that reformatting and then do it again if we decide to replace our custom lazy import system with the PEP 810 one. |
||
| ] | ||
|
|
||
| select = [ | ||
| "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e | ||
| "F", # pyflakes - https://docs.astral.sh/ruff/rules/#pyflakes-f | ||
| # A starting point for our ruff rules, we may want to ignore some of these later on. | ||
| "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i | ||
| "PL", # pylint - https://docs.astral.sh/ruff/rules/#pylint-pl | ||
|
|
||
| # ruff-specific rules -- https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf | ||
| "RUF013", | ||
| "RUF036", | ||
|
|
||
| "TC", # flake8-type-checking - https://docs.astral.sh/ruff/rules/#flake8-type-checking-tc | ||
|
|
||
| # pyupgrade -- https://docs.astral.sh/ruff/rules/#pyupgrade-up | ||
| "UP004", | ||
| "UP006", | ||
|
|
@@ -262,6 +292,119 @@ select = [ | |
| "UP022", | ||
| "UP034", | ||
| "UP035", | ||
|
|
||
| "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#pycodestyle-e-w | ||
|
|
||
| # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that we use a fixed version of ruff in CI, so I would say the danger of random failures due to rules in preview is relatively low.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a different version
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, I forgot about the possible version mismatch when running it locally. Then listing the rules like you did is indeed a good idea! |
||
| # Ideally we would enable (almost) all of the E rules, but too | ||
| # many of these rules are in preview to trust that something won't change | ||
| # in ruff itself and cause us headaches. | ||
| "E101", | ||
| "E401", | ||
| "E701", | ||
| "E702", | ||
| "E703", | ||
| "E711", | ||
| "E712", | ||
| "E713", | ||
| "E714", | ||
| "E721", | ||
| "E722", | ||
| "E731", | ||
| "E742", | ||
| "E902", | ||
|
|
||
| # pylint - https://docs.astral.sh/ruff/rules/#pylint-pl | ||
| # Like with the E rules, this isn't stable enough yet to enable all of PL | ||
|
|
||
| # pylint convention - https://docs.astral.sh/ruff/rules/#convention-plc | ||
| "PLC0105", | ||
| "PLC0131", | ||
| "PLC0132", | ||
| "PLC0205", | ||
| "PLC0206", | ||
| "PLC0208", | ||
| "PLC0414", | ||
| "PLC1802", | ||
| "PLC2403", | ||
| "PLC3002", | ||
|
|
||
| # pylint errors - https://docs.astral.sh/ruff/rules/#error-ple | ||
| "PLE0100", | ||
| "PLE0101", | ||
| "PLE0115", | ||
| "PLE0116", | ||
| "PLE0117", | ||
| "PLE0118", | ||
| "PLE0237", | ||
| "PLE0241", | ||
| "PLE0302", | ||
| "PLE0303", | ||
| "PLE0305", | ||
| "PLE0307", | ||
| "PLE0308", | ||
| "PLE0309", | ||
| "PLE0604", | ||
| "PLE0605", | ||
| "PLE0643", | ||
| "PLE0704", | ||
| "PLE1132", | ||
| "PLE1142", | ||
| "PLE1205", | ||
| "PLE1206", | ||
| "PLE1300", | ||
| "PLE1307", | ||
| "PLE1310", | ||
| "PLE1507", | ||
| "PLE1519", | ||
| "PLE1520", | ||
| "PLE1700", | ||
| "PLE2502", | ||
| "PLE2510", | ||
| "PLE2512", | ||
| "PLE2513", | ||
| "PLE2514", | ||
| "PLE2515", | ||
|
|
||
| # pylint refactor - https://docs.astral.sh/ruff/rules/#refactor-plr | ||
| "PLR0124", | ||
| "PLR0133", | ||
| "PLR0206", | ||
| "PLR0402", | ||
| "PLR1704", | ||
| "PLR1711", | ||
| "PLR1716", | ||
| "PLR1722", | ||
| "PLR1730", | ||
| "PLR1733", | ||
| "PLR1736", | ||
| "PLR2044", | ||
| "PLR5501", | ||
|
|
||
| # pyling warning - https://docs.astral.sh/ruff/rules/#warning-plw | ||
| "PLW0120", | ||
| "PLW0127", | ||
| "PLW0128", | ||
| "PLW0129", | ||
| "PLW0131", | ||
| "PLW0133", | ||
| "PLW0177", | ||
| "PLW0211", | ||
| "PLW0245", | ||
| "PLW0406", | ||
| "PLW0602", | ||
| "PLW0603", | ||
| "PLW0604", | ||
| "PLW0642", | ||
| "PLW0711", | ||
| "PLW1501", | ||
| "PLW1507", | ||
| "PLW1508", | ||
| "PLW1509", | ||
| "PLW1510", | ||
| "PLW2101", | ||
| "PLW2901", | ||
| "PLW3301", | ||
| ] | ||
|
|
||
| [tool.ruff.lint.per-file-ignores] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are actually quite a few imports in methods that could be moved to the top level without a problem. You want method-level imports only in one instance, namely to break circular imports, right? In that case it would be very helpful if the important is annotated to ease migrating to the new lazy imports (which doesn't help with circular imports) and so it's good if they have a comment like
# noqa: PLC0415 - breaks circular import x > y > zThen during the migration to the built-in lazy imports, you know you don't need to touch those imports.
If it's just a heavy import that is rarely used in the module, it's okay to convert it to a
lazy_import(and then later to the built-in lazy import).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lazy imports can help with circular imports depending on the situation. Sometimes a lazy import can fix a circular import, sometimes it can't.
As for what to do until we can use built-in lazy imports, there are so many linter failures related to imports that I think trying to address is futile unless we can reliably do it automatically, I don't think we can until built-in lazy imports are available.
Yeah but I don't think it's worth the trouble of fixing thousands of lines for this, just to do it again once built-in lazy imports are available.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For context:
PLC0415currently has 10606 failures and has no autofix option available.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of weeks ago, I looked into how the migration to
lazy importwill most likely look like for us (and asked some clarifying questions to the PEP authors). Python will provide some way to call the underlying logic of the lazy import mechanism (similar to the dynamicimportmethod). We can use this in ourlazy_importmethod using something likeThen, once we have 3.15 as the minimal Python version (which will be in 4 to 5 years), we can replace
lazy_import(...)bylazy import ...globally.So it's a pretty long time frame until we can really profit from the new lazy imports syntax.
As for the local imports, the overall migration to lazy imports would look like:
lazy_importlazy_import>lazy importLocal imports that cannot be migrated to lazy imports, would need to be annotated in either case.
As for the reason why I like to keep
PCL0415activated is that IDEs highlight the import as a linter warning. So if you touch the surrounding code, you get a natural push to move the local import to a global (lazy) import. Then you usually run the doctests anyway, and will see if the import can be global or it really needs to be local (to break a circular import). I like to keep that nudge, as we would like to remove all possible local imports in the long term anyway.