Skip to main content
This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (pypi.python.org).
Help us improve Python packaging - Donate today!

Implementation of the Common Lisp's conditions system in Python.

Project Description

Implementation of the Common Lisp’s conditions system in Python.

Free software: BSD license.

Rationale

Common Lisp (CL) has a very rich condition system. Conditions in CL is a some sort of signals, and used not only for exception handling but also in some other patterns. There is a very good explanation of how they works – a chapter from the book Practical Common Lisp by Peter Seibel: Beyond Exception Handling: Conditions and Restarts.

Python’s exceptions cover only one scenerio from this book, but Common Lisp’s conditions allows more interesting usage, particlarly “restarts”. Restart is a way to continue code execution after the exception was signaled, without unwinding a call stack. I’ll repeat: without unwinding a call stack.

Moreover, conditions allows to the author of the library to define varios cases to be choosen to take over the exception.

Example

Here is example from the book, but implemented in python using conditions library:

def parse_log_entry(text):
    """This function does all real job on log line parsing.
    it setup two cases for restart parsing if a line
    with wrong format was found.

    Restarts:
    - use_value: just retuns an object it was passed. This can
      be any value.
    - reparse: calls `parse_log_entry` again with other text value.
      Beware, this call can lead to infinite recursion.
    """
    text = text.strip()

    if well_formed_log_entry_p(text):
        return LogEntry(text)
    else:
        def use_value(obj):
            return obj
        def reparse(text):
            return parse_log_entry(text)

        with restarts(use_value,
                      reparse) as call:
            return call(signal, MalformedLogEntryError(text))


def log_analyzer(path):
    """This procedure replaces every line which can't be parsed
    with special object MalformedLogEntry.
    """
    with handle(MalformedLogEntryError,
                  lambda (c):
                      invoke_restart('use_value',
                                     MalformedLogEntry(c.text))):
        for filename in find_all_logs(path):
            analyze_log(filename)


def log_analyzer2(path):
    """This procedure considers every line which can't be parsed
    as a line with ERROR level.
    """
    with handle(MalformedLogEntryError,
                  lambda (c):
                      invoke_restart('reparse',
                                     'ERROR: ' + c.text)):
        for filename in find_all_logs(path):
            analyze_log(filename)

What we have here is a function parse_log_entry which defines two ways of handling an exceptional situation: use_value and reparse. But decision how bad lines should be handled is made by high level function log_analyser. Original book’s chapter have only one version of the log_analyser, but I’ve added an alternative log_analyser2 to illustrate a why restarts is a useful pattern. The value of this pattern is in the ability to move dicision making code from low level library functions into the higher level business logic.

Full version of this example can be found in example/example.py file.

Installation

pip install conditions

Development

To run the all tests run:

tox

Note, to combine the coverage data from all the tox environments run:

Windows
set PYTEST_ADDOPTS=--cov-append
tox
Other
PYTEST_ADDOPTS=--cov-append tox

Changelog

0.2.0 (2016-04-05)

  • Added context manager restarts and manager restart now gets only a function and returns a function like to call code to be restarted.

0.1.0 (2016-03-29)

  • First release on PyPI.
Release History

Release History

This version
History Node

0.2.0

History Node

0.1.0

Download Files

Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
conditions-0.2.0.tar.gz (19.3 kB) Copy SHA256 Checksum SHA256 Source Jan 16, 2017

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting