R
Ryan Kelly
Hi All,
Apologies if you receive multiple copies of this, my python-announce
posts don't seem to be making it through.
I've just released a new python module called "withrestart". It's an
attempted Pythonisation of the restart-based condition system of Common
Lisp. Details are on PyPI:
http://pypi.python.org/pypi/withrestart/0.2.1
For an introduction to conditions and restarts, see "Beyond Exception
Handling" by Peter Seibel:
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
For a quick demo of the module in action, keep reading...
Cheers,
Ryan
About withrestart:
------------------
Version: 0.2.1
Licence: MIT
Source: http://github.com/rfk/withrestart
withrestart is a Pythonisation (Lispers might rightly say "bastardisation") of
the restart-based condition system of Common Lisp. It's designed to make error
recovery simpler and easier by removing the assumption that unhandled errors
must be fatal.
A "restart" represents a named strategy for resuming execution of a function
after the occurrence of an error. At any point during its execution a
function can push a Restart object onto its call stack. If an exception
occurs within the scope of that Restart, code higher-up in the call chain can
invoke it to recover from the error and let the function continue execution..
By providing several restarts, functions can offer several different strategies
for recovering from errors.
A "handler" represents a higher-level strategy for dealing with the occurrence
of an error. It is conceptually similar to an "except" clause, in that one
establishes a suite of Handler objects to be invoked if an error occurs during
the execution of some code. There is, however, a crucial difference: handlers
are executed without unwinding the call stack. They thus have the opportunity
to take corrective action and then resume execution of whatever function
raised the error.
As an example, here's a function that doesn't like the number seven:
def anything_but_seven(v):
if v == 7:
raise ValueError("Argh! A Seven!")
return v
And here's a function that can recover from the occurrence of a seven
using the pre-defined restarts "skip" and "use_value":
def sum_items(items):
total = 0
for i in items:
with restarts(skip,use_value) as invoke:
total += invoke(anything_but_seven,i)
return total
Naively calling this will raise a ValueError:
Traceback (most recent call last):
...
ValueError: Argh! A Seven!
But if we handle ValueErrors by invoking the "skip" restart, we can
still get the sum of the remaining items:
... sum_items(range(8))
...
21
Alternately, we can invoke the "use_value" restart to replace the sevens
with another value:
... sum_items(range(8))
...
33
By splitting the responsibility for error recovery between Handlers and
Restarts, we can cleanly separate the low-level mechanics of recovering
from an error from the high-level decisions about what sort of recovery
to perform.
--
Ryan Kelly
http://www.rfk.id.au | This message is digitally signed. Please visit
(e-mail address removed) | http://www.rfk.id.au/ramblings/gpg/ for details
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEABECAAYFAksrFJoACgkQfI5S64uP50r9fQCfdJ1MpUwmForLdBHyucrO6BnI
Qf0AmwSDupSgzNklVZhVXBZtYT6ZyITS
=Aubk
-----END PGP SIGNATURE-----
Apologies if you receive multiple copies of this, my python-announce
posts don't seem to be making it through.
I've just released a new python module called "withrestart". It's an
attempted Pythonisation of the restart-based condition system of Common
Lisp. Details are on PyPI:
http://pypi.python.org/pypi/withrestart/0.2.1
For an introduction to conditions and restarts, see "Beyond Exception
Handling" by Peter Seibel:
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
For a quick demo of the module in action, keep reading...
Cheers,
Ryan
About withrestart:
------------------
Version: 0.2.1
Licence: MIT
Source: http://github.com/rfk/withrestart
withrestart is a Pythonisation (Lispers might rightly say "bastardisation") of
the restart-based condition system of Common Lisp. It's designed to make error
recovery simpler and easier by removing the assumption that unhandled errors
must be fatal.
A "restart" represents a named strategy for resuming execution of a function
after the occurrence of an error. At any point during its execution a
function can push a Restart object onto its call stack. If an exception
occurs within the scope of that Restart, code higher-up in the call chain can
invoke it to recover from the error and let the function continue execution..
By providing several restarts, functions can offer several different strategies
for recovering from errors.
A "handler" represents a higher-level strategy for dealing with the occurrence
of an error. It is conceptually similar to an "except" clause, in that one
establishes a suite of Handler objects to be invoked if an error occurs during
the execution of some code. There is, however, a crucial difference: handlers
are executed without unwinding the call stack. They thus have the opportunity
to take corrective action and then resume execution of whatever function
raised the error.
As an example, here's a function that doesn't like the number seven:
def anything_but_seven(v):
if v == 7:
raise ValueError("Argh! A Seven!")
return v
And here's a function that can recover from the occurrence of a seven
using the pre-defined restarts "skip" and "use_value":
def sum_items(items):
total = 0
for i in items:
with restarts(skip,use_value) as invoke:
total += invoke(anything_but_seven,i)
return total
Naively calling this will raise a ValueError:
Traceback (most recent call last):
...
ValueError: Argh! A Seven!
But if we handle ValueErrors by invoking the "skip" restart, we can
still get the sum of the remaining items:
... sum_items(range(8))
...
21
Alternately, we can invoke the "use_value" restart to replace the sevens
with another value:
... sum_items(range(8))
...
33
By splitting the responsibility for error recovery between Handlers and
Restarts, we can cleanly separate the low-level mechanics of recovering
from an error from the high-level decisions about what sort of recovery
to perform.
--
Ryan Kelly
http://www.rfk.id.au | This message is digitally signed. Please visit
(e-mail address removed) | http://www.rfk.id.au/ramblings/gpg/ for details
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEABECAAYFAksrFJoACgkQfI5S64uP50r9fQCfdJ1MpUwmForLdBHyucrO6BnI
Qf0AmwSDupSgzNklVZhVXBZtYT6ZyITS
=Aubk
-----END PGP SIGNATURE-----