Why are single type constraints disallowed in Python?

PythonTypesPython 3.6

Python Problem Overview


Suppose you want to constrain a type variable to implement a certain interface. You might write something like so:

from typing import TypeVar, Callable

T = TypeVar('T', Callable)

class Foo(Generic[T]):
    ...

>> TypeError: A single constraint is not allowed

Why is Python unhappy about this use of type constraints? PEP 484 and the Python source code are unhelpful in this regard.

Note: in my particular case I am interested in constraining a type variable to implement an abstract base class, but the principle is the same.

Python Solutions


Solution 1 - Python

You’re looking for bound:

T = TypeVar('T', bound=Callable)

From the docs:

> a type variable may specify an upper bound using bound=<type>. This means that an actual type substituted (explicitly or implicitly) for the type variable must be a subclass of the boundary type, see PEP 484.

TypeVar(name, *args) means that the type has to be one of args, so all instances of T would just be replaceable by Callable if T = TypeVar('T', Callable) were allowed.

You should be able to see the difference here (though I didn’t actually try it, heh):

from typing import Generic, TypeVar, Callable

T = TypeVar('T', Callable, bool)

class Foo(Generic[T]):
    value: T

    def __init__(self, value: T) -> None:
        self.value = value

class Bar:
    baz = 5

    def __call__(self):
        pass

f = Foo(Bar())
print(f.value.baz)  # doesn’t typecheck because f.value is only a Callable

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionalcornView Question on Stackoverflow
Solution 1 - PythonRy-View Answer on Stackoverflow