-
-
Notifications
You must be signed in to change notification settings - Fork 466
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
Add ClassVar
annotations on mutable ModelAdmin
types for ruff
#2524
Add ClassVar
annotations on mutable ModelAdmin
types for ruff
#2524
Conversation
See astral-sh/ruff#5243 for RUF012 discussion Signed-off-by: Yury V. Zaytsev <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, fix the CI. What about other fields? It would be strange to have just two ClassVar
s and others as regular intance fields.
Hey Nikita! Cheers to Nizhny.
Thanks for the very quick response! I'll look into it.
You tell me :) That's what I asked in the PR description.
|
I want fields that are really class Some:
x: ClassVar[int] = 1
@classmethod
def print_x(cls) -> None:
print(cls.x) # `x` cannot be an instance field, because we have explicit `cls.x` usage But, if some field can be both instance and class level, then this would be an error: class Some:
x: ClassVar[int] = 1
def __init__(self) -> None:
self.x = 2 # error: instance level overrides a classvar So, in this case - I think that As the result, if some fields are class-level fields, then let's add annotations. If not - let's keep this as-is. |
I think I understand where
Thank you for the explanation and examples. It was very helpful. I agree with you that it makes sense to mark fields with I went through the Django documentation here and marked all the fields listed there as configuration class variables: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-options I had to leave out Also, this idiom is quite common in Django. Do you have any idea what else you think should be marked? I think it could include the following classes:
This would probably be too much work for me alone. And maybe better submitted as separate PRs anyway. |
Nope, that's a limitation of our type system. |
@@ -150,33 +150,33 @@ _ActionCallable: TypeAlias = Callable[[_ModelAdmin, HttpRequest, QuerySet[_Model | |||
class ModelAdmin(BaseModelAdmin[_ModelT]): | |||
list_display: _DisplayT[_ModelT] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, add a comment: why do we left these two without a ClassVar
, so future users won't be confused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in 3e2fdc8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if any of the attributes have any use case to be modified outside/after class declaration.
Though changing to ClassVar is making it stricter, we could always relax it later on if needed.
I don't have any strong opinions here
Yes, I wondered about this as well and actually checked the Django source code. It seems that this is not the case. Of course, this is not necessarily true for user code. However, the usual pattern seems to be "if you need to override something, don't touch the class variables, override Maybe some real user feedback will come after the updated stubs make it into PyCharm. Do you have any idea how often this happens? Until then, it might not be a good idea to process the remaining classes. I think it's worth looking at |
See also: - astral-sh/ruff#5243 - typeddjango#2524 Signed-off-by: Yury V. Zaytsev <[email protected]>
See also: - astral-sh/ruff#5243 - #2524 Signed-off-by: Yury V. Zaytsev <[email protected]>
I have made things!
I suggest adding
ClassVar
annotations on mutableModelAdmin
types to silence theruff
ruleRUF012
:https://docs.astral.sh/ruff/rules/mutable-class-default/
This rule requires that mutable types are explicitly marked as class (as opposed to instance) variables. There is some discussion in the referenced issue (astral-sh/ruff#5243) as to whether or not this rule should apply to DSL-type classes at all.
When writing Django code, I think it's generally easy to solve the problem by switching from lists to tuples for user-written code, but dictionaries are more tricky. Adding
ClassVar
annotations takes care of the dictionary story as well. It's not even wrong!As far as migrations are concerned, either Ruff should add exceptions based on class hierarchy, as they apparently did for Pydantic, or maybe the lists can be marked as
ClassVar
here. I'm not sure how you (and the Ruff developers) feel about this, so I'm not adding any more types at the moment. Besides, the problem can be solved by per-file excludes:Related issues
Refs astral-sh/ruff#5243.