Skip to content

Commit 52a34d9

Browse files
committed
Make raisef more pythonic; support also raise ... from ...
See #30. Now all that's left is to drop support for the old-style parameters when v0.15.0 hits.
1 parent f4da595 commit 52a34d9

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

doc/features.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2745,12 +2745,19 @@ Inspired by *Function application with $* in [LYAH: Higher Order Functions](http
27452745
27462746
### ``raisef``: ``raise`` as a function
27472747
2748+
*Changed in v0.14.2.* The parameters of `raisef` now more closely match what would be passed to `raise`. See examples below. Old-style parameters are now deprecated, and support for them will be dropped in v0.15.0.
2749+
27482750
Raise an exception from an expression position:
27492751
27502752
```python
27512753
from unpythonic import raisef
27522754
2753-
f = lambda x: raisef(RuntimeError, "I'm in ur lambda raising exceptions")
2755+
# plain `raise ...`
2756+
f = lambda x: raisef(RuntimeError("I'm in ur lambda raising exceptions"))
2757+
2758+
# `raise ... from ...`
2759+
exc = TypeError("oof")
2760+
g = lambda x: raisef(RuntimeError("I'm in ur lambda raising exceptions"), cause=exc)
27542761
```
27552762
27562763

unpythonic/misc.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,28 +208,48 @@ def applyfrozenargsto(f):
208208
return maybe_force_args(force(f), *args, **kwargs)
209209
return applyfrozenargsto
210210

211-
def raisef(exctype, *args, **kwargs):
211+
def raisef(exc, *args, cause=None, **kwargs):
212212
"""``raise`` as a function, to make it possible for lambdas to raise exceptions.
213213
214214
Example::
215215
216-
raisef(ValueError, "message")
216+
raisef(ValueError("message"))
217217
218218
is (almost) equivalent to::
219219
220220
raise ValueError("message")
221221
222222
Parameters:
223-
exctype: type
223+
exc: exception instance, or exception class
224+
The object to raise. This is whatever you would give as the argument to `raise`.
225+
Both instances (e.g. `ValueError("oof")`) and classes (e.g. `StopIteration`)
226+
can be used as `exc`.
227+
228+
cause: exception instance, or `None`
229+
If `exc` was triggered as a direct consequence of another exception,
230+
and you would like to `raise ... from ...`, pass that other exception
231+
instance as `cause`. The default `None` performs a plain `raise ...`.
232+
233+
*Changed in v0.14.2.* The parameters have changed to match `raise` itself as closely
234+
as possible. Old-style parameters are still supported, but are now deprecated. Support
235+
for them will be dropped in v0.15.0. The old-style parameters are:
236+
237+
exc: type
224238
The object type to raise as an exception.
225239
226240
*args: anything
227-
Passed on to the constructor of exctype.
241+
Passed on to the constructor of exc.
228242
229243
**kwargs: anything
230-
Passed on to the constructor of exctype.
244+
Passed on to the constructor of exc.
231245
"""
232-
raise exctype(*args, **kwargs)
246+
if args or kwargs: # old-style parameters
247+
raise exc(*args, **kwargs)
248+
249+
if cause:
250+
raise exc from cause
251+
else:
252+
raise exc
233253

234254
def pack(*args):
235255
"""Multi-argument constructor for tuples.

unpythonic/test/test_misc.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,26 @@ def mul3(a, b, c):
9393
m = (f(3) for f in [lambda x: 2 * x, lambda x: x**2, lambda x: x**(1 / 2)])
9494
assert tuple(m) == (6, 9, 3**(1 / 2))
9595

96+
# raisef: raise an exception from an expression position
97+
l = lambda: raisef(ValueError("all ok")) # the argument works the same as in `raise ...`
98+
try:
99+
l()
100+
except ValueError as err:
101+
assert err.__cause__ is None # like plain `raise ...`, no cause set (default behavior)
102+
else:
103+
assert False
104+
105+
# using the `cause` parameter, raisef can also perform a `raise ... from ...`
106+
exc = TypeError("oof")
107+
l = lambda: raisef(ValueError("all ok"), cause=exc)
108+
try:
109+
l()
110+
except ValueError as err:
111+
assert err.__cause__ is exc # cause specified, like `raise ... from ...`
112+
else:
113+
assert False
114+
115+
# raisef with old-style parameters (as of v0.14.2, deprecated, will be dropped in v0.15.0)
96116
l = lambda: raisef(ValueError, "all ok")
97117
try:
98118
l()

0 commit comments

Comments
 (0)