Skip to content
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

Question: How to bound a mixin to a subclass #8705

Open
canassa opened this issue Apr 21, 2020 · 1 comment
Open

Question: How to bound a mixin to a subclass #8705

canassa opened this issue Apr 21, 2020 · 1 comment
Labels
question topic-inheritance Inheritance and incompatible overrides topic-protocols

Comments

@canassa
Copy link

canassa commented Apr 21, 2020

I created a mixin for Django models and I would like to know how to properly type it, e.g.:

from django.db import models

T = TypeVar("T", bound=models.Model)


class SafeCreateMixin:
    @classmethod
    @transaction.atomic()
    def safe_create(cls: Type[T], **kwargs) -> Optional[T]:
        try:
            return cls.objects.create(**kwargs)
        except IntegrityError as e:
            return None

class MyModel(SafeCreateMixin, models.Model):
    ....

It fails with the following error:

error: The erased type of self "Type[django.db.models.base.Model]" is not a supertype of its class "Type[SafeCreateMixin]"

I understood that the mypy docs recommend creating a Protocol for mixins, but in my case, I just want to enforce that my mixins are added to a subclass of models.Model

@AlexWaygood AlexWaygood added question topic-protocols topic-inheritance Inheritance and incompatible overrides labels Apr 4, 2022
@erictraut
Copy link

There isn't a way to declare this relationship in the type system today, but you can use a runtime assert to enforce it.

class SafeCreateMixin:
    @classmethod
    def safe_create(cls, **kwargs) -> Self | None:
        assert issubclass(cls, models.Model)
        try:
            return cls.objects.create(**kwargs)
        except IntegrityError:
            return None

erictraut pushed a commit to microsoft/pyright that referenced this issue Aug 24, 2023
… intersection type is created and one of the two subclasses has a custom metaclass. This is related to mypy issue python/mypy#8705.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question topic-inheritance Inheritance and incompatible overrides topic-protocols
Projects
None yet
Development

No branches or pull requests

3 participants