Skip to content

Django-stubs > 5.1.1 causes VSCode to infer model field types as Any instead of expected types #2534

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

Open
lucemia opened this issue Mar 11, 2025 · 8 comments
Labels
bug Something isn't working pyright Related to pyright type checker

Comments

@lucemia
Copy link
Contributor

lucemia commented Mar 11, 2025

Bug report

What's wrong

After upgrading to django-stubs version > 5.1.1, VSCode's type intelligence no longer correctly infers the type of model fields. Specifically, it treats fields as Any instead of their expected types.

Reproduction

Minimal example:

from django.db import models

class Temp(models.Model):
    text = models.TextField()

t = Temp()
t.text  # Expected: str, but reported as Any in VSCode

Expected Behavior

  • django-stubs 5.1.1 correctly infers t.text as str in VSCode.
  • django-stubs > 5.1.1 incorrectly treats t.text as Any in VSCode.

Observations

  • Running mypy still shows str as expected.
  • Issue only affects VSCode’s type intelligence (Pylance/pyright).
  • Removing the py.typed file from the django-stubs folder fixes the issue, but the reason is unclear.
  • Downgrading django-stubs to 5.1.1 restores correct type inference.

How is that should be

VSCode should correctly infer the type of model fields, just like in django-stubs 5.1.1. The expected behavior is:

t.text  # Type should be inferred as str, not Any

System information

  • OS: Mac
  • python version: 3.11
  • django version: 5.1
  • mypy version: 1.13.0
  • django-stubs version: 5.1.3
  • django-stubs-ext version: 5.1.3
@lucemia lucemia added the bug Something isn't working label Mar 11, 2025
@sobolevn
Copy link
Member

Sorry, I have no idea how pylance works, it is not supported officially. If you know how to fix it, please send a PR.

@lucemia
Copy link
Contributor Author

lucemia commented Mar 11, 2025

Sorry, I have no idea how pylance works, it is not supported officially. If you know how to fix it, please send a PR.

Sure, would like to open PR once I figure out what's the right way to do so.

microsoft/pylance-release#6029 (comment)

@jhassine
Copy link

jhassine commented Mar 11, 2025

Observations

  • Running mypy still shows str as expected.
  • Issue only affects VSCode’s type intelligence (Pylance/pyright).
  • Removing the py.typed file from the django-stubs folder fixes the issue, but the reason is unclear.
  • Downgrading django-stubs to 5.1.1 restores correct type inference.

What i have read from other issue reports, here is the conclusion in for your case:

  • When you remove py.typed from django-stubs, then VScode/Pylance defaults to it's internally shipped stubs which is based on django-types library.
  • py.typed marker was added in django-stubs version 5.1.2.

Given your code example, with django-stubs (5.1.3) installed:

Image

BTW: in case you wondered I used inlay hints in vscode, to show the inferred types inline.

When you remove django-stubs library or manually install django-types stubs, you would see this:

Image

With django-stubs, to make all type checkers happy (including pyre) you would need to do the following:

Image

I noticed there is quite good discussion here about django-stubs compared to django-types: #579

@ebk46
Copy link

ebk46 commented Mar 24, 2025

Thanks @jhassine - removing py.typed worked for us as well.

Is there hope for a package-default solution to resolve this?

@jhassine
Copy link

@ebk46 ok.

Depends what you mean by "package-default solution"?

Just a note for you based on my experiences: instead of removing py.typed from django-stubs you can also straight install django-types package and have django-stubs NOT installed. Otherwise you likely end up having somewhat conflicting situation especially if you use multiple type checkers: as VSCode+Pylance would use it's internally shipped django-types and other type checkers would use django-stubs. They most noticeable differ with how to define the generics of Django model fields. There are other differences too which I linked in my previous comment.

How I see, one should decide whether to use django-stubs or django-types package in their project. But not use them both at the same time.

Personally I prefer django-stubs as it supports better what's new in Django 5 (at least there seem to be an open ticket for django-types package Django 5 version support.

However django-stubs has a downside you would need to do add more type annotations by hand if you want to keep multiple type checkers happy (except mypy which seems working okay with django-stubs). But once you put the additional type annotations in place by hand, you will have pretty good experience.

I admit it's a bit confusing, took a while for me to understand as well.

Ideally django-stubs would have some more complete implementation it would work similar fashion than django-types. If I had extra time, I would investigate more.

Second best would be to have more complete documentation how to make django-stubs work well with non-mypy type checkers.

@ebk46
Copy link

ebk46 commented Mar 24, 2025

@jhassine I meant is this something the maintainers of django-stubs are likely to fix. I am using mypy with VSCode and not doing anything special otherwise so I would think my setup is fairly common. This issue only seemed to arise with an upgrade from mypy 1.14.1 to 1.15.0.

We are still on Django 4.2 so django-types might be a solution for us for now, but we'd prefer to stick with django-stubs for Django 5 support.

@jhassine
Copy link

@ebk46 ok.

Well, I am not the maintainer but have understood that contributions in the form of PRs are welcomed 😅

Hmm, I have been using mypy 1.15 for a good while already and haven't noticed anything strange compared to the previous versions. What kind of issues you have?

I have understood, mypy 1.15 is officially supported by the project since version 5.1.3 and the py.typed marker was added in 5.1.2 so they are pretty close. So I am not sure if your issues are related now to mypy or something else?

@ebk46
Copy link

ebk46 commented Mar 25, 2025

@jhassine I did some investigation and for some reason uninstalling and reinstalling django-stubs resolved what I was seeing. Not sure what kind of conflicts there were, but I was seeing the following:

foo: Foo = Bar.objects.get(id=1).foo

That .foo foreign key was "Unknown" despite it being defined in the Bar class as a foreign key to a Foo object. I had hoped to correct it using foo: Foo but VS Code was still considering it Foo | Unknown unless I actually used cast

I did try django-types and, maybe I'm missing something, but it didn't seem to work at all in our project. Foreign key relationships were typed as ForeignKey rather than the object they referenced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working pyright Related to pyright type checker
Development

No branches or pull requests

4 participants