typeddjango / django-stubs

PEP-484 stubs for Django
MIT License
1.52k stars 425 forks source link

Assignment of django model field to wrong type of var does not show error #2251

Closed sam-ghosh closed 1 week ago

sam-ghosh commented 1 week ago

Bug report

Assignment of django model field to wrong type does not show error

What's wrong

        tickets = RUSupportTicket.objects.all()

        reveal_type(tickets) # Revealed type is "django.db.models.query._QuerySet[RUSupportTicket, RUSupportTicket]" (113:20)
        reveal_type(tickets[0])  # Revealed type is "RUSupportTicket" (114:20)
        a = tickets[0]
        reveal_type(a)  # RUSupportTicket

        reveal_type(a.friendly_title)  # str

        a.friendly_title = 123  # does not show error

How is that should be

a.friendly_title = 123  # THIS LINE should show mypy warning of incorrect assignment of int to str

System information

sobolevn commented 1 week ago

Sorry, these two lines are confusing:

        reveal_type(a.friendly_title)  # int

        a.friendly_title = 123  # does not show error

if mypy infers a.friendly_title as int (as you say), so, why it should raise a warning on a.friendly_title = 123?

sam-ghosh commented 1 week ago

You are correct @sobolevn , it is my bad - i put wrong comment, i have fixed it now

should be reveal_type(a.friendly_title) # str

flaeppe commented 1 week ago

There's nothing displaying what field friendly_title is, but I would guess that it's declared as a CharField.

The default behaviour from django-stubs regarding CharField declares that it accepts int, str or Combinable as set types. Ref:

https://github.com/typeddjango/django-stubs/blob/f89454da6b2e932577cd9356f4424832980c560d/django-stubs/db/models/fields/__init__.pyi#L294-L296

It's possible to change that if you set explicit set/get type arguments to CharField. e.g. the following would declare that friendly_title only accepts stras set and get type:

class RUSupportTicket(models.Model):
    friendly_title = CharField[str, str]()
sam-ghosh commented 1 week ago

Thanks @flaeppe , i understand a bit better now. What I now understand is that there is much more more to django-stubs than what is shown on the readme

For example syntax like models.CharField[str, str] is even possible is not shown with examples in the readme or anywhere else, do you have a recommendation of where I can see a "recipe book" or a "cookbook" kind of standard and best practices to use django-stubs?

flaeppe commented 1 week ago

While I agree that documentation could definitely improve. I unfortunately don't have any good place to point to for reading.

Closest thing I could come up with is to read Mypy's documentation