GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Bounded TypeVar inferred as object for nested covariant generic arguments · Issue #22331 · python/mypy

Bounded TypeVar inferred as object for nested covariant generic arguments #22331

New issue
Copy link
New issue
Copy link
Open
Open
Bounded TypeVar inferred as object for nested covariant generic arguments#22331
Copy link

Description

@ayushin
ayushin
opened on Oct 30, 2026
Issue body actions

Bug report

Mypy infers object for a bounded type variable when combining covariant generic arguments, although their common upper bound is valid. This reproduces without Django or plugins.

Reproducer

from typing import Generic, TypeVar
class Model: pass
class Person(Model): pass
class Audit(Model): pass
M = TypeVar("M", bound=Model, covariant=True)
class QuerySet(Generic[M]): pass
Q = TypeVar("Q", bound=QuerySet[Model], covariant=True)
L = TypeVar("L", bound=str, covariant=True)
P = TypeVar("P", bound=Person)
class Prefetch(Generic[L, Q]):
    def __init__(self, lookup: L, queryset: Q) -> None: ...
def accept(*items: Prefetch[L, Q]) -> None: ...
def example(people: QuerySet[P], audits: QuerySet[Audit]) -> None:
    accept(Prefetch("left", queryset=people), Prefetch("audit", queryset=audits))

Expected: the call is accepted; Q = QuerySet[Model] satisfies both arguments and its bound.

Actual:

error: Value of type variable "Q" of "accept" cannot be "object"  [type-var]

Annotating each argument as Prefetch[str, QuerySet[Model]] before the call succeeds. Using concrete QuerySet[Person] instead of QuerySet[P], or removing the L parameter from Prefetch, also succeeds. Merely assigning the arguments to unannotated intermediate variables does not help.

Environment: Python 3.14.6; reproduced on mypy 2.4.1 and unmodified master d8a43fbcf21e30bd7855b5635bdd2f07ffbb5d95, without plugins or project configuration (--no-incremental --cache-dir=/dev/null --config-file=/dev/null).

Originally reported as typeddjango/django-stubs#3770. The draft stubs PR bypasses this inference and is being withdrawn in favor of reporting the checker issue.

Investigation and reproducer prepared with AI assistance.

Activity

  1. Anurag-S1ngh commented on Oct 31, 2026

    @Anurag-S1ngh
    Anurag-S1ngh
    on Oct 31, 2026
    More actions

    Hi, I'd like to take this issue. Could you assign it to me?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.