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

Make Model.objects a ClassVar #394

Closed
wants to merge 1 commit into from

Conversation

davidhalter
Copy link

Model.objects is only available on classes and while we cannot force this, without ClassVar it's kind of only available on instances.

I have noticed this when I was writing a Jedi plugin that makes django-stubs work properly.

@davidhalter
Copy link
Author

davidhalter commented Jun 9, 2020

The test suite is failing, but master is also failing on Travis, so I'm not sure if that's my fault.

I also don't really understand why this one line change would cause so many test failures.

@sobolevn
Copy link
Member

sobolevn commented Jun 9, 2020

@davidhalter that's totally not your fault. We have some unexpected failures from our build system.

@@ -22,7 +22,7 @@ class Model(metaclass=ModelBase):
class Meta: ...
_meta: Options[Any]
_default_manager: BaseManager[Model]
objects: BaseManager[Any]
objects: ClassVar[BaseManager[Any]]
Copy link
Member

Choose a reason for hiding this comment

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

This is a great addition! But, this does raise an important topic to discuss.

Currently, we do not treat properties as ClassVars. I guess that we need to fix that. And mark ones that apply as ClassVars.

@danifus can you please open a new issue?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi, was this comment intended for me or @davidhalter?

Copy link
Member

Choose a reason for hiding this comment

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

Oups! 😆 My bad!

But, feel free to participate!

Copy link
Author

@davidhalter davidhalter Jun 12, 2020

Choose a reason for hiding this comment

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

@sobolevn I don't really understand what needs to be fixed. I see that the CI is still failing even after I force pushed an amended commit. I'm guessing that has something to do with the Mypy plugin. But since I'm not using Mypy, I'm only interested in correct type annotations and I would appreciate if you guys could take it from here.

I obviously understand that this is more work, but it's not my forte. As a temporary measure, I might just ship a patched version in Jedi until this gets fixed.

Still thanks for looking at it @sobolevn!

Copy link
Member

Choose a reason for hiding this comment

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

@sobolevn Failing tests are not a matter of the bug I've fixed, I've just checked that. Introducing ClassVars to our stubs it quite a big change. It'd be awesome @davidhalter if you could create an issue on this one. As @sobolevn wrote, marking properties that apply as ClassVar would be a lot of help too. Thank you for your work, I can take it from here if you want me to 😄

Copy link
Author

Choose a reason for hiding this comment

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

@kszmigiel Yeah feel free to take it from here, I really have no idea :)

I can of course create an issue, but I'd rather not, since I really don't understand what the issue is. The issue would probably have the content "ClassVar for Model.objects doesn't work". If that has value for you, I'm fine doing that :).

Copy link
Member

Choose a reason for hiding this comment

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

@davidhalter Sure thing, I'll create an issue for that later, thanks for pointing this out 😄

@sobolevn
Copy link
Member

sobolevn commented Jun 9, 2020

Thanks a lot for your work! 👍

@sobolevn
Copy link
Member

The CI is fixed.

davidhalter added a commit to davidhalter/jedi that referenced this pull request Jun 12, 2020
Model.objects is only available on classes and while we cannot force this, without ClassVar it's kind of only available on instances.

I have noticed this when I was writing a Jedi plugin that makes django-stubs work properly.
@adamchainz adamchainz changed the title Model.objects should be a ClassVar Make Model.objects a ClassVar Nov 3, 2022
@adamchainz
Copy link
Contributor

I’ve rebase this PR - @sobolevn want to double check and merge?

@sobolevn
Copy link
Member

sobolevn commented Nov 3, 2022

Looks like this needs a bit more work:

 django-stubs/contrib/sites/models.pyi:14: error: Cannot override class variable (previously declared on base class "Model") with instance variable
django-stubs/contrib/contenttypes/models.pyi:18: error: Cannot override class variable (previously declared on base class "Model") with instance variable
django-stubs/contrib/auth/models.pyi:22: error: Cannot override class variable (previously declared on base class "Model") with instance variable
django-stubs/contrib/auth/models.pyi:33: error: Cannot override class variable (previously declared on base class "Model") with instance variable
django-stubs/contrib/admin/models.pyi:32: error: Cannot override class variable (previously declared on base class "Model") with instance variable
django-stubs/contrib/sessions/base_session.pyi:17: error: Cannot override class variable (previously declared on base class "Model") with instance variable

@adamchainz
Copy link
Contributor

Yeah I was just looking at this. We can add objects: ClassVar[models.Manager] = ... in many places, but that will erase some of the inferred types from the Mypy plugin. I think the plugin would need adjusting to wrap its return types with ClassVar[...], if that’s possible.

It might also annoying to users if they have to add ClassVar everywhere they override a manager.

@sobolevn
Copy link
Member

sobolevn commented Nov 3, 2022

ClassVar is only really helpful when there are classmethods. Otherwise, overriding class-level variables with instance-level ones is not great, but not problematic.

This is what we do in typeshed at least.

@adamchainz
Copy link
Contributor

So you think we can close this one? It does seem quite disruptive.

@sobolevn
Copy link
Member

sobolevn commented Nov 3, 2022

Yes, I think so.

@davidhalter thank you for your proposal!

If anyone wants to submit a full-featured solution, please provide real-world use-cases where this can be useful first.

@sobolevn sobolevn closed this Nov 3, 2022
@PeterJCLaw
Copy link
Contributor

Cross linking: it looks like #1150 may have resolved this.

@davidhalter
Copy link
Author

I feel like I also changed the default behavior of non-ClassVar variables on classes to be available on classes as well. This is something that Mypy allows as well, so I figured we are probably not wrong to allow that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

6 participants