forked from pg020196/Neural-Network-Translator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin_collection.py
93 lines (71 loc) · 3.71 KB
/
plugin_collection.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import inspect
import os
import pkgutil
class Plugin(object):
"""Base plugin that every plugin must inherit from"""
def __init__(self, identifier, description):
self.description = description
self.identifier = identifier
class FrontendPlugin(Plugin):
"""Base class that each frontend plugin must inherit from"""
def __init__(self, identifier, description):
super().__init__(identifier, description)
def transform_to_intermediate_format(self, input):
"""Transforms given input into intermediate format and returns output as string"""
raise NotImplementedError
class BackendPlugin(Plugin):
"""Base class that each backend plugin must inherit from"""
def __init__(self, identifier, description, prerequisites):
super().__init__(identifier, description)
self.prerequisites = prerequisites
def translate_to_native_code(self, input):
"""Translates given input in intermediate format to native code"""
raise NotImplementedError
class ConversionPlugin(Plugin):
"""Base class that each conversion plugin must inherit from"""
def __init__(self, identifier, description):
super().__init__(identifier, description)
def process(self, input):
"""Processes the given input and performs a specific conversion, returns processed output"""
raise NotImplementedError
class PluginCollection(object):
"""Manages a list of plugins available in a given directory"""
def __init__(self, plugin_package):
self.plugin_package = plugin_package
self.reload_plugins()
def reload_plugins(self):
"""Loads all available plugins"""
self.plugins = []
self.seen_paths = []
self.search_for_plugins(self.plugin_package)
def get_plugin(self, plugin_identifier):
"""Searches for a plugin with a given identifier in the managed plugin list"""
for plugin in self.plugins:
if (plugin.identifier == plugin_identifier):
return plugin
raise NotImplementedError
def search_for_plugins(self, package):
"""Searches the given directory and all sub directories for available plugins"""
imported_package = __import__(package, fromlist=[''])
#? Recursivly searching for classes inheriting from the specified
for _, pluginname, ispkg in pkgutil.iter_modules(imported_package.__path__, imported_package.__name__ + '.'):
if not ispkg:
plugin_module = __import__(pluginname, fromlist=[''])
clsmembers = inspect.getmembers(plugin_module, inspect.isclass)
for (_, c) in clsmembers:
#? Only add classes that are a sub class of Frontend-, Backend- or ConversionPlugin, but not the class itself
if issubclass(c, Plugin) & (c is not Plugin and c is not FrontendPlugin and c is not BackendPlugin and c is not ConversionPlugin):
self.plugins.append(c())
all_current_paths = []
if isinstance(imported_package.__path__, str):
all_current_paths.append(imported_package.__path__)
else:
all_current_paths.extend([x for x in imported_package.__path__])
for pkg_path in all_current_paths:
if pkg_path not in self.seen_paths:
self.seen_paths.append(pkg_path)
#? Get all subdirectory of the current package path directory
child_pkgs = [p for p in os.listdir(pkg_path) if os.path.isdir(os.path.join(pkg_path, p))]
#? For each subdirectory, apply the searcg_for_plugins method recursively
for child_pkg in child_pkgs:
self.search_for_plugins(package + '.' + child_pkg)