Author gvanrossum
Recipients gvanrossum, kornicameister, levkivskyi
Date 2020-01-12.05:10:38
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1578805839.02.0.649837539281.issue39308@roundup.psfhosted.org>
In-reply-to
Content
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).
History
Date User Action Args
2020-01-12 05:10:39gvanrossumsetrecipients: + gvanrossum, levkivskyi, kornicameister
2020-01-12 05:10:39gvanrossumsetmessageid: <1578805839.02.0.649837539281.issue39308@roundup.psfhosted.org>
2020-01-12 05:10:38gvanrossumlinkissue39308 messages
2020-01-12 05:10:38gvanrossumcreate