-
Notifications
You must be signed in to change notification settings - Fork 400
/
import_helpers.py
62 lines (44 loc) · 2.32 KB
/
import_helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Copyright 2022 MosaicML Composer authors
# SPDX-License-Identifier: Apache-2.0
"""Dynamically import a Python object (e.g. module, class, function, ...)."""
import importlib
from typing import Any, Optional
__all__ = ['MissingConditionalImportError', 'import_object']
class MissingConditionalImportError(ImportError):
"""Handles errors for external packages that might not be installed.
Args:
extra_deps_group (str): the pip package group, found in setup.py. For example, nlp for `mosaicml[nlp]`.
conda_package (str, optional): The package(s) to install if using conda.
conda_channel (str, optional): The conda channel to install packages from. Set to ``None`` if the
package is not published on conda and must be installed via pip.
"""
def __init__(self, extra_deps_group: str, conda_package: str, conda_channel: Optional[str] = 'conda-forge'):
if conda_channel:
conda_command = f'conda install -c {conda_channel} {conda_package}'
else:
# Install via pip, as these packages are not installed via conda.
conda_command = f'pip install {conda_package}'
super().__init__(
(f'Composer was installed without {extra_deps_group} support. To use {extra_deps_group} related '
f"packages, with Composer, run `pip install 'mosaicml[{extra_deps_group}]'` if using pip or "
f'`{conda_command}` if using Anaconda.'
''))
def import_object(name: str) -> Any:
"""Dynamically import a Python object (e.g. class, function, ...).
.. note::
To dynamically import a module, use :func:`importlib.import_module`.
Args:
name (str): The path to the Python object to import.
Separate the module name and class name with a ``':'`` (e.g. ``'path.to.module:function_name'``).
Example:
>>> from composer.utils import import_object
>>> import_object('functools:partial')
<class 'functools.partial'>
.. note::
The module name must be discoverale with the Python path, as determined by :attr:`sys.path`.
Returns:
Any: The imported object.
"""
module_name, object_name = name.split(':')
module = importlib.import_module(module_name)
return getattr(module, object_name)