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?
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.
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?
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.