-
-
Notifications
You must be signed in to change notification settings - Fork 453
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 explicit overload to Field
subclasses
#1900
base: master
Are you sure you want to change the base?
Conversation
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 like the idea. Several comments:
- Please, delete the plugin code, so we can be sure that your changes are enough to pass our CI
- Looks like
stubstest
is not happy with some of the changes. Please, fix or ignore them :)
Great to hear! I'm also experimenting on another solution, but facing some issues (see microsoft/pyright#6914). If this end up working, I think it might be preferable as it would avoid redefining all overloads, + people could easily subclass field classes. Edit: This alternative solution will require some fixes on both pyright and mypy, but it looks promising. On the pyright side, it is currently |
After looking at the related plugin code, I don't know if removing django-stubs/mypy_django_plugin/transformers/fields.py Lines 133 to 153 in 1735d9e
Is being called before mypy actually infers the return type of a call to I also saw a couple hits of public code making use of these attributes on field subclasses. The idea here would be to add tests without the plugin added in the mypy config, and assert that they work. I've tried making use of the I might take a second look and see if it's in fact possible to remove the plugin code |
name = models.CharField(max_length=255) | ||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) | ||
codename = models.CharField(max_length=100) |
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.
Having explicit assignments feels a bit weird in a stub file and was causing issues when testing without the plugin (had error code var-annotated
)
@@ -34,7 +35,7 @@ class GroupManager(models.Manager[Group]): | |||
class Group(models.Model): | |||
objects: ClassVar[GroupManager] | |||
|
|||
name = models.CharField(max_length=150) | |||
name: models.CharField[str | int | Combinable, str] | |||
permissions = models.ManyToManyField(Permission) |
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.
... however I can't explicitly annotate permissions: models.ManyToManyField[..., ...]
as the second type var is solved by the plugin to a class that doesn't exist in stubs nor at runtime
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.
You can have a look here how it can be done: https://github.com/typeddjango/django-stubs/pull/2214/files#diff-0236ca9e909bc4743fa03e6653fc33adbaaef02a34d8698501a63a59ad624f1fR42-R51
mypy_django_plugin.main | ||
- mypy_section: | | ||
[mypy] | ||
disable_error_code = var-annotated |
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.
...So I had to disable the error code anyway when testing without the plugin
46928ae
to
c48f9c7
Compare
This allows type checkers other than mypy to infer correctly the `__set/get__` type variables, without the need for the plugin. The plugin logic to solve these type variables is kept, as some special casing is implemented to handle primary key fields with a default. The `Field` docstring was updated with an example reflecting this
This is required to run mypy without the plugin, as it would complain about these fields requiring an annotation. Using `follow_imports = silent` did not work in this case Also feels more natural than doing an assignment in a stub file
A bit of a hacky solution for now, maybe CI could be improved to add this kind of tests more easily. `var-annotated` is still an ignored error code as I wasn't able to change the assignment to an annotation for `ManyToManyField`s in my previous commit
c48f9c7
to
a075b0b
Compare
I rebased everything to have commits easier to review. CI is now passsing, except stubtests, as I had to make arguments following I created a pull request @ mypy to add a |
Really not ideal, so open to alternatives
Field
subclassesField
subclasses
What's the status here, is it waiting for review? @sobolevn since you commented, do you want to review this? |
I think #1900 (comment) needs to be resolved in some way. Even if not really ideal, the linked mypy open PR seems to be the best option. A slightly more elegant solution to this PR is described here, but unsupported in mypy currently. This PR is also imo not a blocker for the next release |
`db_default` is added on all overloads. `_ST` is replaced by the same set type set on `self`
I think the additions from #2048 is what's breaking the |
I was playing around with getting rid of Now I'm thinking that python/mypy#14764 must be a problem for these changes too? |
In #1264 (comment), and to try working on bringing
django-stubs
anddjango-types
together, I suggested a workaround that would allow type checkers to natively infer_ST
and_GT
without the need for a plugin.Unfortunately, for it to work correctly it would most probably require higher kinded type vars (my current example doesn't play well with subclasses, and I can't use
Self
as it can't be parametrized).This is an experimental test, and as you can see it adds a lot of verbosity. But this removes the need to a plugin to parametrize the type variables, and it support nullable fields.
Would you accept such a change? I'm ok if this isn't accepted, considering how much it adds