Skip to content

Classes inheriting from NamedTuple can't have ParamSpec as generic type parameter #21039

@jonded94

Description

@jonded94

Bug Report

It seems like, as soon as a class inherits from NamedTuple, it's not allowed to have a member anymore that has a ParamSpec as a generic.

Switching the class to be a dataclass instead makes it work without a problem though.

To Reproduce

from typing import Callable, NamedTuple
from dataclasses import dataclass

@dataclass
class X[**P]:
    f: Callable[P, None]

class Y[**P](NamedTuple):
    f: Callable[P, None]

def f[**P](x: X[P]) -> None:
    return None


def g[**P](y: Y[P]) -> None:  # <-- this is the line throwing the error
    return None

Expected Behavior

As far as I can see, this should work without a problem.

This is also explained in the original PEP: https://peps.python.org/pep-0612/#user-defined-generic-classes

$ pyrefly check tst.py
 INFO 0 errors
$ pyright tst.py
0 errors, 0 warnings, 0 informations

Actual Behavior

$ mypy --strict tst.py
tst.py:15: error: Invalid location for ParamSpec "P"  [valid-type]
tst.py:15: note: You can use ParamSpec as the first argument to Callable, e.g., "Callable[P, int]"

Your Environment

  • Mypy version used: 1.19.1
  • Mypy command-line flags: --strict
  • Python version used: 3.12.9

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions