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