blob: 58202d1ae845418d0605773b583fa31f552c845c (
plain)
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
|
# standard imports
import importlib
import typing
# inner-module imports
from . import errors
# exports
__all__: typing.Sequence[str] = (
'safe_load',
'unpack_qualified_name',
)
## code ##
def safe_load(module_name: str, class_name: str):
"""Get a class from a module. Raise BuilderError if anything goes wrong."""
try:
# load the module
module = importlib.import_module(module_name)
except Exception as err:
# cannot import module
raise errors.LoaderError(f'cannot load module {module_name} ({err})') from err
try:
# get the class from the module
cls = getattr(module, class_name)
except Exception as err:
# cannot find the class
raise errors.LoaderError(f'cannot load class {class_name} from module {module_name} ({err})') from err
return cls
def unpack_qualified_name(name):
"""Split a name into its module and class component (dot-separated)."""
if not isinstance(name, str):
raise TypeError(name)
if '.' not in name:
raise ValueError('name must be a qualified class name.')
module_name, class_name = name[:name.rfind('.')], name[name.rfind('.')+1:]
if module_name == '':
raise ValueError('name must be a qualified class name.')
return module_name, class_name
## EOF ##
|