edq.util.pyimport

 1import importlib
 2import importlib.util
 3import os
 4import typing
 5import uuid
 6
 7import edq.util.dirent
 8
 9_import_cache: typing.Dict[str, typing.Any] = {}
10""" A cache to help avoid importing a module multiple times. """
11
12def import_path(raw_path: str, cache: bool = True, module_name: typing.Union[str, None] = None) -> typing.Any:
13    """
14    Import a module from a file.
15    If cache is false, then the module will not be fetched or stored in this module's cache.
16    """
17
18    path = os.path.abspath(raw_path)
19    cache_key = f"PATH::{path}"
20
21    # Check the cache before importing.
22    if (cache):
23        module = _import_cache.get(cache_key, None)
24        if (module is not None):
25            return module
26
27    if (not edq.util.dirent.exists(path)):
28        raise ValueError(f"Module path does not exist: '{raw_path}'.")
29
30    if (not os.path.isfile(path)):
31        raise ValueError(f"Module path is not a file: '{raw_path}'.")
32
33    if (module_name is None):
34        module_name = str(uuid.uuid4()).replace('-', '')
35
36    spec = importlib.util.spec_from_file_location(module_name, path)
37    if ((spec is None) or (spec.loader is None)):
38        raise ValueError(f"Failed to load module specification for path: '{raw_path}'.")
39
40    module = importlib.util.module_from_spec(spec)
41    spec.loader.exec_module(module)
42
43    # Store the module in the cache.
44    if (cache):
45        _import_cache[cache_key] = module
46
47    return module
48
49def import_name(module_name: str, cache: bool = True) -> typing.Any:
50    """
51    Import a module from a name.
52    The module must already be in the system's path (sys.path).
53    If cache is false, then the module will not be fetched or stored in this module's cache.
54    """
55
56    cache_key = f"NAME::{module_name}"
57
58    # Check the cache before importing.
59    if (cache):
60        module = _import_cache.get(cache_key, None)
61        if (module is not None):
62            return module
63
64    try:
65        module = importlib.import_module(module_name)
66    except ImportError as ex:
67        raise ValueError(f"Unable to locate module '{module_name}'.") from ex
68
69    # Store the module in the cache.
70    if (cache):
71        _import_cache[cache_key] = module
72
73    return module
74
75def fetch(name: str) -> typing.Any:
76    """
77    Fetch an entity inside of a module.
78    Note that the target is not a module, but an attribute/object inside of the module.
79    The provided name should be fully qualified.
80    """
81
82    parts = name.strip().rsplit('.', 1)
83    if (len(parts) != 2):
84        raise ValueError(f"Target name of fetch must be fully qualified, got '{name}'.")
85
86    module_name = parts[0]
87    short_name = parts[1]
88
89    module = import_name(module_name)
90
91    if (not hasattr(module, short_name)):
92        raise ValueError(f"Module '{module_name}' does not have attribute '{short_name}'.")
93
94    return getattr(module, short_name)
def import_path( raw_path: str, cache: bool = True, module_name: Optional[str] = None) -> Any:
13def import_path(raw_path: str, cache: bool = True, module_name: typing.Union[str, None] = None) -> typing.Any:
14    """
15    Import a module from a file.
16    If cache is false, then the module will not be fetched or stored in this module's cache.
17    """
18
19    path = os.path.abspath(raw_path)
20    cache_key = f"PATH::{path}"
21
22    # Check the cache before importing.
23    if (cache):
24        module = _import_cache.get(cache_key, None)
25        if (module is not None):
26            return module
27
28    if (not edq.util.dirent.exists(path)):
29        raise ValueError(f"Module path does not exist: '{raw_path}'.")
30
31    if (not os.path.isfile(path)):
32        raise ValueError(f"Module path is not a file: '{raw_path}'.")
33
34    if (module_name is None):
35        module_name = str(uuid.uuid4()).replace('-', '')
36
37    spec = importlib.util.spec_from_file_location(module_name, path)
38    if ((spec is None) or (spec.loader is None)):
39        raise ValueError(f"Failed to load module specification for path: '{raw_path}'.")
40
41    module = importlib.util.module_from_spec(spec)
42    spec.loader.exec_module(module)
43
44    # Store the module in the cache.
45    if (cache):
46        _import_cache[cache_key] = module
47
48    return module

Import a module from a file. If cache is false, then the module will not be fetched or stored in this module's cache.

def import_name(module_name: str, cache: bool = True) -> Any:
50def import_name(module_name: str, cache: bool = True) -> typing.Any:
51    """
52    Import a module from a name.
53    The module must already be in the system's path (sys.path).
54    If cache is false, then the module will not be fetched or stored in this module's cache.
55    """
56
57    cache_key = f"NAME::{module_name}"
58
59    # Check the cache before importing.
60    if (cache):
61        module = _import_cache.get(cache_key, None)
62        if (module is not None):
63            return module
64
65    try:
66        module = importlib.import_module(module_name)
67    except ImportError as ex:
68        raise ValueError(f"Unable to locate module '{module_name}'.") from ex
69
70    # Store the module in the cache.
71    if (cache):
72        _import_cache[cache_key] = module
73
74    return module

Import a module from a name. The module must already be in the system's path (sys.path). If cache is false, then the module will not be fetched or stored in this module's cache.

def fetch(name: str) -> Any:
76def fetch(name: str) -> typing.Any:
77    """
78    Fetch an entity inside of a module.
79    Note that the target is not a module, but an attribute/object inside of the module.
80    The provided name should be fully qualified.
81    """
82
83    parts = name.strip().rsplit('.', 1)
84    if (len(parts) != 2):
85        raise ValueError(f"Target name of fetch must be fully qualified, got '{name}'.")
86
87    module_name = parts[0]
88    short_name = parts[1]
89
90    module = import_name(module_name)
91
92    if (not hasattr(module, short_name)):
93        raise ValueError(f"Module '{module_name}' does not have attribute '{short_name}'.")
94
95    return getattr(module, short_name)

Fetch an entity inside of a module. Note that the target is not a module, but an attribute/object inside of the module. The provided name should be fully qualified.