__init__.py
1.68 KB
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
import importlib, types, sys, inspect
from .. import ZINCError
class PluginError (ZINCError) :
pass
class Plugin (object) :
modname = "zn"
plugins = []
modules = []
def __init__ (self, *extends, conflicts=[], depends=[]) :
# check conflicts
for p in conflicts :
if p in self.plugins :
raise PluginError("plugin conflicts with %r" % p)
# load dependencies
for p in depends :
try :
return importlib.import_module(p)
except :
try :
return importlib.import_module("zinc.plugins." + p)
except :
raise PluginError("could not load %r from '.' or 'zinc.plugins'" % p)
# create result module
if self.modname not in sys.modules :
self._mod = sys.modules[self.modname] = types.ModuleType(self.modname)
# load extended modules
for base in extends :
if base not in self.modules :
mod = importlib.import_module(base)
self._mod.__dict__.update(mod.__dict__)
self.modules.append(base)
# record loaded plugin
stack = inspect.stack()
caller = inspect.getmodule(stack[1][0])
self.plugins.append(caller.__name__)
def __getattr__ (self, name) :
return getattr(self._mod, name)
def __call__ (self, obj) :
setattr(self._mod, obj.__name__, obj)
return obj
@classmethod
def reset_plugins (cls, name="zn") :
for p in cls.plugins + cls.modules + [cls.modname] :
del sys.modules[p]
cls.modname = name
cls.plugins = []
cls.modules = []