Guido van Rossum <[email protected]> added the comment:
No need to open the attachment -- a simpler repro is:
>>> from typing import Literal
>>> Literal[1]
typing.Literal[1]
>>> Literal[True]
typing.Literal[1]
>>>
However, in a fresh session
>>> from typing import Literal
>>> Literal[True]
typing.Literal[True]
>>>
This must be because there's a cache in typing.py that use == but doesn't check
the type. We can demonstrate that this is the case using a similar equivalence
between 2.0 and 2:
>>> Literal[2.0]
typing.Literal[2.0]
>>> Literal[2]
typing.Literal[2.0]
>>>
It looks like the function _tp_cache() is the culprit -- it uses
functools.lru_cache() which apparently uses simple equality.
def _tp_cache(func):
"""..."""
cached = functools.lru_cache()(func)
_cleanups.append(cached.cache_clear)
@functools.wraps(func)
def inner(*args, **kwds):
try:
return cached(*args, **kwds)
except TypeError:
pass # All real errors (not unhashable args) are raised below.
return func(*args, **kwds)
return inner
Here's a confusing demo:
>> @functools.lru_cache()
... def f(a): return a
...
>>> f(1)
1
>>> f(True)
True
>>> f(1)
1
>>> f(1.0)
True
>>>
(Confusing because it distinguishes between 1 and True, unlike Literal, but it
then maps 1.0 to True.)
However a possible fix might be to add typed=True to the functools.lru_cache()
call in typing.py, which should have the desired effect (not tested).
----------
title: Literal declarations are not typed. Literal[True] can be Literal[1] if
declared after latter. -> Literal[True] prints as Literal[1] in some cases
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue39308>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com