Skip to content

πŸ› MyPy MRE β€” AsyncSession.get() infers type[T] instead of TΒ #21670

Description

@medmoe

Problem

MyPy incorrectly infers the return type of SQLAlchemy AsyncSession.get() as type[T] | None instead of T | None.

This breaks type narrowing after a None check.


Environment

  • Python: 3.11
  • MyPy: 1.16
  • SQLAlchemy: 2.0.41
  • OS: Linux

Code

from sqlalchemy.ext.asyncio import AsyncSession

class WorkerProfile:
pass

async def test(db: AsyncSession) -> None:
worker_profile = await db.get(WorkerProfile, 1)

reveal_type(worker_profile)

if worker_profile is None:
    return

reveal_type(worker_profile)

Observed MyPy output

First reveal_type:

type[WorkerProfile] | None

Second reveal_type (after narrowing):

type[WorkerProfile]

Expected MyPy output

First reveal_type:

WorkerProfile | None

Second reveal_type:

WorkerProfile

Impact

This makes MyPy treat ORM instances as class objects (type[T]) instead of instances (T), breaking type narrowing and downstream attribute access.


Notes

  • Runtime behavior is correct
  • worker_profile is an instance of WorkerProfile at runtime
  • This only affects static type inference

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions