aboutsummaryrefslogtreecommitdiffstats
path: root/setuptools/sandbox.py
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2015-01-14 22:06:09 -0500
committerJason R. Coombs <jaraco@jaraco.com>2015-01-14 22:06:09 -0500
commit9cf04f13f2ff72a7befa15f8f4835d2c662508e6 (patch)
treed4c59c3838e66d9aa84ac78441ffe754b5f288c8 /setuptools/sandbox.py
parent9c3d6750cbef8e0673e4123aa39149e28a8a098e (diff)
downloadexternal_python_setuptools-9cf04f13f2ff72a7befa15f8f4835d2c662508e6.tar.gz
external_python_setuptools-9cf04f13f2ff72a7befa15f8f4835d2c662508e6.tar.bz2
external_python_setuptools-9cf04f13f2ff72a7befa15f8f4835d2c662508e6.zip
Wrap unpickleable exceptions in another class. Fixes #329.
Diffstat (limited to 'setuptools/sandbox.py')
-rwxr-xr-xsetuptools/sandbox.py24
1 files changed, 19 insertions, 5 deletions
diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py
index 0847ef41..83283ca3 100755
--- a/setuptools/sandbox.py
+++ b/setuptools/sandbox.py
@@ -92,6 +92,22 @@ def pushd(target):
os.chdir(saved)
+class UnpickleableException(Exception):
+ """
+ An exception representing another Exception that could not be pickled.
+ """
+ @classmethod
+ def dump(cls, type, exc):
+ """
+ Always return a dumped (pickled) type and exc. If exc can't be pickled,
+ wrap it in UnpickleableException first.
+ """
+ try:
+ return pickle.dumps(type), pickle.dumps(exc)
+ except Exception:
+ return cls.dump(cls, cls(repr(exc)))
+
+
class ExceptionSaver:
"""
A Context Manager that will save an exception, serialized, and restore it
@@ -105,8 +121,7 @@ class ExceptionSaver:
return
# dump the exception
- self._type = pickle.dumps(type)
- self._exc = pickle.dumps(exc)
+ self._saved = UnpickleableException.dump(type, exc)
self._tb = tb
# suppress the exception
@@ -115,11 +130,10 @@ class ExceptionSaver:
def resume(self):
"restore and re-raise any exception"
- if '_exc' not in vars(self):
+ if '_saved' not in vars(self):
return
- type = pickle.loads(self._type)
- exc = pickle.loads(self._exc)
+ type, exc = map(pickle.loads, self._saved)
compat.reraise(type, exc, self._tb)