Skip to content

[refurb] Mark FURB180 fix unsafe when class has bases #18149

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

Merged
merged 6 commits into from
Jun 3, 2025

Conversation

robsdedude
Copy link
Contributor

Summary

Mark FURB180's fix as unsafe if the class already has base classes. This is because the base classes might validate the other base classes (like typing.Protocol does) or otherwise alter runtime behavior if more base classes are added.

Test Plan

The existing snapshot test covers this case already.

References

Partially addresses #13307 (left out way to permit certain exceptions)

@MichaReiser
Copy link
Member

@ntBre could you take a look at this PR when you're back?

@ntBre ntBre added bug Something isn't working fixes Related to suggested fixes for violations labels May 29, 2025
Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this makes sense to me! I just had one stylistic suggestion.

@@ -69,6 +74,7 @@ pub(crate) fn metaclass_abcmeta(checker: &Checker, class_def: &StmtClassDef) {
return;
}

let has_bases = !class_def.bases().is_empty();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think we could use something like this here:

Suggested change
let has_bases = !class_def.bases().is_empty();
let applicability = if class_def.bases().is_empty() { Applicability::Safe } else { Applicability::Unsafe };

And then instead of the make_fix method, we can just use Fix::applicable_edits where we previously used Fix::safe_edits. You could then move your comments from make_fix here too, or possibly delete them too since I think you covered it nicely in the Fix safety section.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much. Nit happily applied.

Copy link
Contributor

github-actions bot commented May 29, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+0 -0 violations, +0 -24 fixes in 4 projects; 51 projects unchanged)

apache/airflow (+0 -0 violations, +0 -6 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL

+ airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py:78:49: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- airflow-core/src/airflow/api_fastapi/auth/managers/base_auth_manager.py:78:49: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ providers/standard/src/airflow/providers/standard/operators/python.py:376:53: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- providers/standard/src/airflow/providers/standard/operators/python.py:376:53: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ task-sdk/src/airflow/sdk/definitions/_internal/node.py:67:32: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- task-sdk/src/airflow/sdk/definitions/_internal/node.py:67:32: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class

apache/superset (+0 -0 violations, +0 -2 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL

+ superset/db_engine_specs/presto.py:159:44: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- superset/db_engine_specs/presto.py:159:44: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class

bokeh/bokeh (+0 -0 violations, +0 -2 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL

+ src/bokeh/colors/color.py:54:27: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- src/bokeh/colors/color.py:54:27: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class

astropy/astropy (+0 -0 violations, +0 -14 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview

+ astropy/cosmology/_src/tests/test_core.py:111:5: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- astropy/cosmology/_src/tests/test_core.py:111:5: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ astropy/utils/shapes.py:167:46: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- astropy/utils/shapes.py:167:46: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ astropy/visualization/wcsaxes/frame.py:157:30: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- astropy/visualization/wcsaxes/frame.py:157:30: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ astropy/visualization/wcsaxes/transforms.py:149:45: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- astropy/visualization/wcsaxes/transforms.py:149:45: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ astropy/visualization/wcsaxes/transforms.py:180:45: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- astropy/visualization/wcsaxes/transforms.py:180:45: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ astropy/visualization/wcsaxes/transforms.py:31:34: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- astropy/visualization/wcsaxes/transforms.py:31:34: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class
+ astropy/wcs/wcsapi/wrappers/base.py:6:39: FURB180 Use of `metaclass=abc.ABCMeta` to define abstract base class
- astropy/wcs/wcsapi/wrappers/base.py:6:39: FURB180 [*] Use of `metaclass=abc.ABCMeta` to define abstract base class

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
FURB180 24 0 0 0 24

@ntBre ntBre added the preview Related to preview mode features label May 29, 2025
@ntBre ntBre changed the title Mark FURB180 fix unsafe when class has bases [refurb] Mark FURB180 fix unsafe when class has bases Jun 3, 2025
@ntBre ntBre enabled auto-merge (squash) June 3, 2025 00:39
@ntBre ntBre disabled auto-merge June 3, 2025 00:41
@ntBre ntBre enabled auto-merge (squash) June 3, 2025 00:44
@ntBre ntBre merged commit 14c42a8 into astral-sh:main Jun 3, 2025
33 checks passed
dcreager added a commit that referenced this pull request Jun 3, 2025
…aration

* origin/main:
  [ty] Infer `list[T]` when unpacking non-tuple type (#18438)
  [ty] Meta-type of type variables should be type[..] (#18439)
  [`pyupgrade`] Make fix unsafe if it deletes comments (`UP050`) (#18390)
  [`pyupgrade`] Make fix unsafe if it deletes comments (`UP004`) (#18393)
  [ty] Support using legacy typing aliases for generic classes in type annotations (#18404)
  Use ty's completions in playground (#18425)
  Update editor setup docs about Neovim and Vim (#18324)
  Update NPM Development dependencies (#18423)
  Infer `list[T]` for starred target in unpacking (#18401)
  [`refurb`] Mark `FURB180` fix unsafe when class has bases (#18149)
  [`fastapi`] Avoid false positive for class dependencies (`FAST003`) (#18271)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixes Related to suggested fixes for violations preview Related to preview mode features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants