Home > Back-end >  "None" in Python code breaks code suggestions in vscode
"None" in Python code breaks code suggestions in vscode

Time:09-02

I've got a weird issue in vscode. For some reason, code completion of c. stops working after the first None in the Python code, as shown in below screenshot.

After first None, it is like c. contains nothing

This is the complete Card class (complete source code, see link below):

from dataclasses import asdict
from dataclasses import dataclass
from dataclasses import field

@dataclass
class Card:
    summary: str = None
    owner: str = None
    state: str = "todo"
    id: int = field(default=None, compare=False)

    @classmethod
    def from_dict(cls, d):
        return Card(**d)
    def to_dict(self):
        return asdict(self)

It is like if c. contains nothing after that. I just get "No suggestions." when using Ctrl . at c..

If i put None in quotes, like "None", suggestions works for following rows. Until the next None that is.

If I change to False, suggestions works for following rows. It just seems to happen for None!

It is also contained within the function scope too.

Any idea why this is happening?

The code is used in the Pytest book and can be download from enter image description here

If you only remove type annotations for some variables, like below.

class Card:
    summary: str = None
    owner: str = None
    state = "todo"
    id = field(default=None, compare=False)

Then when the variable with the type annotation is assigned none, the following intellisense will be invalid.

enter image description here

summary is None, the following code cannot get suggestions

enter image description here

summary is not None, the following code can get suggestions

enter image description here

summary is not None, but owner is None, the following code cannot get suggestions

CodePudding user response:

If you are going to use type hints, I suggest you configure vscode to do Mypy type checking to avoid these kind of errors.

If you annotate the type as str and then assign it a value of None, and you have Mypy type checking, this will trigger an incompatible type warning.

screenshot vscode incompatible type

Because you have annotated the type as str. Vscode will think that the 2nd assertion is unreachable:

c = Card()
assert c.summary is None # assertion always fails because c.summary is string
assert c.owner is None # this statement is unreachable

The 2nd assertion Screenshot shows that vscode thinks 2nd assertion is never reached because the 1st assertion will always fail because a string type will never be none. Screenshot never reached

To correct use the Optional type hint when assigning None.

from dataclasses import asdict
from dataclasses import dataclass
from dataclasses import field

from typing import Optional, Any, Dict

@dataclass
class Card:
    summary: Optional[str] = None
    owner: Optional[str] = None
    state: str = "todo"
    id: Optional[int] = field(default=None, compare=False)

    @classmethod
    def from_dict(cls, d: Dict[str, Any]) -> "Card":
        return Card(**d)
    def to_dict(self) -> Dict[str, Any]:
        return asdict(self)

As a final point, I think you have absolutely done the right thing. In my view, autocomplete is critically important in avoiding mistakes. If autocomplete isn't working you should stop, figure out why, and do not continue until you get autocomplete working again.

  • Related