Solvedpylint [Python 3.9] Value 'Optional' is unsubscriptable (unsubscriptable-object) (also Union)


Steps to reproduce

Install Python 3.9, then:

from typing import Optional, Union
foo: Optional[int] = 3
bar: Union[int, str] = 4

Current behavior

Pylint reports E1136: Value 'Optional' is unsubscriptable (unsubscriptable-object) E1136: Value 'Union' is unsubscriptable (unsubscriptable-object)

Expected behavior

This isn't an error in Python 3.8 so I don't think it should be an error in 3.9?

pylint --version output

pylint 2.6.0
astroid 2.4.2

(I tried pip install pylint astroid --pre -U)

13 Answers

✔️Accepted Answer

Also encountering this with the Union type in Python 3.9:

Other Answers:

@metal3d Pylint 2.7.1 is the latest version and I believe the problem you see should have been fixed in version 2.7.0, so try to update Pylint.

Self-contained reproducer, which is not Python 3.9 dependent (but the typing issue is 3.9 dependent):

class deco:
    def __init__(self, f):
        self.f = f

    def __getitem__(self, item):
        return item

def Optional():


Probably related to #2578:

pylint doesn't currently correctly understand decorators

Looks like some code give up checks if the function is decorated, IIRC:

if isinstance(owner, astroid.FunctionDef) and owner.decorators:
    return False

it would be a simple quick-fix if we have no good way of studying the decorator from now.

As my reproducer is not 3.9 specific I'm digging about why the initial reproducer is failing on 3.9:

  • The inferred function on line 1722 of is Optional in 3.9
  • The inferred function on line 1722 of is Union in 3.8

Optional in 3.8 is declared as:

Optional = _SpecialForm('Optional', doc=...)

while in 3.9 it's declared as:

def Optional(self, parameters):

As pylint does not resolve decorator, the inference is still OK in 3.8 (no decorator) but fails in 3.9 (decorated).

Looks like it could be fixed by using something like:

if inferred.decorators:
    first_decorator = helpers.safe_infer(inferred.decorators.nodes[0])
    if isinstance(first_decorator, astroid.ClassDef):
        inferred = first_decorator.instantiate_class()
        return  # TODO: Handle decorators that are not classes

in visit_subscript in

More Issues: