Purpose of __name__ in TypeVar, NewType

Question:

In the typing module, both TypeVar and NewType require as a first positional argument, a string to be used as the created object’s __name__ attribute. What is the purpose of __name__ here?

Considering that this is a compulsory argument, I would expect it to be something essential. In PEP-484 where type hinting was introduced, the argument is normally set as a string of the variable name assigned to the object:

T = TypeVar('T', int, float, complex)

But, I can’t really tell how this end up being used in typing.py in CPython. Replacing the string with indeed any other string does not appear to break anything in my tests.

Asked By: Melvin

||

Answers:

The __name__ attribute is the associated typename that the IDE, for example, will use in its type hints. Given the following toy code:

T = TypeVar('not_T', int, float)
def test_func(arg: T): pass

Calling the function with something incorrect like test_func('not_a_number') would result in a type hint like this:

Expected type 'not_t', got 'str' instead

As far as the python interpreter is concerned, no restrictions are set on conformity between type.__name__ and the name tag you use to handle it, but other third-party tools such as mypy might not accept differing variable name and __name__, which is also a requirement in the intitial typing PEP-484:

The argument to TypeVar() must be a string equal to the variable name to which it is assigned. Type variables must not be redefined.


For an additional use case, you can also check the types in the __annotations__ member of any object where it is used to type hint, e.g.

print(test_func.__annotations__)
>> {'arg': ~not_T}

And use that to implement further type checking or handling in your code – in which case your TypeVar.__name__s better be meaningful 🙂

Answered By: Arne
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.