Typing an unimported module

Viewed 42

I have a Python package that has an optional [extras] dependency, yet I want to adhere to typing on all methods.

The situation is that in my file, I have this

class MyClass:

    def __init__(self, datastore: Datastore):  # <- Datastore is azureml.core.Datastore
        ...

    def my_func(self):
        from azureml.core import Datastore
        ...

I import from within the function because there are other classes in the same file that should be imported when not using the extras (extras being azureml).

So this obviously fails, because I refer to Datastore before importing it. Removing the Datastore typing from the __init__ method obviously solves the problem.

So in general my question is whether it is possible, and if so how, to use typing when typing an optional (extras) package.

Notice, that importing in the class definition (below the class MyClass statement) is not a valid solution, as this code is called when the module is imported

1 Answers

You can use TYPE_CHECKING:

A special constant that is assumed to be True by 3rd party static type checkers. It is False at runtime.

It is False at runtime: So it doesn't affect your module's behavior.

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from azureml.core import Datastore


class MyClass:
    def __init__(self, datastore: Datastore):
        ...

    def my_func(self):
        from azureml.core import Datastore
        ...

Since I want to show this in action, I will use operator.itemgetter as an instance because it's recognizable for type checkers, but azureml.core is not:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from operator import itemgetter


class MyClass:
    def __init__(self, datastore: itemgetter):
        ...

    def my_func(self):
        from operator import itemgetter
        ...


obj1 = MyClass(itemgetter(1))  # line 16
obj2 = MyClass(10)             # line 17

Here is the Mypy error:

main.py:17: error: Argument 1 to "MyClass" has incompatible type "int"; expected "itemgetter[Any]"
Found 1 error in 1 file (checked 1 source file)

Which shows it works as excepted.

Related