How do you import a nested package via string?

Question:

I’m trying to dynamically import a package which is a subdirectory of another package.

Though there is no documentation about it, this doesn’t seem to be possible with importlib.

Example:
Start with

pip install pytest

then,

import importlib
mod = importlib.import_module("pytester", package="_pytest")

fails with ModuleNotFoundError: No module named 'pytester', while

from _pytest import pytester

succeeds.

import importlib
mod = importlib.__import__("_pytest.pytester")

also succeed, but returns the _pytest module, not the pytester module, and I don’t seem to have a way of accessing mod.pytester by string.

Am I doing something wrong? Is there another way to achieve this?

Asked By: cowlinator

||

Answers:

The ‘package’ argument of import_module is used for relative imports.

Instead, the equivalent of from _pytest import pytester would be:

pytester = importlib.import_module("_pytest.pytester")

Note that this module is not a public API of pytest, as indicated by the leading underscore. It’s pytest’s own business to import the pytester submodule, users shouldn’t need to do this – the public API is using the pytester fixture which does not require you to import anything.

Answered By: wim