Home > Mobile >  Python type hinting for sake of VSCODE autocomplete causes circular imports,
Python type hinting for sake of VSCODE autocomplete causes circular imports,

Time:01-09

I need type hints for the sake of autocomplete in VSCODE. I have following:

# a.py

class A:
    def __init__(self):
        self.B = B(self)
# b.py

from a import A
# I NEED TO IMPORT A HERE SO I CAN REFER TO A IN TYPE HINT

class B:
    def __init__(self, a: A):
        self.A = a

This causes circular import. I have read, that it is allowed to type hint in between single quotation marks, but this removes the purpose for why I need it. It is VSCODE autocomplete. Once A is in quotation marks, VSCODE does not know what it is. I have read about stub files, but these wont work for me, because I would have to edit these files every time I change A class and I plan to have it a large class.

CodePudding user response:

I think TYPE_CHECKING will solve the problem of your circular import.

Try import as in the following code.

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from a import A

The following article may also be helpful for your understanding.
Python type hinting without cyclic imports

CodePudding user response:

If you have the following files.

a.py

from b import B

class A:
    def __init__(self) -> None:
        self.b = B(self)

b.py

import typing

if typing.TYPE_CHECKING:
    from a import A
    
class B:
    def __init__(self, a: "A"):
        self.a = a
        
# actual usage
def foo() -> None:
    B(1)

mypy will return b.py:11: error: Argument 1 to "B" has incompatible type "int"; expected "A" [arg-type]

Depending on the linter you use, you may also get this information in your IDE. For me I get a listing error

Argument of type "Literal[1]" cannot be assigned to parameter "a" of type "A" in function "__init__" "Literal[1]" is incompatible with "A"Pylance
  • Related