Mixing PEP 695 and 696 (Type Parameter with default)

Hi,

has anybody thought about mixing PEP 695 and 696?
Currently it is hard / impossible to create a dynamic function with a given default.

from typing import TypeVar

T = TypeVar("T")

# This won't work with MyPy atm
def string_tuple(s: T = 1) -> tuple[str, str, str)
    return str(s), str(s), str(s)

Now with PEP 696 we can get it to work

from typing import TypeVar

T = TypeVar("T", default=str)

def string_tuple(s: T = 1) -> tuple[str, str, str)
    return str(s), str(s), str(s)

But I also would like to use PEP 695 and simply be able to write:

def string_tuple[T: default=str](s: T = 1) -> tuple[str, str, str)
    return str(s), str(s), str(s)

As PEP696 didn’t make it into Python 3.12, would it be possible to add this feature, as PEP 695 was added to Python 3.12 already?

I know this was already discussed a bit but I think a new thread makes it easier to find and discuss.

This is already part of PEP696: PEP 696 – Type defaults for TypeVarLikes | peps.python.org

But of course this will not be possible to use until Python 3.13, since it requires changes to the grammar.

Thanks for pointing this out, I kind of missed it :person_shrugging:

Yes, the PEP 695 syntax was designed with PEP 696 in mind. If PEP 696 is accepted in its current form, the PEP 695 syntax would be extended to allow for defaults. This would simply involve an = token followed by the default value. There’s no need to introduce a default keyword to the grammar.

def string_tuple[T = str](s: T = 1) -> tuple[str, str, str]:
    return str(s), str(s), str(s)

Provisional support for PEP 696 — including the grammar changes — is already implemented in pyright if you’d like to play with it. You need to tell pyright that you want it to assume Python 3.13. Obviously, this won’t work at runtime unless/until the PEP is accepted and the grammar changes implemented in the CPython code base.

2 Likes