Autocomplete stopped working on local class members
Environment data
- Language Server version: v2023.7.40
- OS: Windows 11
- Python version: 3.11
Code Snippet
from aiohttp import ClientSession
class MyClass:
a = 0
b: int
def __init__(self) -> None:
self.c = 0
async def d():
pass
async def func():
async with MyClass() as mc:
mc.a = 1
Repro Steps
- Type
mc.followed by Ctrl+Space. There is no autocomplete suggestion (themcclass instance is found, but none of the local class members are accessible via autocomplete). - Change
async with MyClass() as mc:toasync with ClientSession() as mc:and try again. Autocomplete is working now. - Uninstall or disable the Pylance extension and reload VS Code. Now autocomplete works for the local class as expected but this time none of the
ClientSessionclass members appears in the suggested list.
Expected behavior
Autocomplete works for local class instances.
Actual behavior
Below is what is happening when the Pylance is installed:
And without Pylance:
- Everything was working well, and these issues appeared for no reason by yesterday.
- I'm running my code on a remote server, but I have the same issue on the local project as well.
- These issues exist in both Python files and Jupyter notebooks.
- Adding
"python.languageServer": "Default"or"python.languageServer": "Pylance"to thesettings.jsondidn't help. - Updating VS Code and all the extensions including Pylance (both the latest stable and preview releases) didn't help as well.
Your class MyClass doesn't support the async context manager protocol, so it's invalid to use here. If you attempt to run your code, it will crash at runtime. To make this work, you would need to implement an __aenter__ and __aexit__ method in MyClass. The __aenter__ should return the context manager type, which provides the type to the variable mc in the statement async with MyClass() as mc.
If you enable type checking (set python.analysis.typeCheckingMode to "basic") in pylance, it will tell you about errors like this.
@erictraut thanks for the reply. I already know about that. This is a sample code to demonstrate the issue in auto-completing. In my real project, this happened when I was trying to access members of my own class that were inherited from aiohttp.ClientSession. Adding __aenter__ to the class as follows doesn't help at all:
async def __aenter__(self) -> "MyClass":
return self
Have you tried adding both an __aenter__ and __aexit__? Both are required. If I add both of them, completion suggestions appear as expected. If I omit either of these methods, the code crashes at runtime if I call func.
from types import TracebackType
class MyClass:
a = 0
b: int
def __init__(self) -> None:
self.c = 0
async def d(self):
pass
async def __aenter__(self) -> "MyClass":
return self
async def __aexit__(
self,
exc_type: type[BaseException] | None,
exc: BaseException | None,
tb: TracebackType | None,
) -> None:
pass
async def func():
async with MyClass() as mc:
mc.a = 1
I tried different scenarios and got some weird results.
- Adding
__aexit__as well asfrom types import TracebackTypeto my existing sample code doesn't help but replacing it by your entire code works. - I created a new file and implement the same code again. Autocomplete didn't work until I added
__aenter__. No need to add__aexit__
Also, inside the class, suggestions do not appear for default methods except for __init__() and __init_subclass__ until I type five characters. When I press CTRL+Space, no suggestions are displayed, not even for the __init__ method. Therefore, I have to delete the typed word and manually retype it without utilizing the hotkey.
Do you see the red squiggle under MyClass() in your screen recording? Pylance is telling you that you have a bug in your code. You need to fix that bug if you want your code to run without crashing. You also need to fix that error for type completions to work for mc. The type of the variable mc depends on the behavior of your __aenter__ and __aexit__ methods. If you don't define those methods, pylance cannot offer completion suggestions here. When a language server like pylance returns zero completion suggestions, VS Code offers some of its own suggestions based on other identifiers that it sees in the same file. That's what you're observing in this case.
Inside the class, you will get completions for methods that you are overriding from a base class. In your case, the only base class for MyClass is object, and the object class doesn't provide a __aenter__ or __aexit__ method, so you won't see any completion suggestions for these methods. The object class does define an __init__ and __init_class__ method, so pylance offers these as override suggestions.
Since MyClass is intended to be an async context manager, it should probably derive from the abstract base class typing.AsyncContextManager. If you do this, you'll then see override completion suggestions for __aenter__ and __aexit__.
Pylance appears to be working as designed. I don't see any bugs based on the behaviors you're observing. If there's a different behavior that you'd like to see, please consider filing an enhancement request.
Great explanation, thanks.
But unlike your code editor, I don't have any suggestions after typing two underscores. Only after typing the fifth character, the only two available items appear:
This is also true for __aenter__:
But there is no suggestion for __aexit__, __call__ and other predefined keywords:
On the other hand, if I inherit my class from aiohttp.ClientSession which is what I'm going to do in my real project, even the __init__ definition doesn't suggest by Pylance:
Also, even though __aenter__ and __aexit__ are defined in aiohttp.ClientSession, no suggestion is provided for those methods too. However, after I defined all those methods manually, autocomplete works as expected:
But unlike your code editor, I don't have any suggestions after typing two underscores.
@BabakAmini, I'm unable to reproduce the completion suggestion behavior that you mentioned in your last comment. Here's what I see after typing a single underscore using Pylance 2024.2.105:
If you're still seeing problems here, please open a new issue.