|
7 | 7 | from typing import Type
|
8 | 8 |
|
9 | 9 |
|
10 |
| -class ModuleDiscovery: |
11 |
| - def get_all_classes(self, package: str = None) -> List[Tuple[str, Type]]: |
12 |
| - classes = [] |
13 |
| - classes_set = set() |
14 |
| - for module_name, module in dict(sys.modules).items(): |
15 |
| - if module_name.endswith('six.moves'): # pragma: no cover |
16 |
| - continue |
| 10 | +def get_all_classes(package: str = None) -> List[Tuple[str, Type]]: |
| 11 | + classes = [] |
| 12 | + classes_set = set() |
| 13 | + for module_name, module in dict(sys.modules).items(): |
| 14 | + try: |
17 | 15 | for class_name, class_ in inspect.getmembers(module, inspect.isclass):
|
18 | 16 | if class_ in classes_set:
|
19 | 17 | continue
|
20 | 18 | if package and not (isinstance(class_.__module__, str) and class_.__module__.startswith(package)):
|
21 | 19 | continue
|
22 | 20 | classes.append((class_name, class_))
|
23 | 21 | classes_set.add(class_)
|
24 |
| - return classes |
| 22 | + except ImportError: |
| 23 | + pass |
| 24 | + return classes |
25 | 25 |
|
26 |
| - def import_recursively(self, package_name: str): |
27 |
| - package = importlib.import_module(package_name) |
28 |
| - for module in pkgutil.iter_modules(package.__path__): |
29 |
| - child_name = package_name + '.' + module.name |
30 |
| - if module.ispkg: |
31 |
| - self.import_recursively(child_name) |
32 |
| - else: |
33 |
| - importlib.import_module(child_name) |
| 26 | + |
| 27 | +def get_all_subclasses(supertype: Type) -> List[Tuple[str, Type]]: |
| 28 | + classes = [] |
| 29 | + for class_name, class_ in get_all_classes(): |
| 30 | + try: |
| 31 | + # Workaround to not fail in the issubclass check |
| 32 | + from _weakref import ReferenceType |
| 33 | + |
| 34 | + ReferenceType(class_) |
| 35 | + except TypeError: |
| 36 | + continue |
| 37 | + if class_ is not supertype and issubclass(class_, supertype): |
| 38 | + classes.append((class_name, class_)) |
| 39 | + return classes |
| 40 | + |
| 41 | + |
| 42 | +def import_recursively(package_name: str): |
| 43 | + package = importlib.import_module(package_name) |
| 44 | + for module in pkgutil.iter_modules(package.__path__): |
| 45 | + child_name = package_name + '.' + module.name |
| 46 | + if module.ispkg: |
| 47 | + import_recursively(child_name) |
| 48 | + else: |
| 49 | + importlib.import_module(child_name) |
0 commit comments