django-stubs icon indicating copy to clipboard operation
django-stubs copied to clipboard

Django QuerySet does not implement `__contains__` but Stubs does

Open fidoriel opened this issue 1 year ago • 1 comments

What's wrong

Stubs implement __contains__ for QuerySet but Django does not.

How is that should be

Django does not implement __contains__ for QuerySet. It relies on the fallback described in the docs at https://docs.python.org/3/reference/expressions.html#membership-test-details. I do not know why this was introduced in https://github.com/typeddjango/django-stubs/pull/33. It is not mentioned there.

class Example:
    def __iter__(self):
        return self

    def __next__(self):
        raise StopIteration

print(42 in Example())

This Minimal example proves that this is not necessary to type it that way. Example does not implement __contains__ but in is usable. So 42 in myQuerySet will work but myQuerySet.__contains__(42) not, because it is not defined (you can check with dir). QuerySet will be type checked correctly by mypy but will not have the same behavior at Runtime because QuerySet does not implement __contains__. A Django QuerySet is not a container because it does not implement __contains__ as described at https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes and https://mypy.readthedocs.io/en/stable/protocols.html#container-t. The docs are clear there. No __contains__ no Container. A static type checker will think that a Django Stubs QuerySet is a Container but a runtime type checker will not recognize a Django QuerySet as a Container. Also, using __contains__(42) will be allowed by Django Stubs but fail on Django at runtime.

Why __contains__ is not implemented with contains for QuerySet in Django, I do not know. But since this project is for typing Django, this is on their site to do. I am planning to open an issue there as well.

System information

  • OS:
  • python: 3.10
  • django: 4.2.7
  • mypy: 1.8
  • django-stubs: 4.2.6
  • django-stubs-ext: None

fidoriel avatar Jan 29 '24 23:01 fidoriel

PR is welcome!

sobolevn avatar Jan 30 '24 06:01 sobolevn