pylint icon indicating copy to clipboard operation
pylint copied to clipboard

`Enum` values which are of type `TypedDict` are unsubscriptable (false positive)

Open Trombach opened this issue 3 years ago • 4 comments

Bug description

If an Enum has a TypedDict as a value pylint shows a false positive for "unsubscriptable-object". However, this is correctly detected by, for instance, mypy and the python extension in VSCode. The latter even offers IntelliSense completion for the subscript name.

# pylint: disable=missing-class-docstring, missing-module-docstring, missing-function-docstring, invalid-name
from enum import Enum
from typing import TypedDict


class TypedDictionary(TypedDict):
    name: str


class Enumerations(Enum):
    KEY1: TypedDictionary = {"name": "from enum"}


def return_enum_value() -> TypedDictionary:
    return Enumerations.KEY1.value


def return_typed_dict() -> TypedDictionary:
    return {"name": "from function"}


if __name__ == "__main__":
    value1: TypedDictionary = {"name": "flat"}
    assert value1["name"] == "flat"

    value2 = return_typed_dict()
    assert value2["name"] == "from function"

    value3 = Enumerations.KEY1.value
    assert value3["name"] == "from enum"

    value4 = return_enum_value()
    assert value4["name"] == "from enum"

Configuration

No response

Command used

pylint test.py

Pylint output

************* Module test
test.py:30:11: E1136: Value 'value3' is unsubscriptable (unsubscriptable-object)
test.py:33:11: E1136: Value 'value4' is unsubscriptable (unsubscriptable-object)

Expected behavior

value3 and value4 should not be shown as unsubscriptable.

Pylint version

pylint 2.14.5
astroid 2.11.7
Python 3.10.5 (main, Jun 23 2022, 17:14:57) [Clang 13.1.6 (clang-1316.0.21.2.5)]

OS / Environment

MacOS 12.5 zsh 5.8.1 (x86_64-apple-darwin21.0) VSCode 1.70.0 (Universal) with Python extension v2022.12.0

Additional dependencies

No response

Trombach avatar Aug 05 '22 01:08 Trombach

Great report.

I think it could be simply an issue with the type annotation, and not necessarily connected to TypedDict.

(venv310) Marks-MacBook-Air-2:programming markbyrne$ cat example.py 
from enum import Enum


class Veg(Enum):
    TOMATO: dict = {"variety": "beefsteak"}


print(Veg.TOMATO.value["variety"])

(venv310) Marks-MacBook-Air-2:programming markbyrne$ pylint example.py 
example.py:8:6: E1136: Value 'Veg.TOMATO.value' is unsubscriptable (unsubscriptable-object)

(venv310) Marks-MacBook-Air-2:programming markbyrne$ python example.py 
beefsteak

Removing the : dict in this example prevents the unsubscriptable-object message

Update: Updating this line in astroid to be if isinstance(stmt, (nodes.AnnAssign, nodes.Assign)): seems to fix it.

mbyrnepr2 avatar Aug 05 '22 09:08 mbyrnepr2

@mbyrnepr2 Thanks for the quick fix! Is there any way to know when this will make it into a release?

Trombach avatar Aug 07 '22 20:08 Trombach

You can check the 2.15 release milestone (on mobile so I can't link, but click on 2.15 in the sidebar). The issue labelled 'blocker' in particular.

Pierre-Sassoulas avatar Aug 08 '22 05:08 Pierre-Sassoulas

@Pierre-Sassoulas Awesome, thanks!

Trombach avatar Aug 08 '22 21:08 Trombach

This is extensively tested in astroid and we're nearing a release. I'm going to close this issue as I don't think we'll ever regress on this by changes in pylint itself as this is a pure inference issue.

DanielNoord avatar Aug 25 '22 08:08 DanielNoord