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

Unexpected type Unknown with default Model manager

Open dan-woz opened this issue 1 year ago • 7 comments

I'm having trouble getting the correct types to be inferred using django-types with Pyright, specifically when using the default objects manager.

Expectation

from django.db import models

class Thing(models.Model):
    field = models.TextField()

def query_thing(id: str) -> Thing:
    thing = Thing.objects.get(id=id)
    return thing

In this example, variable thing should be understood as type Thing.

Actual

For me, variable thing is typed as Unknown.

Image

Adding an explicit objects: models.Manager["Thing"] to my Thing model gives me the correct type for this specific case, but breaks again if I add in any sort of .filter, etc. calls to the query builder.

Environment

  • django-types: 0.20.0
  • pyright: 1.1.392
  • python: 3.13.1

I'm not completely convinced this is a problem with django-types as opposed to something else, but I'm not sure where to look/how to debug this issue.

dan-woz avatar Jan 16 '25 22:01 dan-woz

hmm does the issue happen with mypy as well, wonder if something changed

sbdchd avatar Jan 17 '25 03:01 sbdchd

For reference, I reverted my Python version back to 3.12.8, and types appear to be working again. I suspect it's something in the 3.13 upgrade.

dan-woz avatar Jan 17 '25 05:01 dan-woz

Okay, I haven't used mypy before, so this could be wrong, but it appears to get the typing correct with django-stubs installed.

Here is my new source file testo.py.

from django.db import models

class Thing(models.Model):
    field = models.TextField()

    objects: models.Manager["Thing"]

def query_thing(id: str) -> Thing:
    thing = Thing.objects.filter(id=id).get(id=id)
    reveal_type(thing)
    return thing

When I run mypy testo.py on this file, I get the following output.

testo.py:10: note: Revealed type is "testo.Thing"
Success: no issues found in 1 source file

Looks correct to me. This is with the following environment.

  • python: 3.13.1
  • mypy: 1.14.1
  • django-stubs: 5.1.2

EDIT: I will note that removing the explicit objects type line results in an error from mypy.

testo.py:7: error: "type[Thing]" has no attribute "objects"  [attr-defined]
testo.py:8: note: Revealed type is "Any"
Found 1 error in 1 file (checked 1 source file)

dan-woz avatar Jan 17 '25 05:01 dan-woz

django-stubs is the parent of this fork, what happens if you use django-types with mypy?

sbdchd avatar Jan 17 '25 15:01 sbdchd

How do I set up mypy to use django-types? I'm using the basic pyproject.toml configuration suggested in the django-stubs README, but running mypy with that config + django-types gives me an error.

Error importing plugin "mypy_django_plugin.main": No module named 'mypy_django_plugin'

dan-woz avatar Jan 17 '25 17:01 dan-woz

this project (django-types), doesn't use a mypy plugin so If you remove that it might work?

sbdchd avatar Jan 19 '25 03:01 sbdchd

Yeah, removing the mypy plugin line from my pyproject.toml seems to have worked. I'm also getting the correct type from reveal_type with mypy.

dan-woz avatar Jan 19 '25 05:01 dan-woz