pylint icon indicating copy to clipboard operation
pylint copied to clipboard

False positive ``no-member`` for ``TypedDict.__annotations__``

Open Pierre-Sassoulas opened this issue 3 years ago • 7 comments

Bug description

from typing import TypedDict


class Example(TypedDict):
    string: str
    integer: int
    boolean: bool


print(Example.__annotations__)

See https://github.com/PyCQA/pylint/issues/3234#issuecomment-896701002

Configuration

No response

Command used

pylint a.py

Pylint output

a.py:10:6: E1101: Class 'Example' has no '__annotations__' member (no-member)

Expected behavior

No warning

Pylint version

2.15.0-dev0

OS / Environment

No response

Additional dependencies

No response

Pierre-Sassoulas avatar Jul 04 '22 18:07 Pierre-Sassoulas

I often use a construct like this in Python 3.7 and I get that false positive too:

class foobar():
	""" … """
	
	foo: str
	bar: int
	
	__slots__ = tuple(__annotations__)  # __slots__ "on the fly"
	
	def __init__(self, foo, bar):
		self.foo = foo
		self.bar = bar

	
test = foobar('foobar', 12345)
$ pylint --version
pylint 2.15.6
astroid 2.12.13
Python 3.7.6 (v3.7.6:43364a7ae0, Dec 18 2019, 14:18:50) 
[Clang 6.0 (clang-600.0.57)]

$ pylint thebug1.py 
************* Module thebug1
thebug1.py:9:19: E0602: Undefined variable '__annotations__' (undefined-variable)

------------------------------------------------------------------
Your code has been rated at 3.75/10 (previous run: 3.75/10, +0.00)

the-real-tokai avatar Nov 25 '22 17:11 the-real-tokai

The issue with __annotations__ seems to have been fixed in the latest release of Pylint:

pylint 3.0.2
astroid 3.0.1
Python 3.11.6 (main, Oct  2 2023, 13:45:54) [GCC 11.4.0]

However, I don't know it it is the same cause, but I am getting no-member errors on TypedDict fields __required_keys__ and __optional_keys__:

from typing import TypedDict


class Example(TypedDict):
    string: str
    integer: int
    boolean: bool


print(Example.__annotations__)  # {'string': <class 'str'>, 'integer': <class 'int'>, 'boolean': <class 'bool'>}
print(Example.__required_keys__)  # frozenset({'integer', 'string', 'boolean'})
print(Example.__optional_keys__)  # frozenset()
no-member.py:11:6: E1101: Class 'Example' has no '__required_keys__' member (no-member)
no-member.py:12:6: E1101: Class 'Example' has no '__optional_keys__' member (no-member)

jonathanberthias avatar Nov 17 '23 11:11 jonathanberthias

The issue with annotations seems to have been fixed in the latest release of Pylint:

I added the help wanted label because checking that the bug is fixed by adding a functional test case can be done without pylint knowledge (the CI will check from python 3.8 to python 3.12 on win/mac/linux).

However, I don't know it it is the same cause, but I am getting no-member errors on TypedDict fields required_keys and optional_keys:

This require some investigation (And maybe another issue).

Pierre-Sassoulas avatar Nov 19 '23 20:11 Pierre-Sassoulas

For me the issue is also fixed for TypedDicts defined with the class-based syntax.

It is still there when using the Alternative Syntax though. We use these for TypedDicts whose fields are not valid attribute names in Python, e.g. because they are reserved keywords.

robertschweizer avatar Nov 29 '23 17:11 robertschweizer

I have the same issue and from my tests it also only happens when using the alternative syntax

from typing import TypedDict


class MyTypedDict(TypedDict):
    a: int
    b: str


OtherTypedDict = TypedDict('OtherTypedDict', {'a': int, 'b': str})


print(MyTypedDict.__annotations__)  # No Error
print(OtherTypedDict.__annotations__)  # Error

Instance of TypedDict has no __annotations__ member E1101:no-member

Vulcagon avatar Apr 02 '24 00:04 Vulcagon

The issue with __annotations__ seems to have been fixed in the latest release of Pylint:

pylint 3.0.2
astroid 3.0.1
Python 3.11.6 (main, Oct  2 2023, 13:45:54) [GCC 11.4.0]

Is not fixed in pylint 3.0.3:

$ pylint --version
pylint 3.0.3
astroid 3.0.3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]

$ cat tmp/test.py 
class Test:
    a: int
    b: float
    c: str

    __slots__ = tuple(__annotations__)

$ pylint tmp/test.py 
************* Module test
tmp/test.py:6:22: E0602: Undefined variable '__annotations__' (undefined-variable)

------------------------------------------------------------------
Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00)

dnpetrov avatar May 22 '24 09:05 dnpetrov

That’s a slightly different case. The thing that was said to be fixed was not about referencing the attribute in the class body itself.

mbyrnepr2 avatar May 22 '24 09:05 mbyrnepr2