typing: dealing with import cycles (beginner - intermediate) anthony explains #214

preview_player
Показать описание
today I talk about an all-too-common problem when typing code: circular imports! fortunately there's an easy straightforward solution

==========

I won't ask for subscriptions / likes / comments in videos but it really helps the channel. If you have any suggestions or things you'd like to see please comment below!
Рекомендации по теме
Комментарии
Автор

Can we just take a minute to admire the fact this guy is like 29 and basically knows everything and contributes to Python

UriYakir
Автор

Thank you Anthony! You've saved me with this one again!

spidermila
Автор

the code for mypy figuring out import cycles is wack, almost gave me a headache. Also made me appreciate all those graph algorithms in my coursebook a lot more.

sadhlife
Автор

Is there a way to get this to work with Generics in classes? I have a `class ...` in a.py where TPkgUID is a TypeVar from b.py because it is bound in a way that is an implementation detail of b. It looks like `Generic['TPkgUID']` is not allowed so the annotations trick doesn't work, even though this is only for type checking

realvatican
Автор

Dude thank you for your contribution to Python.

icresoftgames
Автор

I Have a doubt not related to this video, I see you use the import statements as writing the imports for each class or function in different line in order to prevent git conflicts while merge, but what if instead of writing each imports on a separate line we write the imports like this
from import (
BucketDoesNotExistsError,
BucketExistError,
DropletDoesNotExists,
)
Its technically in different lines right ??🤔🤔🤔
Will writing like this cause any git conflicts ??

adwaithrajesh
Автор

not working for me : it looks like doesn't do the imports anymore, it doesn't recognize the functions I'm calling (and I did the __future__ part). I have 3 files and each one import the 2 others, because each one need to use at least one function from the 2 others. As if your a.py and b.py files needed a function f in t.py (f also used in t itself). Maybe it can't work in this case ?

Edit : for those who would have the same problem as me : I moved the f function in a new file I named antiCircular.py, and I imported antiCircular in t.py, a.py and b.py. I then even managed to remove TYPE_CHECKING and __future__ without any problem. Which I don't understand : I still have the same kind of import as in the vid

machintruc
Автор

I'm afraid your solution is very particular and fails in almost all practical aplications. I shited the main part of my code (which I presented below) to a separate file and it indeed worked. But when I add inheritance to one of my classes (after the another) it stops working. I get "NameError: name '...' is not defined". I've got
if TYPE_CHECKING:
from... import...

in both my modules (why do you have it only in one module?) and it doesn't work. Is there anything I can do about it?

plrc
Автор

It doesn't work for me. Addmittedly the "circular" error doesn't appear, but another error shows up.

I created two modules. Additional called Class2 which contains only:
from Class1 import Class1

class Class2:
def __init__(this):
this.field = 20

and the main, which cointains:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from Class2 import Class2

class Class1:
def __init__(this):
this.field = 10

def method(this, object: "Class2"):
pass


def main():
print("It's my main procedure.")
object1 = Class2()
print("I've created an object of the Class2")


if __name__ == "__main__":
main()

and when I run it I get "NameError: name 'Class2' is not defined". When I replace
if TYPE_CHECKING
for
if False
python doesn't recognize Class2 at all. Jesus Christ what a silly language.

plrc