python / python/mypy

Can't assign default argument value to type when using ParamSpec

Open
#16,176 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

I have a function that takes a Callable with ParamSpec, and I want to set a default for this parameter to a type.

To Reproduce

from typing import Callable, Concatenate, ParamSpec

P = ParamSpec("P")

class Foo:
    def __init__(self, a: int, /, b: str) -> None:
        self.a = a
        self.b = b

        
def func(cls: Callable[Concatenate[int, P], Foo] = Foo) -> Callable[P, Foo]:
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> Foo:
        return cls(1, *args, **kwargs)
    return wrapper

However, mypy complains:

main.py:11: error: Incompatible default for argument "cls" (default has type "type[Foo]", argument has type "Callable[[int, **P], Foo]")  [assignment]

https://mypy-play.net/?mypy=latest&python=3.11&flags=new-type-inference&gist=065da8e39f9cecda995ea9d598b9441e

Expected Behavior

I expect mypy to accept this default value, since removing the default and calling func works fine:

def func(cls: Callable[Concatenate[int, P], Foo]) -> Callable[P, Foo]:
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> Foo:
        return cls(1, *args, **kwargs)
    return wrapper
    
func(Foo)("b")

https://mypy-play.net/?mypy=latest&python=3.11&flags=new-type-inference&gist=289ae2368c78c0d9636dcc8766baf135

Your Environment

  • Mypy version used: 1.5.1
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.11

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the main.py reproducer and the linked mypy-play examples, then trace checking of the ParamSpec-based Callable default. Compare the defaulted and non-defaulted func definitions. Done means the reported incompatible-default error is resolved for this example and the behavior is covered by an appropriate regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.