-
-
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
Remove some unnecessary defer rounds #2252
base: master
Are you sure you want to change the base?
Conversation
myapp/models:39: note: Revealed type is "django.db.models.manager.Manager[Any]" | ||
myapp/models:40: note: Revealed type is "django.db.models.manager.Manager[myapp.models.Booking]" | ||
myapp/models:42: note: Revealed type is "myapp.models.UnknownManager[myapp.models.TwoUnresolvable]" | ||
myapp/models:43: note: Revealed type is "myapp.models.UnknownManager[myapp.models.TwoUnresolvable]" | ||
myapp/models:42: note: Revealed type is "django.db.models.manager.Manager[Any]" | ||
myapp/models:43: note: Revealed type is "django.db.models.manager.Manager[Any]" | ||
myapp/models:44: note: Revealed type is "django.db.models.manager.Manager[myapp.models.TwoUnresolvable]" | ||
myapp/models:46: note: Revealed type is "myapp.models.UnknownManager[myapp.models.InvisibleUnresolvable]" | ||
myapp/models:46: note: Revealed type is "django.db.models.manager.Manager[Any]" | ||
myapp/models:47: note: Revealed type is "django.db.models.manager.Manager[myapp.models.InvisibleUnresolvable]" | ||
myapp/models:49: note: Revealed type is "django.db.models.fields.related_descriptors.RelatedManager[myapp.models.Booking]" | ||
myapp/models:50: note: Revealed type is "django.db.models.fields.related_descriptors.RelatedManager[myapp.models.Booking]" | ||
myapp/models:53: note: Revealed type is "def () -> myapp.models.UnknownQuerySet[myapp.models.Booking, myapp.models.Booking]" | ||
myapp/models:53: note: Revealed type is "def () -> django.db.models.query.QuerySet[Any, Any]" | ||
myapp/models:54: error: "Manager[Any]" has no attribute "custom" [attr-defined] | ||
myapp/models:54: note: Revealed type is "Any" | ||
myapp/models:55: note: Revealed type is "def (*args: Any, **kwargs: Any) -> myapp.models.UnknownQuerySet[myapp.models.Booking, myapp.models.Booking]" | ||
myapp/models:55: note: Revealed type is "def (*args: Any, **kwargs: Any) -> django.db.models.query.QuerySet[Any, Any]" | ||
myapp/models:56: error: "QuerySet[Any, Any]" has no attribute "custom" [attr-defined] | ||
myapp/models:56: note: Revealed type is "Any" | ||
myapp/models:57: note: Revealed type is "Union[myapp.models.Booking, None]" | ||
myapp/models:58: note: Revealed type is "myapp.models.Booking" | ||
myapp/models:59: note: Revealed type is "builtins.list[myapp.models.Booking]" | ||
myapp/models:60: note: Revealed type is "builtins.list[myapp.models.Booking]" | ||
myapp/models:57: note: Revealed type is "Union[Any, None]" | ||
myapp/models:58: note: Revealed type is "Any" | ||
myapp/models:59: note: Revealed type is "builtins.list[Any]" | ||
myapp/models:60: note: Revealed type is "builtins.list[Any]" |
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'm going to argue that the changes here improves correctness. Since the manager in the test comes from a function that specifies a manager as return type:
def LocalManager() -> models.Manager:
"""
Returns a manager instance of an inlined manager type that can't
be resolved.
"""
class InnerManager(models.Manager): ...
return InnerManager()
This (now) assigns a type models.Manager[Any]
, the return type of the function. I would say that the previous behaviour did too much, since it tried to express that assigned an invalid manager. But to know that it had to draw conclusions from the function body and thus "override" the return type.
The plugin should now only consider calls of the format: objects = <Manager>.from_queryset(<QuerySet>)()
or objects = <QuerySet>.as_manager()
in this case
Change so that we don't trigger unnecessary defer rounds during manager creation via the `from_queryset` method call.
8ed6834
to
07503e6
Compare
To clarify a little bit more; previously the plugin could tell mypy to defer on e.g. a case like this: def not_a_manager() -> Any: ...
class SomeModel(models.Model):
objects = not_a_manager() Deferring isn't gonna make it a more of a manager. The changed code looks for a more narrow/specific case that we want and can handle that comes from |
Change so that we don't trigger unnecessary defer rounds during manager creation via the
from_queryset
method call.Refs: