Skip to content

PLR6301 doesn't consider base class methods #12172

@minusf

Description

@minusf

Consider the following simple example (and common python pattern in general) in django:
to build a management command, one simply inherits from BaseCommand and overrides some methods:

from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
    def add_arguments(self, parser):
        pass
    def handle(self, *args, **options):
        pass

Currently both of these are marked by ruff 0.5.0 as PLR6301 (https://docs.astral.sh/ruff/rules/no-self-use/).

I tell a lie: I copy pasted this "minimal" example into a new file and there is no warning 😁
However the moment I add actual code to the methods, the warnings show up:

from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
    def add_arguments(self, parser): 
        parser.add_argument("--id", required=True, type=int, help="Page id")

    def handle(self, *args, **options):
        pass

Out of curiosity I installed pylint and ran it on the file and it does not trigger this message...

[tool.ruff]
line-length = 100

[tool.ruff.lint]
preview = true
select = [
    "A",      # https://pypi.org/project/flake8-builtins/
    "B",      # https://pypi.org/project/flake8-bugbear/
    "C4",     # https://pypi.org/project/flake8-comprehensions/
    "C90",    # https://pypi.org/project/mccabe/
    "DJ",     # https://pypi.org/project/flake8-django/
    "DTZ",    # https://pypi.org/project/flake8-datetimez/
    "E", "W", # https://pypi.org/project/pycodestyle/
    "F",      # https://pypi.org/project/pyflakes/
    "FURB",   # https://pypi.org/project/refurb/
    "G",      # https://pypi.org/project/flake8-logging-format/
    "I",      # https://pypi.org/project/isort/
    "N",      # https://pypi.org/project/pep8-naming/
    "PERF",   # https://pypi.org/project/perflint/
    "PIE",    # https://pypi.org/project/flake8-pie/
    "PL",     # https://pypi.org/project/pylint/
    "PT",     # https://pypi.org/project/flake8-pytest-style/
    "PTH",    # https://pypi.org/project/flake8-use-pathlib/
    "RET",    # https://pypi.org/project/flake8-return/
    "RUF",    # Ruff-specific rules
    "S",      # https://pypi.org/project/flake8-bandit/
    "SIM",    # https://pypi.org/project/flake8-simplify/
    "UP",     # https://pypi.org/project/pyupgrade/
]
ignore = ["RUF012"]

[tool.ruff.lint.isort]
# Use a single line between direct and from import.
lines-between-types = 1
section-order = ["future", "standard-library", "third-party", "django", "wagtail", "first-party", "local-folder"]

[tool.ruff.lint.isort.sections]
# Group all Django imports into a separate section.
"django" = ["django"]
"wagtail" = ["wagtail"]

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtype-inferenceRequires more advanced type inference.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions