Browse Source

Now we can use LodelContext with the with statement

Yann Weber 8 years ago
parent
commit
dbcccb2bbf
1 changed files with 60 additions and 8 deletions
  1. 60
    8
      lodel/context.py

+ 60
- 8
lodel/context.py View File

6
 import os
6
 import os
7
 import os.path
7
 import os.path
8
 import re
8
 import re
9
+import copy
9
 
10
 
10
 import warnings #For the moment no way to use the logger in this file (I guess)
11
 import warnings #For the moment no way to use the logger in this file (I guess)
11
 
12
 
107
     ##@brief Create a new context
108
     ##@brief Create a new context
108
     #@see LodelContext.new()
109
     #@see LodelContext.new()
109
     def __init__(self, site_id, instance_path = None):
110
     def __init__(self, site_id, instance_path = None):
110
-        print("New context instanciation named '%s'" % site_id)
111
+        if site_id is None and self.multisite():
112
+            site_id = LOAD_CTX
113
+        if self.multisite() and site_id is not LOAD_CTX:
114
+            with LodelContext.with_context(None) as ctx:
115
+                ctx.expose_modules(globals(), {'lodel.logger': 'logger'})
116
+                logger.info("New context instanciation named '%s'" % site_id)
111
         if site_id is None:
117
         if site_id is None:
118
+            self.__id = None
112
             #Monosite instanciation
119
             #Monosite instanciation
113
-            if self.__class__._type != self.__class__.MONOSITE:
120
+            if self.multisite():
114
                 raise ContextError("Cannot instanciate a context with \
121
                 raise ContextError("Cannot instanciate a context with \
115
 site_id set to None when we are in MULTISITE beahavior")
122
 site_id set to None when we are in MULTISITE beahavior")
116
             else:
123
             else:
121
                 return
128
                 return
122
         else:
129
         else:
123
             #Multisite instanciation
130
             #Multisite instanciation
124
-            if self.__class__._type != self.__class__.MULTISITE:
131
+            if not self.multisite():
125
                 raise ContextError("Cannot instanciate a context with a \
132
                 raise ContextError("Cannot instanciate a context with a \
126
 site_id when we are in MONOSITE beahvior")
133
 site_id when we are in MONOSITE beahvior")
127
             if not self.validate_identifier(site_id):
134
             if not self.validate_identifier(site_id):
145
             #Importing the site package to trigger its creation
152
             #Importing the site package to trigger its creation
146
             self.__package = importlib.import_module(self.__pkg_name)
153
             self.__package = importlib.import_module(self.__pkg_name)
147
             self.__class__._contexts[site_id] = self
154
             self.__class__._contexts[site_id] = self
155
+        #Designed to be use by with statement
156
+        self.__previous_ctx = None
148
     
157
     
149
     ##@brief Expose a module from the context
158
     ##@brief Expose a module from the context
150
     #@param globs globals : globals where we have to expose the module
159
     #@param globs globals : globals where we have to expose the module
165
         sys.path.append(self.__instance_path)
174
         sys.path.append(self.__instance_path)
166
         dyncode = importlib.import_module('leapi_dyncode')
175
         dyncode = importlib.import_module('leapi_dyncode')
167
         self.safe_exposure(globs, dyncode, alias)
176
         self.safe_exposure(globs, dyncode, alias)
177
+    
178
+    @classmethod
179
+    def multisite(cls):
180
+        return cls._type == cls.MULTISITE
181
+
182
+    @classmethod
183
+    def with_context(cls, target_ctx_id):
184
+        return cls.get(target_ctx_id)
168
 
185
 
169
     ##@brief Utility method to expose a module with an alias name in globals
186
     ##@brief Utility method to expose a module with an alias name in globals
170
     #@param globs globals() : concerned globals dict
187
     #@param globs globals() : concerned globals dict
220
         if site_id not in cls._contexts:
237
         if site_id not in cls._contexts:
221
             raise ContextError("No context named '%s' found." % site_id)
238
             raise ContextError("No context named '%s' found." % site_id)
222
         cls._current = cls._contexts[site_id]
239
         cls._current = cls._contexts[site_id]
240
+        return cls._current
241
+    
242
+    ##@brief Getter for contexts
243
+    #@param ctx_id str | None | False : if False return the current context
244
+    #@return A LodelContext instance
245
+    @classmethod
246
+    def get(cls, ctx_id = False):
247
+        if ctx_id is False:
248
+            if cls._current is None:
249
+                raise ContextError("No context loaded")
250
+            return cls._current
251
+        ctx_id = LOAD_CTX if ctx_id is None else ctx_id
252
+        if ctx_id not in cls._contexts:
253
+            raise ContextError("No context identified by '%s'" % ctx_id)
254
+        return cls._contexts[ctx_id]
223
     
255
     
224
-    ##@brief Helper method that returns the current context
256
+    ##@brief Returns the name of the loaded context
225
     @classmethod
257
     @classmethod
226
-    def get(cls):
258
+    def get_name(cls):
227
         if cls._current is None:
259
         if cls._current is None:
228
             raise ContextError("No context loaded")
260
             raise ContextError("No context loaded")
229
-        return cls._current
261
+        return copy.copy(cls._current.__id)
262
+        
230
 
263
 
231
     ##@brief Create a new context given a context name
264
     ##@brief Create a new context given a context name
232
     #
265
     #
349
                 "Unable to create a context named '%s'" % site_id)
382
                 "Unable to create a context named '%s'" % site_id)
350
         cls.new(site_id, path)
383
         cls.new(site_id, path)
351
         return site_id
384
         return site_id
352
-
385
+    
353
     ##@brief Delete a site's context
386
     ##@brief Delete a site's context
354
     #@param site_id str : the site's name to remove the context
387
     #@param site_id str : the site's name to remove the context
355
     def remove(cls, site_id):
388
     def remove(cls, site_id):
367
             else:
400
             else:
368
                 raise ContextError("Cannot have a context with \
401
                 raise ContextError("Cannot have a context with \
369
     site_id set when we are in MONOSITE beahavior")
402
     site_id set when we are in MONOSITE beahavior")
370
-        
403
+    
404
+    ##@brief Implements the with statement behavior
405
+    def __enter__(self):
406
+        if self.__previous_ctx is not None:
407
+            raise ContextError("__enter__ called but a previous context \
408
+is allready registered !!! Bailout")
409
+        current = LodelContext.get().__id
410
+        if current != self.__id:
411
+            #Only switch if necessary
412
+            self.__previous_ctx = LodelContext.get().__id
413
+            LodelContext.set(self.__id)
414
+        return self
415
+
416
+    ##@brief Implements the with statement behavior
417
+    def __exit__(self, exc_type, exc_val, exc_tb):
418
+        prev = self.__previous_ctx
419
+        self.__previous_ctx = None
420
+        if prev is not None:
421
+            #Only restore if needed
422
+            LodelContext.set(self.__previous_ctx)
371
 
423
 

Loading…
Cancel
Save