[Reproducible-commits] [reprotest] 01/02: Monkey-patch contextlib.ExitStack to work around CPython bug, see https://bugs.python.org/issue25782 and https://bugs.python.org/issue25786
Ceridwen
ceridwen-guest at moszumanska.debian.org
Sat Jul 16 04:17:21 UTC 2016
This is an automated email from the git hooks/post-receive script.
ceridwen-guest pushed a commit to branch virtualization
in repository reprotest.
commit 06d19d22c627a905a5db3478cc157fe2a2c48914
Author: Ceridwen <ceridwenv at gmail.com>
Date: Sat Jul 16 00:15:08 2016 -0400
Monkey-patch contextlib.ExitStack to work around CPython bug, see https://bugs.python.org/issue25782 and https://bugs.python.org/issue25786
---
reprotest/__init__.py | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/reprotest/__init__.py b/reprotest/__init__.py
index d2627a8..c172fec 100644
--- a/reprotest/__init__.py
+++ b/reprotest/__init__.py
@@ -24,6 +24,72 @@ from reprotest import _shell_ast
adtlog.verbosity = 2
+# Monkey-patch contextlib.ExitStack
+
+# Patch from: https://bugs.python.org/file41216/Issue25786.patch
+
+# https://bugs.python.org/issue25782
+
+# https://bugs.python.org/issue25786
+
+# This code is from the standard library contextlib
+
+def monkey_patch_exit_stack():
+ def __exit__(self, *exc_details):
+ received_exc = exc_details[0] is not None
+
+ # We manipulate the exception state so it behaves as though
+ # we were actually nesting multiple with statements
+ frame_exc = sys.exc_info()[1]
+ def _fix_exception_context(new_exc, old_exc):
+ # Context may not be correct, so find the end of the chain
+ if new_exc is old_exc:
+ return
+ while 1:
+ exc_context = new_exc.__context__
+ if exc_context is old_exc:
+ # Context is already set correctly (see issue 20317)
+ return
+ if exc_context is None or exc_context is frame_exc:
+ break
+ new_exc = exc_context
+ # Change the end of the chain to point to the exception
+ # we expect it to reference
+ new_exc.__context__ = old_exc
+
+ # Callbacks are invoked in LIFO order to match the behaviour of
+ # nested context managers
+ suppressed_exc = False
+ pending_raise = False
+ while self._exit_callbacks:
+ cb = self._exit_callbacks.pop()
+ try:
+ if cb(*exc_details):
+ suppressed_exc = True
+ pending_raise = False
+ exc_details = (None, None, None)
+ except:
+ new_exc_details = sys.exc_info()
+ # simulate the stack of exceptions by setting the context
+ _fix_exception_context(new_exc_details[1], exc_details[1])
+ pending_raise = True
+ exc_details = new_exc_details
+ if pending_raise:
+ try:
+ # bare "raise exc_details[1]" replaces our carefully
+ # set-up context
+ fixed_ctx = exc_details[1].__context__
+ raise exc_details[1]
+ except BaseException:
+ exc_details[1].__context__ = fixed_ctx
+ raise
+ return received_exc and suppressed_exc
+
+ contextlib.ExitStack.__exit__ = __exit__
+
+monkey_patch_exit_stack()
+
+
# chroot is the only form of OS virtualization that's available on
# most POSIX OSes. Linux containers (lxc) and namespaces are specific
# to Linux. Some versions of BSD have jails (MacOS X?). There are a
@@ -202,6 +268,8 @@ def build(script, source_root, built_artifact, testbed, artifact_store, env):
testbed.check_exec(['sh', '-ec', str(new_script)], xenv=[str(k) + '=' + str(v) for k, v in env.items()])
# print(exit_code, stdout, stderr)
testbed.execute(['ls', '-l', source_root])
+ testbed.execute(['stat', source_root])
+ testbed.execute(['stat', built_artifact])
testbed.command('copyup', (built_artifact, artifact_store))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/reprotest.git
More information about the Reproducible-commits
mailing list