What is the difference between TypeVar(bound=Hashable) and just Hashable

Question:

from collections.abc import Iterable, Hashable, Mapping
from typing import TypeVar, Any

K = TypeVar("K", bound=Hashable)


def func1(data: Iterable[K]) -> Mapping[K, Any]:
    t_dict = {k: 0 for k in data}
    return t_dict


def func2(data: Iterable[Hashable]) -> Mapping[Hashable, Any]:
    t_dict = {k: 0 for k in data}
    return t_dict


if __name__ == '__main__':
    data1 = [[1, 2, 3] * 3]
    func1(data1)
    func2(data1)

"""
What is the difference between TypeVar(bound=Hashable) and just Hashable. How it work?
"""

Asked By: Mr. Stand

||

Answers:

In the func1 TypeVar(K) will treat Hashable and all subtypes from it.
It will work if we passed typed data1.
For instance data1: list[list[int], float] = [[1, 2, 3], 4.0].
And now all are worked!

Answered By: Mr. Stand

Occurrences of the abstract base class Hashable (or indeed any class) in the type signature are independent: each one can refer to a completely different type:

def foo(x: Hashable) -> Hashable:
    return 3

This type-checks because no matter what hashable value you pass as an argument, 3 (as an int) is a hashable value.

Type variables must be bound to the same class in each occurrence.

def bar(x: K) -> K:
    return 3

This definition does not type-check because an int is only a valid return value if an int is passed as an argument.

Answered By: chepner
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.