xdoctest.utils.util_import module¶
This file was autogenerated based on code in ubelt via dev/port_ubelt_utils.py in the xdoctest repo
- xdoctest.utils.util_import.is_modname_importable(modname, sys_path=None, exclude=None)[source]¶
Determines if a modname is importable based on your current sys.path
- Parameters:
modname (str) – name of module to check
sys_path (list | None, default=None) – if specified overrides
sys.path
exclude (list | None) – list of directory paths. if specified prevents these directories from being searched.
- Returns:
True if the module can be imported
- Return type:
Example
>>> is_modname_importable('xdoctest') True >>> is_modname_importable('not_a_real_module') False >>> is_modname_importable('xdoctest', sys_path=[]) False
- class xdoctest.utils.util_import.PythonPathContext(dpath, index=0)[source]¶
Bases:
object
Context for temporarily adding a dir to the PYTHONPATH.
Used in testing, and used as a helper in certain ubelt functions.
Warning
Even though this context manager takes precautions, this modifies
sys.path
, and things can go wrong when that happens. This is generally safe as long as nothing else you do inside of this context modifies the path. If the path is modified in this context, we will try to detect it and warn.- Variables:
Example
>>> import sys >>> with PythonPathContext('foo', -1): >>> assert sys.path[-1] == 'foo' >>> assert sys.path[-1] != 'foo' >>> with PythonPathContext('bar', 0): >>> assert sys.path[0] == 'bar' >>> assert sys.path[0] != 'bar'
Example
>>> # xdoctest: +REQUIRES(module:pytest) >>> # Mangle the path inside the context >>> import sys >>> self = PythonPathContext('foo', 0) >>> self.__enter__() >>> sys.path.insert(0, 'mangled') >>> import pytest >>> with pytest.warns(UserWarning): >>> self.__exit__(None, None, None)
Example
>>> # xdoctest: +REQUIRES(module:pytest) >>> import sys >>> self = PythonPathContext('foo', 0) >>> self.__enter__() >>> sys.path.remove('foo') >>> import pytest >>> with pytest.raises(RuntimeError): >>> self.__exit__(None, None, None)
- Parameters:
dpath (str | PathLike) – directory to insert into the PYTHONPATH
index (int) – position to add to. Typically either -1 or 0.
- xdoctest.utils.util_import.import_module_from_path(modpath, index=-1)[source]¶
Imports a module via a filesystem path.
This works by modifying
sys.path
, importing the module name, and then attempting to undo the change to sys.path. This function may produce unexpected results in the case where the imported module itself itself modifiessys.path
or if there is another conflicting module with the same name.- Parameters:
modpath (str | PathLike) – Path to the module on disk or within a zipfile. Paths within a zipfile can be given by
<path-to>.zip/<path-inside-zip>.py
.index (int) – Location at which we modify PYTHONPATH if necessary. If your module name does not conflict, the safest value is -1, However, if there is a conflict, then use an index of 0. The default may change to 0 in the future.
- Returns:
the imported module
- Return type:
ModuleType
References
- Raises:
IOError - when the path to the module does not exist –
ImportError - when the module is unable to be imported –
Note
If the module is part of a package, the package will be imported first. These modules may cause problems when reloading via IPython magic
This can import a module from within a zipfile. To do this modpath should specify the path to the zipfile and the path to the module within that zipfile separated by a colon or pathsep. E.g. “/path/to/archive.zip:mymodule.pl”
Warning
It is best to use this with paths that will not conflict with previously existing modules.
If the modpath conflicts with a previously existing module name. And the target module does imports of its own relative to this conflicting path. In this case, the module that was loaded first will win.
For example if you try to import ‘/foo/bar/pkg/mod.py’ from the folder structure:
- foo/ +- bar/ +- pkg/ + __init__.py |- mod.py |- helper.py
If there exists another module named
pkg
already insys.modules
and mod.py contains the codefrom . import helper
, Python will assume helper belongs to thepkg
module already insys.modules
. This can cause a NameError or worse — an incorrect helper module.- SeeAlso:
Example
>>> # xdoctest: +SKIP("ubelt dependency") >>> import xdoctest >>> modpath = xdoctest.__file__ >>> module = ub.import_module_from_path(modpath) >>> assert module is xdoctest
Example
>>> # Test importing a module from within a zipfile >>> # xdoctest: +SKIP("ubelt dependency") >>> import zipfile >>> from xdoctest import utils >>> import os >>> from os.path import join, expanduser, normpath >>> dpath = expanduser('~/.cache/xdoctest') >>> dpath = utils.ensuredir(dpath) >>> #dpath = utils.TempDir().ensure() >>> # Write to an external module named bar >>> external_modpath = join(dpath, 'bar.py') >>> # For pypy support we have to write this using with >>> with open(external_modpath, 'w') as file: >>> file.write('testvar = 1') >>> internal = 'folder/bar.py' >>> # Move the external bar module into a zipfile >>> zippath = join(dpath, 'myzip.zip') >>> with zipfile.ZipFile(zippath, 'w') as myzip: >>> myzip.write(external_modpath, internal) >>> # Import the bar module from within the zipfile >>> modpath = zippath + ':' + internal >>> modpath = zippath + os.path.sep + internal >>> module = ub.import_module_from_path(modpath) >>> assert normpath(module.__name__) == normpath('folder/bar') >>> assert module.testvar == 1
Example
>>> import pytest >>> # xdoctest: +SKIP("ubelt dependency") >>> with pytest.raises(IOError): >>> ub.import_module_from_path('does-not-exist') >>> with pytest.raises(IOError): >>> ub.import_module_from_path('does-not-exist.zip/')
- xdoctest.utils.util_import.import_module_from_name(modname)[source]¶
Imports a module from its string name (i.e.
__name__
)This is a simple wrapper around
importlib.import_module()
, but is provided as a companion function toimport_module_from_path()
, which contains functionality not provided in the Python standard library.- Parameters:
modname (str) – module name
- Returns:
module
- Return type:
ModuleType
- SeeAlso:
Example
>>> # test with modules that won't be imported in normal circumstances >>> # todo write a test where we guarantee this >>> # xdoctest: +SKIP("ubelt dependency") >>> import sys >>> modname_list = [ >>> 'pickletools', >>> 'lib2to3.fixes.fix_apply', >>> ] >>> #assert not any(m in sys.modules for m in modname_list) >>> modules = [ub.import_module_from_name(modname) for modname in modname_list] >>> assert [m.__name__ for m in modules] == modname_list >>> assert all(m in sys.modules for m in modname_list)
- xdoctest.utils.util_import.modname_to_modpath(modname, hide_init=True, hide_main=False, sys_path=None)[source]¶
Finds the path to a python module from its name.
Determines the path to a python module without directly import it
Converts the name of a module (__name__) to the path (__file__) where it is located without importing the module. Returns None if the module does not exist.
- Parameters:
modname (str) – The name of a module in
sys_path
.hide_init (bool) – if False, __init__.py will be returned for packages. Defaults to True.
hide_main (bool) – if False, and
hide_init
is True, __main__.py will be returned for packages, if it exists. Defaults to False.sys_path (None | List[str | PathLike]) – The paths to search for the module. If unspecified, defaults to
sys.path
.
- Returns:
modpath - path to the module, or None if it doesn’t exist
- Return type:
str | None
Example
>>> modname = 'xdoctest.__main__' >>> modpath = modname_to_modpath(modname, hide_main=False) >>> assert modpath.endswith('__main__.py') >>> modname = 'xdoctest' >>> modpath = modname_to_modpath(modname, hide_init=False) >>> assert modpath.endswith('__init__.py') >>> # xdoctest: +REQUIRES(CPython) >>> modpath = basename(modname_to_modpath('_ctypes')) >>> assert 'ctypes' in modpath
- xdoctest.utils.util_import.normalize_modpath(modpath, hide_init=True, hide_main=False)[source]¶
Normalizes __init__ and __main__ paths.
- Parameters:
modpath (str | PathLike) – path to a module
hide_init (bool) – if True, always return package modules as __init__.py files otherwise always return the dpath. Defaults to True.
hide_main (bool) – if True, always strip away main files otherwise ignore __main__.py. Defaults to False.
- Returns:
a normalized path to the module
- Return type:
str | PathLike
Note
Adds __init__ if reasonable, but only removes __main__ by default
Example
>>> from xdoctest import static_analysis as module >>> modpath = module.__file__ >>> assert normalize_modpath(modpath) == modpath.replace('.pyc', '.py') >>> dpath = dirname(modpath) >>> res0 = normalize_modpath(dpath, hide_init=0, hide_main=0) >>> res1 = normalize_modpath(dpath, hide_init=0, hide_main=1) >>> res2 = normalize_modpath(dpath, hide_init=1, hide_main=0) >>> res3 = normalize_modpath(dpath, hide_init=1, hide_main=1) >>> assert res0.endswith('__init__.py') >>> assert res1.endswith('__init__.py') >>> assert not res2.endswith('.py') >>> assert not res3.endswith('.py')
- xdoctest.utils.util_import.modpath_to_modname(modpath, hide_init=True, hide_main=False, check=True, relativeto=None)[source]¶
Determines importable name from file path
Converts the path to a module (__file__) to the importable python name (__name__) without importing the module.
The filename is converted to a module name, and parent directories are recursively included until a directory without an __init__.py file is encountered.
- Parameters:
modpath (str) – Module filepath
hide_init (bool) – Removes the __init__ suffix. Defaults to True.
hide_main (bool) – Removes the __main__ suffix. Defaults to False.
check (bool) – If False, does not raise an error if modpath is a dir and does not contain an __init__ file. Defaults to True.
relativeto (str | None) – If specified, all checks are ignored and this is considered the path to the root module. Defaults to None.
Todo
- [ ] Does this need modification to support PEP 420?
- Returns:
modname
- Return type:
- Raises:
ValueError – if check is True and the path does not exist
Example
>>> from xdoctest import static_analysis >>> modpath = static_analysis.__file__.replace('.pyc', '.py') >>> modpath = modpath.replace('.pyc', '.py') >>> modname = modpath_to_modname(modpath) >>> assert modname == 'xdoctest.static_analysis'
Example
>>> import xdoctest >>> assert modpath_to_modname(xdoctest.__file__.replace('.pyc', '.py')) == 'xdoctest' >>> assert modpath_to_modname(dirname(xdoctest.__file__.replace('.pyc', '.py'))) == 'xdoctest'
Example
>>> # xdoctest: +REQUIRES(CPython) >>> modpath = modname_to_modpath('_ctypes') >>> modname = modpath_to_modname(modpath) >>> assert modname == '_ctypes'
Example
>>> modpath = '/foo/libfoobar.linux-x86_64-3.6.so' >>> modname = modpath_to_modname(modpath, check=False) >>> assert modname == 'libfoobar'
- xdoctest.utils.util_import.split_modpath(modpath, check=True)[source]¶
Splits the modpath into the dir that must be in PYTHONPATH for the module to be imported and the modulepath relative to this directory.
- Parameters:
modpath (str) – module filepath
check (bool) – if False, does not raise an error if modpath is a directory and does not contain an
__init__.py
file.
- Returns:
(directory, rel_modpath)
- Return type:
- Raises:
ValueError – if modpath does not exist or is not a package
Example
>>> from xdoctest import static_analysis >>> modpath = static_analysis.__file__.replace('.pyc', '.py') >>> modpath = abspath(modpath) >>> dpath, rel_modpath = split_modpath(modpath) >>> recon = join(dpath, rel_modpath) >>> assert recon == modpath >>> assert rel_modpath == join('xdoctest', 'static_analysis.py')