From 8c1c6f136c359fa64f8e4913a7504c54d4754ad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Dunand?= Date: Mon, 16 Jul 2012 14:26:29 +0200 Subject: [PATCH] Allow to use embedded lib in embedded lib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example, if you have the following scripts in an image: lib/ |- 01-foo.py (module 'foo') |- 02-bar.py (module 'bar') module 'bar' (and subsequent) could import and use content from module 'foo'. Signed-off-by: Sébastien Luttringer --- installsystems/image.py | 46 +++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/installsystems/image.py b/installsystems/image.py index 0e3ee10..435fc5b 100644 --- a/installsystems/image.py +++ b/installsystems/image.py @@ -103,7 +103,7 @@ class Image(object): raise ISError(u"Unable to compile %s" % filename, e) # load module try: - exec bytecode in module.__dict__ + self.secure_exec_bytecode(bytecode, name, module.__dict__) except Exception as e: raise ISError(u"Unable to load %s" % filename, e) return module @@ -148,9 +148,6 @@ class Image(object): arrow(u"Run %s scripts" % scripts_name) # backup current directory and loaded modules cwd = os.getcwd() - # system modules dict - sysmodules = sys.modules - sysmodules_backup = sysmodules.copy() for fp, fn, fc in select_scripts(): # check input unicode stuff assert(isinstance(fp, unicode)) @@ -166,28 +163,37 @@ class Image(object): bytecode = compile(fc, fn.encode(locale.getpreferredencoding()), "exec") except Exception as e: raise ISError(u"Unable to compile script %s" % fp, e) - # autoload modules - global_dict.update(self.modules) # add current image global_dict["image"] = self # execute source code - try: - # replace system modules by image loaded - # we must use the same directory and not copy it (probably C reference) - sysmodules.clear() - # sys must be in sys.module to allow loading of modules - sysmodules["sys"] = sys - sysmodules.update(self.modules) - exec bytecode in global_dict - sysmodules.clear() - sysmodules.update(sysmodules_backup) - except Exception as e: - sysmodules.clear() - sysmodules.update(sysmodules_backup) - raise ISError(u"Unable to execute script %s" % fp, e) + self.secure_exec_bytecode(bytecode, fp, global_dict) arrowlevel(level=old_level) os.chdir(cwd) + def secure_exec_bytecode(self, bytecode, path, global_dict): + ''' + Execute bytecode in a clean modules' environment, without altering + Installsystems' sys.modules + ''' + # system modules dict + sysmodules = sys.modules + sysmodules_backup = sysmodules.copy() + # autoload modules + global_dict.update(self.modules) + try: + # replace system modules by image loaded + # we must use the same directory and not copy it (probably C reference) + sysmodules.clear() + # sys must be in sys.module to allow loading of modules + sysmodules["sys"] = sys + sysmodules.update(self.modules) + exec bytecode in global_dict + except Exception as e: + raise ISError(u"Unable to execute script %s" % path, e) + finally: + sysmodules.clear() + sysmodules.update(sysmodules_backup) + class SourceImage(Image): ''' -- GitLab