astral-sh / ruff

An extremely fast Python linter and code formatter, written in Rust.
https://docs.astral.sh/ruff
MIT License
32.84k stars 1.1k forks source link

SLF001 when using Django Model `_meta` API #13382

Closed bittner closed 1 month ago

bittner commented 2 months ago

In Django, there is the Model _meta API, an endorsed way to access internal information about a model.

Example model:

class MyModel(models.Model):

    class Meta:
        db_table = "custom_table_name"

Example usage:

table_name = MyModel()._meta.db_table

The way the API is used is by the _meta member, which quite obviously triggers SLF001 as a linter warning. (As of Ruff version 0.6.4)

There's no other way to access the members of this API, and as this is an official API of the Django framework it's not clear why code like this should be discouraged (unless it's about motivating the Django project to redesign this API).

Is there any chance we could make Ruff consider this as an accepted pattern? -- Should this request be submitted to the flake8-django project, first?

charliermarsh commented 2 months ago

I think I'd recommend adding this to ignore-names -- does that work?

E.g.:

[tool.ruff.lint.flake8-self]
ignore-names = ["_meta"]
bittner commented 2 months ago

That works, thank you! :+1:

But shouldn't we make this a general rule, and more specific, just for Django Model classes?

MichaReiser commented 1 month ago

But shouldn't we make this a general rule, and more specific, just for Django Model classes?

That would be great, but Ruff must understand that models.Model inherits a Django model, something it currently doesn't understand because it lacks multifile analysis.

An alternative is to default to ignoring _meta whenever there's a django import, but I don't even know if that's the case for this file. This has the risk of the rule missing _meta usages outside of a Django model.

Overall, ignore names is a good explicit opt in for now.