Browse Source

Bugfixes in numerous import processes

Replace some old pure python import by LodelContext calls
Change the plugins imports methods to use LodelContext instead
Fixes dyncode exposure method
Yann Weber 8 years ago
parent
commit
e31adfda8e

+ 25
- 3
lodel/context.py View File

@@ -166,6 +166,13 @@ length == 2 but got : %s" % spec)
166 166
             self._expose_module(globs, module_fullname, exposure_spec)
167 167
         else:
168 168
             self._expose_objects(globs, module_fullname, exposure_spec)
169
+
170
+    ##@brief Return a module from current context
171
+    def get_module(self, fullname):
172
+        fullname = self._translate(fullname)
173
+        module = importlib.import_module(fullname)
174
+        return module
175
+        
169 176
     
170 177
     ##@brief Delete a site's context
171 178
     #@param site_id str : the site's name to remove the context
@@ -210,7 +217,10 @@ site_id set to None when we are in MULTISITE beahavior")
210 217
 : '%s'" % site_id)
211 218
         if site_id not in cls._contexts:
212 219
             raise ContextError("No context named '%s' found." % site_id)
213
-        cls._current = cls._contexts[site_id]
220
+        wanted_ctx = cls._contexts[site_id]
221
+        if hasattr(wanted_ctx, '__instance_path'):
222
+            os.chdir(self.__instance_path) #May cause problems
223
+        cls._current = wanted_ctx
214 224
         return cls._current
215 225
     
216 226
     ##@brief Getter for contexts
@@ -271,6 +281,12 @@ site_id set to None when we are in MULTISITE beahavior")
271 281
         for spec in specs.items():
272 282
             ctx.expose(globs, spec)
273 283
     
284
+    ##@brief Return a module from current context
285
+    #@param fullname str : module fullname
286
+    @classmethod
287
+    def module(cls, fullname):
288
+        return cls.get().get_module(fullname)
289
+        
274 290
     ##@brief Expose leapi_dyncode module
275 291
     @classmethod
276 292
     def expose_dyncode(cls, globs, alias = 'leapi_dyncode'):
@@ -404,9 +420,15 @@ MONOSITE mode")
404 420
             raise ImportError(msg)
405 421
     
406 422
     ##@brief Implements LodelContext::expose_dyncode()
423
+    #@todo change hardcoded leapi_dyncode.py filename
407 424
     def _expose_dyncode(self, globs, alias = 'leapi_dyncode'):
408
-        sys.path.append(self.__instance_path)
409
-        dyncode = importlib.import_module('leapi_dyncode')
425
+        fullname = '%s.%s.dyncode' % (CTX_PKG, self.__id)
426
+        if fullname in sys.modules:
427
+            dyncode = sys.modules[fullname]
428
+        else:
429
+            path = os.path.join(self.__instance_path, 'leapi_dyncode.py')
430
+            sfl = importlib.machinery.SourceFileLoader(fullname, path)
431
+            dyncode = sfl.load_module()
410 432
         self.safe_exposure(globs, dyncode, alias)
411 433
     
412 434
     ##@brief Translate a module fullname to the context equivalent

+ 4
- 2
lodel/plugin/core_hooks.py View File

@@ -40,7 +40,8 @@ def datasources_bootstrap_hook(hook_name, caller, payload):
40 40
 ##@brief Bootstrap hook that print debug infos about registered hooks
41 41
 @LodelHook('lodel2_bootstraped')
42 42
 def list_hook_debug_hook(name, caller, payload):
43
-    from lodel import logger
43
+    LodelContext.expose_modules(globals(), {
44
+        'lodel.logger': 'logger'})
44 45
     hlist = LodelHook.hook_list()
45 46
     for name, reg_hooks in hlist.items():
46 47
         for hook, priority in reg_hooks:
@@ -57,5 +58,6 @@ def list_hook_debug_hook(name, caller, payload):
57 58
 ##@brief Hooks that trigger custom methods injection in dynmic classes
58 59
 @LodelHook("lodel2_dyncode_loaded")
59 60
 def lodel2_plugins_custom_methods(self, caller, dynclasses):
60
-    from lodel.plugin.plugins import CustomMethod
61
+    LodelContext.expose_modules(globals(), {
62
+        'lodel.plugin.plugins': ['CustomMethod']})
61 63
     CustomMethod.set_registered(dynclasses)

+ 2
- 2
lodel/plugin/hooks.py View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 import os
4 4
 import copy
5
-from importlib.machinery import SourceFileLoader
5
+from lodel.context import LodelContext
6 6
 
7 7
 
8 8
 ##@brief Class designed to handle a hook's callback with a priority
@@ -64,7 +64,7 @@ class LodelHook(object):
64 64
     # @return modified payload
65 65
     @classmethod
66 66
     def call_hook(cls, hook_name, caller, payload):
67
-        from lodel import logger
67
+        LodelContext.expose_modules(globals(), {'lodel.logger': 'logger'})
68 68
         logger.info("Calling hook '%s'" % hook_name)
69 69
         if hook_name in cls._hooks:
70 70
             for hook in cls._hooks[hook_name]:

+ 7
- 13
lodel/plugin/plugins.py View File

@@ -5,7 +5,7 @@ import os.path
5 5
 import importlib
6 6
 import copy
7 7
 import json
8
-from importlib.machinery import SourceFileLoader, SourcelessFileLoader
8
+from importlib.machinery import SourceFileLoader
9 9
 
10 10
 from lodel.context import LodelContext
11 11
 LodelContext.expose_modules(globals(), {
@@ -297,13 +297,7 @@ class Plugin(object, metaclass=MetaPlugType):
297 297
         # Importing __init__.py infos in it
298 298
         plugin_module = '%s.%s' % (VIRTUAL_PACKAGE_NAME,
299 299
                                     plugin_name)
300
-
301
-        init_source = os.path.join(self.path, INIT_FILENAME)
302
-        try:
303
-            loader = SourceFileLoader(plugin_module, init_source)
304
-            self.module = loader.load_module()
305
-        except (ImportError,FileNotFoundError) as e:
306
-             raise PluginError("Failed to load plugin '%s'. It seems that the plugin name is not valid or the plugin do not exists" % plugin_name)
300
+        self.module = LodelContext.module(plugin_module)
307 301
 
308 302
         # loading confspecs
309 303
         try:
@@ -397,11 +391,10 @@ name differ from the one found in plugin's init file"
397 391
                 fname = filename,
398 392
                 name = self.name)
399 393
             raise PluginError(msg)
400
-        # importing the file in varname
401
-        module_name = self.module.__name__+"."+varname
402
-        filename = os.path.join(self.path, filename)
403
-        loader = SourceFileLoader(module_name, filename)
404
-        return loader.load_module()
394
+        #extract module name from filename
395
+        base_mod = '.'.join(filename.split('.')[:-1])
396
+        module_name = self.module.__name__+"."+base_mod
397
+        return importlib.import_module(module_name)
405 398
    
406 399
     ##@brief Check dependencies of plugin
407 400
     #@return A list of plugin name to be loaded before
@@ -813,6 +806,7 @@ file : '%s'. Running discover again..." % DISCOVER_CACHE_FILENAME)
813 806
     ##@brief Import init file from a plugin path
814 807
     #@param path str : Directory path
815 808
     #@return a tuple (init_module, module_name)
809
+    #@todo very dirty, clean it
816 810
     @classmethod
817 811
     def import_init(cls, path):
818 812
         cls._mod_cnt += 1 # in order to ensure module name unicity

+ 5
- 0
lodel/plugins/multisite/loader.py View File

@@ -58,6 +58,11 @@ for lodelsite_path in lodelsites_list:
58 58
     LodelHook.call_hook('lodel2_plugins_loaded', '__main__', None)
59 59
     #Next hook triggers call of interface's main loop
60 60
     LodelHook.call_hook('lodel2_bootstraped', '__main__', None)
61
+    #a dirty & quick attempt to fix context unwanted exite via
62
+    #hooks
63
+    for name in ( 'LodelHook', 'core_hooks', 'core_scripts',
64
+            'Settings', 'settings', 'logger', 'Plugin'):
65
+        del(globals()[name])
61 66
     #switch back to loader context
62 67
     LodelContext.set(None)
63 68
 

+ 1
- 1
lodel/plugins/webui/interface/controllers/listing.py View File

@@ -1,10 +1,10 @@
1 1
 # -*- coding: utf-8 -*-
2 2
 from lodel.context import LodelContext
3 3
 LodelContext.expose_modules(globals(), {'lodel.logger': 'logger'})
4
+LodelContext.expose_dyncode(globals(), 'dyncode')
4 5
 
5 6
 from .base import get_response
6 7
 from ...exceptions import *
7
-import leapi_dyncode as dyncode
8 8
 
9 9
 ##@brief These functions are called by the rules defined in ../urls.py
10 10
 ## To browse the editorial model

+ 1
- 2
lodel/plugins/webui/interface/controllers/users.py View File

@@ -5,8 +5,7 @@ from ...client import WebUiClient as WebUiClient
5 5
 
6 6
 from lodel.context import LodelContext
7 7
 LodelContext.expose_modules(globals(), {'lodel.logger': 'logger'})
8
-
9
-import leapi_dyncode as dyncode #TODO : handle this with context
8
+LodelContext.expose_dyncode(globals(), 'dyncode')
10 9
 
11 10
 ##@brief These functions are called by the rules defined in ../urls.py
12 11
 ## Their goal is to handle the user authentication

Loading…
Cancel
Save