Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importing classes just for typing in python?

I am trying to use typing in Python 3.8 and I am a bit stuck. Example: I am mainly developing in main.py. I also have a class util.py that contains some helper functions an classes. But these classes also need to import classes from main.py for Typing. Now, when I want to use functions from util.py in main.py I also need to import it - but then I'll get an error because of circular importing (and rightly so).

Is there a way around this?

like image 269
Stefan Wobbe Avatar asked Jul 16 '26 01:07

Stefan Wobbe


2 Answers

Sylvio's answer is correct, but I want to address just for typing in your title.

Importing classes just for typing in python?

If the only reason you are importing a class is to address some typing consideration, you can use the typing.TYPE_CHECKING constant to make that import conditional.

Quoting that documentation:

Runtime or type checking?

Sometimes there's code that must be seen by a type checker (or other static analysis tools) but should not be executed. For such situations the typing module defines a constant, TYPE_CHECKING, that is considered True during type checking (or other static analysis) but False at runtime. Example:

import typing

if typing.TYPE_CHECKING:
    import expensive_mod

def a_func(arg: 'expensive_mod.SomeClass') -> None:
    a_var = arg  # type: expensive_mod.SomeClass
    ...

(Note that the type annotation must be enclosed in quotes, making it a "forward reference", to hide the expensive_mod reference from the interpreter runtime. In the # type comment no quotes are needed.)

Bottom line is that you may very well not have to import it all, except for when you are type-checking.

like image 130
JL Peyret Avatar answered Jul 18 '26 16:07

JL Peyret


Circular imports are not an immediate error in Python; they're only an error if you use them in a particular way. I believe you're looking for forward references

Example main.py:

import util

class SomeClass:
    pass

Example util.py

import main

# We can't use main.SomeClass in the type signature because of the cycle,
# but we can forward reference it, which the type system understands.
def make_some_class() -> "main.SomeClass":
    return main.SomeClass()
like image 42
Silvio Mayolo Avatar answered Jul 18 '26 16:07

Silvio Mayolo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!