Skip to content

Try supporting protocols that include Mapped with type union #10673

@CaselIT

Description

@CaselIT

The following code reports errors:

from typing import Protocol
from uuid import UUID, uuid4

import sqlalchemy as sa
from sqlalchemy.orm import DeclarativeBase, Mapped, declared_attr


class ModelBase(DeclarativeBase):
    pass


class CompareProtocol(Protocol):
    id: Mapped[int | UUID]  # Or `Mapped[int] | Mapped[UUID]`


class CompareMixin:
    def compare(self: CompareProtocol, other: CompareProtocol) -> bool:
        return self.id == other.id  # Simplified example


class IntIdMixin:
    @declared_attr
    def id(cls) -> Mapped[int]:
        return sa.orm.mapped_column(sa.Integer, primary_key=True)


class UuidIdMixin:
    @declared_attr
    def id(cls) -> Mapped[UUID]:
        return sa.orm.mapped_column(sa.UUID, primary_key=True, default=uuid4)


class MyModel(CompareMixin, IntIdMixin, ModelBase):
    pass


m1 = MyModel()
m2 = MyModel()
m1.compare(m2)  # Mypy reports two errors here

This errors with both mypy and pylance.

See also #10287 (reply in thread)

Metadata

Metadata

Assignees

No one assigned

    Labels

    PRs (with tests!) welcomea fix or feature which is appropriate to be implemented by volunteersormtypingpep -484 typing issues. independent of "mypy"

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions