pythonic way to do checks before imports

Viewed 122

I have to develop python code for an inhouse framework which can either run in the system's standard python environment or sometimes requires a custom environment to be active. For example, to be able to load certain modules. Because an ImportError might not be too obvious for any user, I would like to give the user a proper error message, explaining the issue.

Some sample code might look like this:

# standard imports...
import sys

import numpy as np

# import which requires special environment
import myspecialmodule

# [...]

One method would be to check for ImportErrors like this:

# standard imports...
import sys

import numpy as np

# import which requires special environment
try:
    import myspecialmodule
except ImportError:
    print('not in the env', file=sys.stderr)
    sys.exit(1)

# [...]

However, that is quite tedious to do, especially if there are many such scripts or if there are many imports. The question is then, which import has failed, if you do not want to repeat the try/except several times.

Now, I wrote a function guard() which checks for the existence of the environment in another way:

import sys
import os


def guard():
    # assume the environment sets this special variable
    if 'MYSPECIALENV' in os.environ:
        # do more checks if the environment is correctly loaded
        # if it is, simply:
        return

    print("The environment is not loaded correctly. "
          "Run this script only in the special environment", file=sys.stderr)
    sys.exit(1)

I altered the imports on the script:

# standard imports...
import sys

import numpy as np

# import which requires special environment
guard()
import myspecialmodule

# [...]

The advantage over the try/except method is, that an ImportError is still raised even if the environment is loaded.

But the issue is, that code linters like isort do not like function calls before imports. Now, one could add configuration to isort to skip this section...

Furthermore, for a reader of the code, it might not be too obvious what is going on. Of course, I could add some comments explaining it...

Another method I thought of is to write a module which does the job of guard, i.e.:

# file: guard/__init__.py
import sys
import os

if 'MYSPECIALENV' not in os.environ:
    print("The environment is not loaded correctly. "
          "Run this script only in the special environment", file=sys.stderr)
    sys.exit(1)
# standard imports...
import sys

import numpy as np

# import which requires special environment
import guard
import myspecialmodule

# [...]

but this might be even less obvious, especially as imports might be sorted in a different way (again thinking about isort).

Is there a better, more pythonic way to do such things before importing a module? Especially one that is obvious for a future developer as well.

0 Answers
Related