[refurb] Do not add abc.ABC if already present (FURB180)#22234
[refurb] Do not add abc.ABC if already present (FURB180)#22234ntBre merged 12 commits intoastral-sh:mainfrom
refurb] Do not add abc.ABC if already present (FURB180)#22234Conversation
Summary According to the FURB180 rule, abc.ABC should be used instead of metaclass=abc.ABCMeta. This issue can be fixed automatically, but if the class being checked already contains abc.ABC, it would be added a second time.
ntBre
left a comment
There was a problem hiding this comment.
Thanks! This looks good to me overall, I just had a couple of small suggestions. We should also add your manual tests from the PR summary as regression tests. At the bottom of this file would be a good place for them:
refurb] Do not add abc.ABC if already present (FURB180)
|
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| PYI034 | 10 | 0 | 10 | 0 | 0 |
| UP045 | 10 | 0 | 0 | 10 | 0 |
| PIE794 | 2 | 0 | 2 | 0 | 0 |
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+0 -12 violations, +10 -0 fixes in 5 projects; 50 projects unchanged)
apache/superset (+0 -1 violations, +10 -0 fixes)
ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL
- superset/charts/client_processing.py:285:17: UP045 Use `X | None` for type annotations + superset/charts/client_processing.py:285:17: UP045 [*] Use `X | None` for type annotations - superset/db_engine_specs/snowflake.py:348:26: UP045 Use `X | None` for type annotations + superset/db_engine_specs/snowflake.py:348:26: UP045 [*] Use `X | None` for type annotations - superset/db_engine_specs/snowflake.py:370:26: UP045 Use `X | None` for type annotations + superset/db_engine_specs/snowflake.py:370:26: UP045 [*] Use `X | None` for type annotations - superset/mcp_service/utils/retry_utils.py:229:9: PYI034 `__enter__` methods in classes like `RetryableOperation` usually return `self` at runtime - superset/models/helpers.py:2634:17: UP045 Use `X | None` for type annotations + superset/models/helpers.py:2634:17: UP045 [*] Use `X | None` for type annotations - superset/models/helpers.py:897:29: UP045 Use `X | None` for type annotations + superset/models/helpers.py:897:29: UP045 [*] Use `X | None` for type annotations
freedomofpress/securedrop (+0 -1 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --no-fix --output-format concise --preview
- devops/scripts/verify-mo.py:54:9: PYI034 `__enter__` methods in classes like `CatalogVerifier` usually return `self` at runtime
reflex-dev/reflex (+0 -2 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --no-fix --output-format concise --preview
- reflex/components/recharts/cartesian.py:245:5: PIE794 Class field `fill` is defined multiple times - reflex/components/recharts/cartesian.py:248:5: PIE794 Class field `stroke` is defined multiple times
rotki/rotki (+0 -7 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --no-fix --output-format concise --preview
- rotkehlchen/assets/resolver.py:38:9: PYI034 `__new__` methods in classes like `AssetResolver` usually return `self` at runtime - rotkehlchen/db/drivers/gevent.py:72:9: PYI034 `__enter__` methods in classes like `DBCursor` usually return `self` at runtime - rotkehlchen/db/settings.py:512:9: PYI034 `__new__` methods in classes like `CachedSettings` usually return `self` at runtime - rotkehlchen/globaldb/handler.py:118:9: PYI034 `__new__` methods in classes like `GlobalDBHandler` usually return `self` at runtime - rotkehlchen/history/price.py:82:9: PYI034 `__new__` methods in classes like `PriceHistorian` usually return `self` at runtime - rotkehlchen/inquirer.py:355:9: PYI034 `__new__` methods in classes like `Inquirer` usually return `self` at runtime - rotkehlchen/utils/hexbytes.py:46:9: PYI034 `__new__` methods in classes like `HexBytes` usually return `self` at runtime
scikit-build/scikit-build-core (+0 -1 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --no-fix --output-format concise --preview
- src/scikit_build_core/settings/skbuild_model.py:50:9: PYI034 `__new__` methods in classes like `CMakeSettingsDefine` usually return `self` at runtime
Changes by rule (3 rules affected)
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| PYI034 | 10 | 0 | 10 | 0 | 0 |
| UP045 | 10 | 0 | 0 | 10 | 0 |
| PIE794 | 2 | 0 | 2 | 0 | 0 |
- use of `analyze::class::any_qualified_base_class`, - use of a stack slice instead of a heap-allocated `Vec`, - `range_deletion` instead of `deletion`, - the appropriate `py.snap` file was updated.
|
According to @"... add your manual tests from the PR summary as regression tests." - I added the following changes to from abc import abstractmethod, ABCMeta, ABC
from abc import ABC as ABCAlternativeName
...
class A7(ABC):
@abstractmethod
def foo(self): pass
class A8(ABCAlternativeName):
@abstractmethod
def foo(self): pass
...I hope this is what was expected. |
|
Thank you! That was close to what I had in mind, but I think your tests in the summary were a bit more helpful than the ones added to FURB180.py. I just pushed two commits updating the tests. A couple of things I tried to fix:
After making these changes, it showed that there's an issue with the fix: - class A11(MyMetaClass, metaclass=ABCMeta): # FURB180
+ class A11(MyMetaClass, ): # FURB180We're leaving a trailing comma after removing the metaclass argument. I think we might want to try the |
|
According to: "We're leaving a trailing comma after removing the metaclass argument". |
Fixed the issue above here: 740da9e Example. Before fix:import abc
from abc import abstractmethod, ABCMeta, ABC
from abc import ABC as ABCAnotherName
class ParentClass:
...
class Foo(metaclass=ABCMeta):
...
class Foo2(abc.ABC, ParentClass, metaclass=ABCMeta):
...
class Foo3(ParentClass, ABC, metaclass=ABCMeta):
...
class Foo4(ABCAnotherName, metaclass=ABCMeta):
...After fix:import abc
from abc import abstractmethod, ABCMeta, ABC
from abc import ABC as ABCAnotherName
class ParentClass:
...
class Foo(ABCAnotherName):
...
class Foo2(abc.ABC, ParentClass):
...
class Foo3(ParentClass, ABC):
...
class Foo4(ABCAnotherName):
... |
|
And since there are several commits here, do I need to squash them? |
|
Hello, @ntBre . Just a friendly reminder and request to take a look at this if possible. |
|
Thank you! I was on PTO last week, but I'm back now :) I'll take a look soon.
Don't worry about squashing, we'll squash-merge at the end, so it's easier to keep all the commits for review in the meantime. |
ntBre
left a comment
There was a problem hiding this comment.
Thank you! This looks great, I just had a couple of minor suggestions. I also noticed a potential issue with the fix safety, but I can turn that into a separate issue if you'd rather not update it here.
Better comment. Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
|
@ntBre , sorry for delay with the answer. Could you please clarify what docs you meant here?
|
ntBre
left a comment
There was a problem hiding this comment.
Thank you! I had one suggestion about narrowing the comment range check and a test for that. Then we just need to update the ## Fix safety section of the rule docs.
Yep, updated the doc too: 0292c87 |
* main: (62 commits) [`refurb`] Do not add `abc.ABC` if already present (`FURB180`) (#22234) [ty] Add a new `assert-type-unspellable-subtype` diagnostic (#22815) [ty] Avoid duplicate syntax errors for `await` outside functions (#22826) [ty] Fix unary operator false-positive for constrained TypeVars (#22783) [ty] Fix binary operator false-positive for constrained TypeVars (#22782) [ty] Fix false-positive `unsupported-operator` for "symmetric" TypeVars (#22756) [`pydocstyle`] Clarify which quote styles are allowed (`D300`) (#22825) [ty] Use distributed versions of AND and OR on constraint sets (#22614) [ty] Add support for dict literals and dict() calls as default values for parameters with TypedDict types (#22161) Document `-` stdin convention in CLI help text (#22817) [ty] Make `infer_subscript_expression_types` a method on `Type` (#22731) [ty] Simplify `OverloadLiteral::spans` and `OverloadLiteral::parameter_span` (#22823) [ty] Require both `*args` and `**kwargs` when calling a `ParamSpec` callable (#22820) [ty] Handle tagged errors in conformance (#22746) Add `--color` cli option to force colored output (#22806) Identify notebooks by LSP didOpen instead of `.ipynb` file extension (#22810) [ty] Fix docstring rendering for literal blocks after doctests (#22676) [ty] Update salsa to fix out-of-order query validation (#22498) [ty] Inline cycle initial and recovery functions (#22814) [ty] Pass the generic context through the decorator (#22544) ...
Summary
According to the
FURB180rule,abc.ABCshould be used instead ofmetaclass=abc.ABCMeta. This issue can be fixed automatically, but if the class being checked already containsabc.ABC, it would be added a second time.Fixes: #17162
Test Plan
I ran
cargo test refurb.For checking the "fix" I used this python file:
Python file (input)
The output after applying the fix is so:
Python file (output)
Note: Trailing commas may remain after the automatic fix. It is unclear whether this is an issue.