-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy path__init__.py
More file actions
73 lines (65 loc) · 2.84 KB
/
__init__.py
File metadata and controls
73 lines (65 loc) · 2.84 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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
##
## © Copyright 2021- IBM Inc. All rights reserved
# SPDX-License-Identifier: MIT
##
from .server import *
from ._app import *
from ._project import *
from ._app import *
from ._project import *
from .oslcqueryapi import *
from ._typesystem import *
from ._ccm import *
from ._rm import *
from ._gcm import *
from ._qm import *
from ._relm import *
from .__meta__ import *
from .httpops import *
from ._customScenarios import *
from .utils import *
__app__ = __meta__.app
__version__ = __meta__.version
__license__ = __meta__.license
__author__ = __meta__.author
import importlib, os, inspect, glob
# scan for extensions to import and extend the specified class
# extensions are .py file with a name like <classname>-something.py e.g RMApp-extension.py
# the classes in the file are added as base classes (i.e. additional mixins) to the extended class
# so it's dynamic mixins :-)
# A mixin may override existing methods but the main aim is to add new methods for that class
def load_extensions( *, path=None, folder=None ):
path = path or os.getcwd()
folder = folder or "extensions"
# find public elmclient names+classes - these are extension points
extendableclasses = {n:c for n,c in inspect.getmembers(importlib.import_module("elmclient"), inspect.isclass) }
# look for extension files
searchdir = os.path.join( path, folder )
# print( f"Loading extensions from {searchdir=}" )
if not os.access( searchdir, os.F_OK ):
# folder doesn't exist - nothing to load
pass
else:
files = glob.glob( os.path.join( searchdir, "**/*.py" ), recursive=True )
for file in files:
filename = os.path.split( file )[1]
# get the extended class
extended = filename.split( "-", 1 )[0]
if extended not in extendableclasses:
print( "No matching class to extend for {filename}" )
else:
extendedclass=extendableclasses[extended]
# Import source file - from https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
loader = importlib.machinery.SourceFileLoader( filename, file )
spec = importlib.util.spec_from_loader( filename, loader )
mymodule = importlib.util.module_from_spec( spec )
loader.exec_module( mymodule )
# find the classes in the extension
extenderclasses = { n:c for n,c in inspect.getmembers( mymodule, inspect.isclass ) }
# add them to the extended class so they precede (i.e. may override) the previous base classes
for n,c in extenderclasses.items():
# add to bases
print( f"Extending {extendedclass} with {c}" )
extendedclass.__bases__ = (c,)+extendedclass.__bases__
## load any local extensions
load_extensions()