python-language-server icon indicating copy to clipboard operation
python-language-server copied to clipboard

concurrent.futures.ThreadPoolExecutor doesn't autocomplete

Open fireattack opened this issue 4 years ago • 6 comments

Environment data

  • Language Server version: 0.5.45.0
  • OS and version: Win7x64
  • Python version (& distribution if applicable, e.g. Anaconda): Python 3.8

Expected behaviour

It shows "ThreadPoolExecutor"

Actual behaviour

image

Logs

https://gist.github.com/fireattack/599faa0f0f02d8e29bfd44bee094d4ba

Code Snippet / Additional lnformation

import concurrent.futures  

concurrent.futures.t

fireattack avatar Apr 01 '20 03:04 fireattack

Same problem goes to ProcessPoolExecutor.

Not very familiar with how it works, but at least they are included in __all__ of lib\concurrent\futures\__init__.py.

fireattack avatar Apr 01 '20 03:04 fireattack

Seems like a bug, given ThreadPoolExecutor and ProcessPoolExecutor are present in the stubs.

jakebailey avatar Apr 01 '20 03:04 jakebailey

3.6 and 3.8 yield me

image

MikhailArkhipov avatar Apr 17 '20 19:04 MikhailArkhipov

@MikhailArkhipov

thanks for testing. However, I can still reproduce this bug with newest insider.

image image

Python 3.8.1 64-bit

fireattack avatar Apr 17 '20 21:04 fireattack

Can also reproduce the bug on

  • A different relatively clean Win 10 computer
  • With freshly installed Python 3.8.2 64-bit.

image

fireattack avatar Apr 17 '20 22:04 fireattack

Module code is based on dynamic assignment. Since LS does not run the code, it does not know about ThreadPoolExecutor.

    if name == 'ThreadPoolExecutor':
        from .thread import ThreadPoolExecutor as te
        ThreadPoolExecutor = te
        return te

static analysis could pull the name from __all__ but it would not know its members. The type is present in stubs, but it is in thread.pyi which is used if thread is imported explicitly.

Related: https://github.com/microsoft/python-language-server/issues/1371

__all__ = (
    'FIRST_COMPLETED',
    'FIRST_EXCEPTION',
    'ALL_COMPLETED',
    'CancelledError',
    'TimeoutError',
    'BrokenExecutor',
    'Future',
    'Executor',
    'wait',
    'as_completed',
    'ProcessPoolExecutor',
    'ThreadPoolExecutor',
)


def __dir__():
    return __all__ + ('__author__', '__doc__')


def __getattr__(name):
    global ProcessPoolExecutor, ThreadPoolExecutor

    if name == 'ProcessPoolExecutor':
        from .process import ProcessPoolExecutor as pe
        ProcessPoolExecutor = pe
        return pe

    if name == 'ThreadPoolExecutor':
        from .thread import ThreadPoolExecutor as te
        ThreadPoolExecutor = te
        return te

MikhailArkhipov avatar May 04 '20 01:05 MikhailArkhipov