diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py index 67c64276ee579d0bbb7a9f524b1fbf53d6c5aa6e..cadfa95426a0548dbdec3b64b34e1478d35486b5 100644 --- a/lib/spack/spack/__init__.py +++ b/lib/spack/spack/__init__.py @@ -186,7 +186,8 @@ # packages should live. This file is overloaded for spack core vs. # for packages. # -__all__ = ['Package', +__all__ = ['PackageBase', + 'Package', 'CMakePackage', 'AutotoolsPackage', 'MakefilePackage', @@ -195,7 +196,7 @@ 'ver', 'alldeps', 'nolink'] -from spack.package import Package, ExtensionConflictError +from spack.package import Package, PackageBase, ExtensionConflictError from spack.build_systems.makefile import MakefilePackage from spack.build_systems.autotools import AutotoolsPackage from spack.build_systems.cmake import CMakePackage diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py index 2790508ee877ebd3bef551c6de26fe40f66d32fe..fbcb172f0c3750cdb62995c47b079039409cd36e 100644 --- a/lib/spack/spack/util/executable.py +++ b/lib/spack/spack/util/executable.py @@ -184,11 +184,11 @@ def streamify(arg, mode): result += err return result - except OSError, e: + except OSError as e: raise ProcessError( "%s: %s" % (self.exe[0], e.strerror), "Command: " + cmd_line) - except subprocess.CalledProcessError, e: + except subprocess.CalledProcessError as e: if fail_on_error: raise ProcessError( str(e), "\nExit status %d when invoking command: %s" % @@ -249,21 +249,41 @@ def __init__(self, msg, long_message=None): @property def long_message(self): - msg = self._long_message - if msg: - msg += "\n\n" - if self.build_log: - msg += "See build log for details:\n" - msg += " %s" % self.build_log + msg = self._long_message if self._long_message else '' if self.package_context: if msg: msg += "\n\n" msg += '\n'.join(self.package_context) + if msg: + msg += "\n\n" + + if self.build_log: + msg += "See build log for details:\n" + msg += " %s" % self.build_log + return msg + def __reduce__(self): + # We need this constructor because we are trying to move a ProcessError + # across processes. This means that we have to preserve the original + # package context and build log + return _make_process_error, ( + self.message, + self._long_message, + self.package_context, + self.build_log + ) + + +def _make_process_error(msg, long_message, pkg_context, build_log): + a = ProcessError(msg, long_message) + a.package_context = pkg_context + a.build_log = build_log + return a + def _get_package_context(): """Return some context for an error message when the build fails. @@ -291,7 +311,7 @@ def _get_package_context(): # Look only at a frame in a subclass of spack.Package obj = frame.f_locals['self'] - if type(obj) != spack.Package and isinstance(obj, spack.Package): + if type(obj) != spack.PackageBase and isinstance(obj, spack.PackageBase): # NOQA: ignore=E501 break else: # Didn't find anything