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

Refactor method classification logic: __new__ methods are now classified as staticmethod #13305

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

cake-monotone
Copy link
Contributor

Summary

__new__ methods are technically static methods, with cls as their first argument. However, Ruff currently classifies them as classmethod, which causes two issues:

  • It conveys incorrect information, leading to confusion. For example, in cases like ARG003, __new__ is explicitly treated as a classmethod.
  • Future rules that should apply to staticmethod may not be applied correctly due to this misclassification.

Based on #13154, I have excluded the first argument cls of __new__ from ARG004. (not concluded, it can be change)

Closes #13154

Copy link
Contributor

github-actions bot commented Sep 10, 2024

ruff-ecosystem results

Linter (stable)

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

latchbio/latch (+2 -2 violations, +0 -0 fixes)

- src/latch_cli/centromere/utils.py:67:34: ARG003 Unused class method argument: `args`
+ src/latch_cli/centromere/utils.py:67:34: ARG004 Unused static method argument: `args`
- src/latch_cli/centromere/utils.py:67:42: ARG003 Unused class method argument: `kwargs`
+ src/latch_cli/centromere/utils.py:67:42: ARG004 Unused static method argument: `kwargs`

pandas-dev/pandas (+0 -0 violations, +0 -0 fixes)


Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
ARG004 2 2 0 0 0
ARG003 2 0 2 0 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+15 -15 violations, +0 -0 fixes in 2 projects; 53 projects unchanged)

latchbio/latch (+2 -2 violations, +0 -0 fixes)

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

- src/latch_cli/centromere/utils.py:67:34: ARG003 Unused class method argument: `args`
+ src/latch_cli/centromere/utils.py:67:34: ARG004 Unused static method argument: `args`
- src/latch_cli/centromere/utils.py:67:42: ARG003 Unused class method argument: `kwargs`
+ src/latch_cli/centromere/utils.py:67:42: ARG004 Unused static method argument: `kwargs`

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

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

- astropy/constants/codata2010.py:19:9: PLR0917 Too many positional arguments (7/5)
+ astropy/constants/codata2010.py:19:9: PLR0917 Too many positional arguments (8/5)
- astropy/constants/constant.py:124:9: PLR0917 Too many positional arguments (7/5)
+ astropy/constants/constant.py:124:9: PLR0917 Too many positional arguments (8/5)
- astropy/coordinates/distances.py:104:9: PLR0917 Too many positional arguments (12/5)
+ astropy/coordinates/distances.py:104:9: PLR0917 Too many positional arguments (13/5)
- astropy/coordinates/spectral_coordinate.py:184:9: PLR0917 Too many positional arguments (6/5)
+ astropy/coordinates/spectral_coordinate.py:184:9: PLR0917 Too many positional arguments (7/5)
- astropy/io/fits/hdu/groups.py:96:9: PLR0917 Too many positional arguments (8/5)
+ astropy/io/fits/hdu/groups.py:96:9: PLR0917 Too many positional arguments (9/5)
- astropy/table/column.py:1235:9: PLR0917 Too many positional arguments (11/5)
+ astropy/table/column.py:1235:9: PLR0917 Too many positional arguments (12/5)
- astropy/table/column.py:1592:9: PLR0917 Too many positional arguments (13/5)
+ astropy/table/column.py:1592:9: PLR0917 Too many positional arguments (14/5)
- astropy/table/column.py:508:9: PLR0917 Too many positional arguments (11/5)
+ astropy/table/column.py:508:9: PLR0917 Too many positional arguments (12/5)
+ astropy/time/core.py:1929:9: PLR0917 Too many positional arguments (10/5)
- astropy/time/core.py:1929:9: PLR0917 Too many positional arguments (9/5)
+ astropy/time/core.py:2896:9: PLR0917 Too many positional arguments (10/5)
- astropy/time/core.py:2896:9: PLR0917 Too many positional arguments (9/5)
- astropy/time/formats.py:1024:9: PLR0917 Too many positional arguments (7/5)
+ astropy/time/formats.py:1024:9: PLR0917 Too many positional arguments (8/5)
- astropy/units/function/core.py:569:9: PLR0917 Too many positional arguments (7/5)
+ astropy/units/function/core.py:569:9: PLR0917 Too many positional arguments (8/5)
- astropy/units/quantity.py:418:9: PLR0917 Too many positional arguments (7/5)
+ astropy/units/quantity.py:418:9: PLR0917 Too many positional arguments (8/5)

Changes by rule (3 rules affected)

code total + violation - violation + fix - fix
PLR0917 26 13 13 0 0
ARG004 2 2 0 0 0
ARG003 2 0 2 0 0

@cake-monotone
Copy link
Contributor Author

I'm sure there are other breaking changes besides the ruff-ecosystem results
I'll try to summarize them.

@AlexWaygood AlexWaygood self-assigned this Sep 10, 2024
@cake-monotone
Copy link
Contributor Author

Affected Rules

  • ARG003: unused-class-method-argument
  • ARG004: unused-static-method-argument
  • PLW0642: self-or-cls-assignment
  • PLW0211: bad-staticmethod-argument
  • N804: invalid-first-argument-name-for-class-method
  • PLR0913: too-many-arguments
  • PLR0917: too-many-positional-arguments

ARG003, ARG004

ARG003 (unused-class-method-argument) -> ARG004 (unused-static-method-argument)

PLW0642

__new__ methods will no longer be checked by PLW0642. This rule only applies to methods and class methods, not static methods.

N804, PLW0211

N804 (invalid-first-argument-name-for-class-method) -> PLW0211 (bad-staticmethod-argument)

PLR0913, PLR0917

PLR0913 (too-many-arguments) and PLR0917 (too-many-positional-arguments) behave differently for classmethod and staticmethod. In classmethod, the first argument cls is excluded from the argument count. In staticmethod, cls is not excluded, so the argument limit applies more strictly.

Example

You can view an example of how these rules are applied here:
https://play.ruff.rs/2df5f2b6-093f-4988-a562-c6101a1c71cc

class ClassDunderNew:
    @classmethod
    def __new__(
        cls,
        x,  # ARG003: Unused class method argument: `x`
    ):
        cls = 1  # PLW0642: Reassigned `cls` variable in class method

    @classmethod
    def __new__(  # PLR0913: Too many arguments in function definition (6 > 5)  # PLR0917: Too many positional arguments (6/5)
        self,  # N804: First argument of a class method should be named `cls`
        a1, a2, a3, a4, a5,
        a6,
    ):
        ...


class StaticDunderNew:
    @staticmethod
    def __new__(
        cls,
        x,  # ARG004: Unused static method argument: `x`
    ):
        cls = 1

    @staticmethod
    def __new__(  # PLR0913: Too many arguments in function definition (6 > 5)  # PLR0917: Too many positional arguments (6/5)
        self,  # PLW0211: First argument of a static method should not be named `self`
        a1, a2, a3, a4, a5,
    ):
        ...

@cake-monotone
Copy link
Contributor Author

I reviewed all the code affected by function_type::classify. Let me know if I missed any affected rules.

Please check if these affected rules are acceptable. :)

@AlexWaygood AlexWaygood removed their assignment Sep 19, 2024
@dylwil3 dylwil3 force-pushed the dunder-new-as-staticmethod branch from 1865ecb to 0e23922 Compare December 25, 2024 05:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A __new__ method should be considered a staticmethod, not a classmethod.
3 participants