sbdchd / django-types

:doughnut: Type stubs for Django
MIT License
188 stars 62 forks source link

Replace exception classes with ClassVars #156

Closed debonte closed 1 year ago

debonte commented 1 year ago

Addresses https://github.com/microsoft/pylance-release/issues/3918

As currently defined, type checkers see the Model.DoesNotExist and Model.MultipleObjectsReturned exception types as being the same on all Model types.

I'm replacing the exception class declarations on Model with ClassVar so each Model type will have a distinct set of exception types, allowing the usage below without type checkers thinking that the later except clauses are unreachable.

from django.db import models

class User(models.Model):
    email = models.EmailField(max_length=250)

class Notification(models.Model):
    message = models.CharField(max_length=250)

class Media(models.Model):
    file = models.FileField()

def do_things(user_id: int, notification_id: int, media_id: Media) -> None:
    try:
        user = User.objects.get(id=user_id)
        note = Notification.objects.get(id=notification_id)
        media = Media.objects.get(id=media_id)
    except User.DoesNotExist:
        raise Exception(f"User with id {user_id} does not exist.")
    except Notification.DoesNotExist:
        raise Exception(f"Notification with id {notification_id} does not exist.") # <- Pylance marks this as unreachable
    except Media.DoesNotExist:
        raise Exception("Example exception") # <- Pylance marks this as unreachable