summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2014-10-29 20:54:24 -0400
committerBenjamin Peterson <benjamin@python.org>2014-10-29 20:54:24 -0400
commit7330876ca5a33ff17d30c430514e00a2650a51de (patch)
tree998168d25045fd0cefda921c2e09fe869f42288d
parent0d77f9165f69e5f46ce364439484157bb193ff11 (diff)
downloadsix-7330876ca5a33ff17d30c430514e00a2650a51de.tar.gz
add raise_from (fixes #102)
Patch from Robert Collins.
-rw-r--r--CHANGES2
-rw-r--r--documentation/index.rst7
-rw-r--r--six.py9
-rw-r--r--test_six.py21
4 files changed, 39 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index fa74e77..cae8ef0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,8 @@ This file lists the changes in each six version.
Development version
-------------------
+- Issue #102: Add `raise_from` to abstract out Python 3's raise from syntax.
+
- Issue #97: Optimize `six.iterbytes` on Python 2.
- Issue #98: Fix `six.moves` race condition in multi-threaded code.
diff --git a/documentation/index.rst b/documentation/index.rst
index c7ca996..7851421 100644
--- a/documentation/index.rst
+++ b/documentation/index.rst
@@ -282,6 +282,13 @@ Python 2 and 3.
ok. :)
+.. function:: raise_from(exc_value, exc_value_from)
+
+ Raise an exception from a context. On Python 3, this is equivalent to
+ ``raise exc_value from exc_value_from``. On Python 2, which does not support
+ exception chaining, it is equivalent to ``raise exc_value``.
+
+
.. function:: reraise(exc_type, exc_value, exc_traceback=None)
Reraise an exception, possibly with a different traceback. In the simple
diff --git a/six.py b/six.py
index 232a0c7..a8cdb22 100644
--- a/six.py
+++ b/six.py
@@ -659,6 +659,15 @@ else:
""")
+if sys.version_info > (3, 2):
+ exec_("""def raise_from(value, from_value):
+ raise value from from_value
+""")
+else:
+ def raise_from(value, from_value):
+ raise value
+
+
print_ = getattr(moves.builtins, "print", None)
if print_ is None:
def print_(*args, **kwargs):
diff --git a/test_six.py b/test_six.py
index 4163520..b0ccd8d 100644
--- a/test_six.py
+++ b/test_six.py
@@ -588,6 +588,27 @@ def test_reraise():
assert tb is get_next(tb2)
+def test_raise_from():
+ try:
+ try:
+ raise Exception("blah")
+ except Exception:
+ ctx = sys.exc_info()[1]
+ f = Exception("foo")
+ six.raise_from(f, None)
+ except Exception:
+ tp, val, tb = sys.exc_info()
+ if sys.version_info[:2] > (3, 0):
+ # We should have done a raise f from None equivalent.
+ assert val.__cause__ is None
+ assert val.__context__ is ctx
+ if sys.version_info[:2] >= (3, 3):
+ # And that should suppress the context on the exception.
+ assert val.__suppress_context__
+ # For all versions the outer exception should have raised successfully.
+ assert str(val) == "foo"
+
+
def test_print_():
save = sys.stdout
out = sys.stdout = six.moves.StringIO()