Total Complexity | 5 |
Total Lines | 50 |
Duplicated Lines | 0 % |
Changes | 0 |
1 | """ |
||
2 | PRIVATE MODULE: do not import (from) it directly. |
||
3 | |||
4 | This module contains the ``discover`` function. |
||
5 | """ |
||
6 | import glob |
||
7 | import sys |
||
8 | from importlib import import_module |
||
9 | from pathlib import Path |
||
10 | from typing import List |
||
11 | from jacked._typing import Module |
||
12 | |||
13 | |||
14 | def discover(directory: str = '.') -> List[Module]: |
||
15 | """ |
||
16 | Discover all modules in the given directory recursively and import them. |
||
17 | :param directory: the directory in which modules are to be discovered. |
||
18 | :return: a ``list`` of all discovered modules. |
||
19 | """ |
||
20 | paths = _find_paths(directory, '**/*.py', True) |
||
21 | return _import(paths) |
||
22 | |||
23 | |||
24 | def _find_paths(directory: str, pattern: str, recursive: bool) -> List[Path]: |
||
25 | # Find all paths in the given directory with the given pattern and return |
||
26 | # them in a list. |
||
27 | path = Path(directory) |
||
28 | abspath = str(path.absolute()) |
||
29 | sys.path.insert(0, abspath) |
||
30 | path_to_discover = path.joinpath(pattern) |
||
31 | paths = [Path(filename) for filename in |
||
32 | glob.iglob(str(path_to_discover), recursive=recursive)] |
||
33 | return paths |
||
34 | |||
35 | |||
36 | def _import(paths: List[Path]) -> List[Module]: |
||
37 | # Import the given list of paths and return the Module instances of the |
||
38 | # successfully imported modules. |
||
39 | result = [] |
||
40 | for p in paths: |
||
41 | path_to_module = p.resolve().parent |
||
42 | sys.path.insert(0, str(path_to_module)) |
||
43 | module_name = p.stem |
||
44 | try: |
||
45 | module = import_module(module_name) |
||
46 | result.append(module) |
||
47 | except ImportError: |
||
48 | pass |
||
49 | return result |
||
50 |