From b22118a2de2f8a3bd14f209ab097ef5a9f7865c1 Mon Sep 17 00:00:00 2001 From: Nikolaus Lieb Date: Sat, 25 Jul 2015 18:25:59 +0800 Subject: [PATCH] Add an option to skip searching the regular sys.path when loading waf tools. Granting this control allows the avoidance of issues such as accidentally loading the "cython" module from from Cython itself, rather than the "cython" waf tool. Conflicts: waflib/Configure.py waflib/Context.py --- waflib/Configure.py | 4 ++-- waflib/Context.py | 54 +++++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/waflib/Configure.py b/waflib/Configure.py index 49b52247..3d69b06e 100644 --- a/waflib/Configure.py +++ b/waflib/Configure.py @@ -234,7 +234,7 @@ class ConfigurationContext(Context.Context): tmpenv = self.all_envs[key] tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX)) - def load(self, input, tooldir=None, funs=None): + def load(self, input, tooldir=None, funs=None, loadFromSysPath=True): """ Load Waf tools, which will be imported whenever a build is started. @@ -260,7 +260,7 @@ class ConfigurationContext(Context.Context): module = None try: - module = Context.load_tool(tool, tooldir, ctx=self) + module = Context.load_tool(tool, tooldir, ctx=self, loadFromSysPath=loadFromSysPath) except ImportError as e: self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, sys.path, e)) except Exception as e: diff --git a/waflib/Context.py b/waflib/Context.py index fe733e4d..d1a1c7d4 100644 --- a/waflib/Context.py +++ b/waflib/Context.py @@ -210,9 +210,10 @@ class Context(ctx): """ tools = Utils.to_list(tool_list) path = Utils.to_list(kw.get('tooldir', '')) + loadFromSysPath = kw.get('loadFromSysPath', True) for t in tools: - module = load_tool(t, path) + module = load_tool(t, path, loadFromSysPath=loadFromSysPath) fun = getattr(module, kw.get('name', self.fun), None) if fun: fun(self) @@ -627,7 +628,7 @@ def load_module(path, encoding=None): return module -def load_tool(tool, tooldir=None, ctx=None): +def load_tool(tool, tooldir=None, ctx=None, loadFromSysPath=True): """ Import a Waf tool (python module), and store it in the dict :py:const:`waflib.Context.Context.tools` @@ -635,33 +636,44 @@ def load_tool(tool, tooldir=None, ctx=None): :param tool: Name of the tool :type tooldir: list :param tooldir: List of directories to search for the tool module + :type loadFromSysPath: boolean + :param loadFromSysPath: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs """ if tool == 'java': tool = 'javaw' # jython else: tool = tool.replace('++', 'xx') - if tooldir: - assert isinstance(tooldir, list) - sys.path = tooldir + sys.path - try: - __import__(tool) + origSysPath = sys.path + if not loadFromSysPath: sys.path = [] + try: + if tooldir: + assert isinstance(tooldir, list) + sys.path = tooldir + sys.path + try: + __import__(tool) + finally: + for d in tooldir: + sys.path.remove(d) ret = sys.modules[tool] Context.tools[tool] = ret return ret - finally: - for d in tooldir: - sys.path.remove(d) - else: - for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): + else: + if not loadFromSysPath: sys.path.insert(0, waf_dir) try: - __import__(x % tool) - break - except ImportError: - x = None - if x is None: # raise an exception - __import__(tool) - ret = sys.modules[x % tool] - Context.tools[tool] = ret - return ret + for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): + try: + __import__(x % tool) + break + except ImportError: + x = None + if x is None: # raise an exception + __import__(tool) + finally: + if not loadFromSysPath: sys.path.remove(waf_dir) + ret = sys.modules[x % tool] + Context.tools[tool] = ret + return ret + finally: + if not loadFromSysPath: sys.path += origSysPath