From d8c44189528207dd341766284dd08d0a78bc879f Mon Sep 17 00:00:00 2001 From: Sergey Kosukhin Date: Fri, 9 Dec 2016 10:18:10 +0100 Subject: Updated python: refactoring and warning messages. --- var/spack/repos/builtin/packages/python/package.py | 93 +++++++++++++--------- 1 file changed, 57 insertions(+), 36 deletions(-) (limited to 'var') diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py index b5c11ee527..010632dbe7 100644 --- a/var/spack/repos/builtin/packages/python/package.py +++ b/var/spack/repos/builtin/packages/python/package.py @@ -29,10 +29,11 @@ from contextlib import closing import spack import llnl.util.tty as tty -import yaml from llnl.util.lang import match_predicate +from llnl.util.filesystem import force_remove from spack import * from spack.util.environment import * +import spack.util.spack_json as sjson class Python(Package): @@ -78,6 +79,10 @@ class Python(Package): patch('ncurses.patch') + _DISTUTIL_VARS_TO_SAVE = ['LDSHARED'] + _DISTUTIL_CACHE_FILENAME = 'sysconfig.json' + _distutil_vars = None + @when('@2.7,3.4:') def patch(self): # NOTE: Python's default installation procedure makes it possible for a @@ -134,7 +139,7 @@ class Python(Package): make() make('install') - self.save_distutils_data(prefix) + self._save_distutil_vars(prefix) self.filter_compilers(prefix) @@ -176,7 +181,7 @@ class Python(Package): # >>> import Tkinter # >>> Tkinter._test() - def save_distutils_data(self, prefix): + def _save_distutil_vars(self, prefix): """ Run before changing automatically generated contents of the _sysconfigdata.py, which is used by distutils to figure out what @@ -188,6 +193,8 @@ class Python(Package): autogenerated value to pass it to the dependant package's setup script. """ + self._distutil_vars = {} + input_filename = None for filename in [join_path(lib_dir, 'python{0}'.format(self.version.up_to(2)), @@ -201,7 +208,6 @@ class Python(Package): return input_dict = None - try: with open(input_filename) as input_file: match = re.search(r'build_time_vars\s*=\s*(?P{.*})', @@ -214,45 +220,60 @@ class Python(Package): pass if not input_dict: + tty.warn('Failed to find \'build_time_vars\' dictionary in file ' + '\'%s\'. This might cause the extensions that are ' + 'installed with distutils to call compilers directly ' + 'avoiding Spack\'s wrappers.' % input_filename) return - vars_to_save = ['LDSHARED'] - saved_vars = {} - - for var_name in vars_to_save: + for var_name in Python._DISTUTIL_VARS_TO_SAVE: if var_name in input_dict: - saved_vars[var_name] = input_dict[var_name] - - if len(saved_vars) > 0: + self._distutil_vars[var_name] = input_dict[var_name] + else: + tty.warn('Failed to find key \'%s\' in \'build_time_vars\' ' + 'dictionary in file \'%s\'. This might cause the ' + 'extensions that are installed with distutils to ' + 'call compilers directly avoiding Spack\'s wrappers.' + % (var_name, input_filename)) + + if len(self._distutil_vars) > 0: + output_filename = None try: output_filename = join_path( spack.store.layout.metadata_path(self.spec), - 'sysconfig.yaml') + Python._DISTUTIL_CACHE_FILENAME) with open(output_filename, 'w') as output_file: - yaml.dump(saved_vars, stream=output_file, - default_flow_style=False) - except (yaml.YAMLError, IOError): + sjson.dump(self._distutil_vars, output_file) + except: + tty.warn('Failed to save metadata for distutils. This might ' + 'cause the extensions that are installed with ' + 'distutils to call compilers directly avoiding ' + 'Spack\'s wrappers.') + # We make the cache empty if we failed to save it to file + # to provide the same behaviour as in the case when the cache + # is initialized by the method load_distutils_data(). + self._distutil_vars = {} + if output_filename: + force_remove(output_filename) + + def _load_distutil_vars(self): + # We update and keep the cache unchanged only if the package is + # installed. + if not self._distutil_vars and self.installed: + try: + input_filename = join_path( + spack.store.layout.metadata_path(self.spec), + Python._DISTUTIL_CACHE_FILENAME) + if os.path.isfile(input_filename): + with open(input_filename) as input_file: + self._distutil_vars = sjson.load(input_file) + except: pass - setattr(self, '_distutils_data_cache', saved_vars) - - def load_distutils_data(self): - if not hasattr(self, '_distutils_data_cache'): - input_filename = join_path( - spack.store.layout.metadata_path(self.spec), - 'sysconfig.yaml') - if os.path.isfile(input_filename): - try: - with open(input_filename) as input_file: - setattr(self, '_distutils_data_cache', - yaml.load(input_file)) - except (yaml.YAMLError, IOError): - pass - - if not hasattr(self, '_distutils_data_cache'): - setattr(self, '_distutils_data_cache', None) + if not self._distutil_vars: + self._distutil_vars = {} - return self._distutils_data_cache + return self._distutil_vars def filter_compilers(self, prefix): """Run after install to tell the configuration files and Makefiles @@ -350,10 +371,10 @@ class Python(Package): module.python = Executable(python_path) module.setup_py = Executable(python_path + ' setup.py --no-user-cfg') - distutils_data = self.load_distutils_data() + distutil_vars = self._load_distutil_vars() - if distutils_data: - for key, value in distutils_data.iteritems(): + if distutil_vars: + for key, value in distutil_vars.iteritems(): module.setup_py.add_default_env(key, value) # Add variables for lib/pythonX.Y and lib/pythonX.Y/site-packages dirs. -- cgit v1.2.3-70-g09d2