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 — Type variable reported unbound when only a ParamSpec alias's return type uses it and its ParamSpec slot is not a ParamSpec · Issue #22399 · python/mypy

Type variable reported unbound when only a ParamSpec alias's return type uses it and its ParamSpec slot is not a ParamSpec #22399

New issue
Copy link
New issue
Copy link
Open
#22443
Open
Type variable reported unbound when only a ParamSpec alias's return type uses it and its ParamSpec slot is not a ParamSpec#22399
#22443
Copy link
Labels
bugmypy got something wrongmypy got something wrong

Description

@alexeyshockov
alexeyshockov
opened on Nov 8, 2026
Issue body actions

Title: Type variable reported unbound when only a ParamSpec alias's return type uses it and its ParamSpec slot is not a ParamSpec

Bug Report

A function whose return type is a generic alias over a ParamSpec, with a parameter list ([int]) or ... in the
ParamSpec slot, gets Type variable "T" is unbound for a type variable that appears only in that return type. With the
type statement the same function gets Name "T" is not defined, although T is declared in its type parameter list.

The same signature is accepted when:

  • the return type is written without the alias (Callable[[int], T]);
  • the alias has no ParamSpec (Callable[[int], T] aliased);
  • the ParamSpec slot holds a ParamSpec;
  • T also appears in a parameter.

pyright, pyrefly and ty accept all of them.

To Reproduce

from collections.abc import Callable
from typing import ParamSpec, TypeAlias, TypeVar

P = ParamSpec("P")
T = TypeVar("T")

Alias: TypeAlias = Callable[P, T]
NoParamSpec: TypeAlias = Callable[[int], T]


def plain() -> Callable[[int], T]:  # accepted
    raise NotImplementedError


def no_paramspec_alias() -> NoParamSpec[T]:  # accepted
    raise NotImplementedError


def paramspec_alias() -> Alias[[int], T]:  # error: Type variable "T" is unbound
    raise NotImplementedError

With PEP 695 syntax:

from collections.abc import Callable

type Alias[**P, T] = Callable[P, T]


def paramspec_alias[T]() -> Alias[[int], T]:  # error: Name "T" is not defined
    raise NotImplementedError


def with_paramspec[**Q, T]() -> Alias[Q, T]:  # accepted
    raise NotImplementedError

typing_extensions.TypeAliasType("Alias", Callable[P, T], type_params=(P, T)) behaves as the TypeAlias form, and
Alias[..., T] as Alias[[int], T].

Expected Behavior

No errors: paramspec_alias() returns a generic callable def [T] (int) -> T, as plain() does.

Actual Behavior

main.py:19: error: Type variable "main.T" is unbound  [valid-type]
main.py:19: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class)
main.py:19: note: (Hint: Use "T" in function signature to bind "T" inside a function)

and, for the PEP 695 example:

main.py:6: error: Name "T" is not defined  [name-defined]

Where it comes from

A decorator-factory alias over a chain type, Dec = Callable[[Chain[P, T]], Chain[P, T2]]. A factory that applies to
any chain and keeps the item type, def identity() -> Dec[..., T, T], hits this; it has to be written with a
ParamSpec of its own, def identity() -> Dec[P, T, T].

Your Environment

  • Mypy version used: 2.4.1 (compiled)
  • Mypy command-line flags: none (--strict gives the same errors)
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.13 (--python-version 3.13)
  • For comparison: basedpyright 1.40.2 (pyright 1.1.414), pyrefly 1.4.1 and ty 0.0.99 report no error on either file.
  • Not checked on master.

Activity

  1. alexeyshockov
    added
    bugmypy got something wrongmypy got something wrong
    on Nov 8, 2026
  2. xh123637
    added 2 commits that reference this issue on Nov 9, 2026

    Bind type variable to callable expanded from a ParamSpec alias (pytho…

    0a252bb

    Bind type variable to callable expanded from a ParamSpec alias (pytho…

    ca1728d
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

    bugmypy got something wrongmypy got something wrong

    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.