pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.33k stars 1.14k forks source link

Typing: Value 'Queue' is unsubscriptablepylint(unsubscriptable-object) #3488

Open NoahCardoza opened 4 years ago

NoahCardoza commented 4 years ago

Steps to reproduce/Current behavior

image

Expected behavior

Would expect no warning since this code runs fine in the interpreter.

pylint --version output

pylint 2.4.4
astroid 2.3.3
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24) 
[Clang 6.0 (clang-600.0.57)]
PCManticore commented 4 years ago

Thanks for the report. pylint is correct here though as Queue is not actually subscriptable. You don't get an error when running the code because you probably enabled annotations support with from __future__ import annotations.

In future versions of Python this kind of subscription might be permitted for any object in annotations, but for now pylint is not aware of those future changes and still emits an error when an annotation is not valid at runtime.

svenpanne commented 2 years ago

I think this issue should be re-opened, Queue is subscriptable since Python 3.9 if I see this correctly. We have to disable the whole unsubscriptable-object because of this (and other pylint/astroid shortcomings), which is a pity.

Pierre-Sassoulas commented 2 years ago

You're right, could you open a new issue with a code example @svenpanne ?

svenpanne commented 2 years ago

Hmmm, now I'm totally confused. It seems that pylint is correct in this respect, at least at the current state of Python's standard libs. What works (with pylint, mypy and actually running the code):

import queue
queue.Queue[int]().put(1)
queue.LifoQueue[int]().put(1)
queue.PriorityQueue[int]().put(1)
queue.SimpleQueue[int]().put(1)

But things get confusing with multiprocessing:

import multiprocessing
multiprocessing.Queue[int]().put(1)
multiprocessing.JoinableQueue[int]().put(1)
multiprocessing.SimpleQueue[int]().put(1)

mypy is happy with these, but both pylint and cpython itself are not: Those queues are not (yet) subscriptable by a type. What's even more confusing: Since Python 3.9, multiprocessing.SimpleQueue has a

    __class_getitem__ = classmethod(types.GenericAlias)

in its class definition, so at least that should work, but it doesn't. The other multiprocessing queues don't even have this line, probably an oversight? What works with mypy and cpython:

from __future__ import annotations
import multiprocessing
mq: multiprocessing.Queue[int] = multiprocessing.Queue()
mjq: multiprocessing.JoinableQueue[int] = multiprocessing.JoinableQueue()
msq: multiprocessing.SimpleQueue[int] = multiprocessing.SimpleQueue()

pylint is unhappy with the subscripts here, can we get a fix for this? The annotations are explicitly lazy, so pylint shouldn't handle them as if they were actually executed.

KholdStare commented 2 months ago

@Pierre-Sassoulas Any updates on this? Just ran into this with multiprocessing.Queue

DanielNoord commented 2 months ago

Nobody has worked on this (yet).

We're open to pull requests, which should probably happen in astroid our ast parser.