{ "info": { "author": "Alexander Artemenko", "author_email": "svetlyak.40wt@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Operating System :: Unix", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Utilities" ], "description": "========\nOverview\n========\n\nImplementation of the Common Lisp's conditions system in Python.\n\nFree software: BSD license.\n\n\n\nRationale\n=========\n\nCommon Lisp (CL) has a very rich condition system. Conditions in CL is a some sort\nof signals, and used not only for exception handling but also in some other patterns.\nThere is a very good explanation of how they works \u2013 a chapter from the book\nPractical Common Lisp by Peter Seibel:\n`Beyond Exception Handling: Conditions and Restarts`_.\n\nPython's exceptions cover only one scenerio from this book, but Common Lisp's conditions\nallows more interesting usage, particlarly \"restarts\". Restart is a way to continue\ncode execution after the exception was signaled, without unwinding a call stack.\nI'll repeat: without unwinding a call stack.\n\nMoreover, conditions allows to the author of the library to define varios cases to be\nchoosen to take over the exception.\n\n.. _`Beyond Exception Handling: Conditions and Restarts`: http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html\n\nExample\n-------\n\nHere is example from the book, but implemented in python using `conditions`_ library::\n\n def parse_log_entry(text):\n \"\"\"This function does all real job on log line parsing.\n it setup two cases for restart parsing if a line\n with wrong format was found.\n\n Restarts:\n - use_value: just retuns an object it was passed. This can\n be any value.\n - reparse: calls `parse_log_entry` again with other text value.\n Beware, this call can lead to infinite recursion.\n \"\"\"\n text = text.strip()\n\n if well_formed_log_entry_p(text):\n return LogEntry(text)\n else:\n def use_value(obj):\n return obj\n def reparse(text):\n return parse_log_entry(text)\n\n with restarts(use_value,\n reparse) as call:\n return call(signal, MalformedLogEntryError(text))\n\n\n def log_analyzer(path):\n \"\"\"This procedure replaces every line which can't be parsed\n with special object MalformedLogEntry.\n \"\"\"\n with handle(MalformedLogEntryError,\n lambda (c):\n invoke_restart('use_value',\n MalformedLogEntry(c.text))):\n for filename in find_all_logs(path):\n analyze_log(filename)\n\n\n def log_analyzer2(path):\n \"\"\"This procedure considers every line which can't be parsed\n as a line with ERROR level.\n \"\"\"\n with handle(MalformedLogEntryError,\n lambda (c):\n invoke_restart('reparse',\n 'ERROR: ' + c.text)):\n for filename in find_all_logs(path):\n analyze_log(filename)\n\nWhat we have here is a function ``parse_log_entry`` which defines two\nways of handling an exceptional situation: ``use_value`` and ``reparse``.\nBut decision how bad lines should be handled is made by high level function\n``log_analyser``. Original book's chapter have only one version of the\n``log_analyser``, but I've added an alternative ``log_analyser2`` to\nillustrate a why restarts is a useful pattern. The value of this\npattern is in the ability to move dicision making code from low level\nlibrary functions into the higher level business logic.\n\nFull version of this example can be found in `example/example.py`_ file.\n\n.. _conditions: https://github.com/svetlyak40wt/python-cl-conditions\n.. _`example/example.py`: https://github.com/svetlyak40wt/python-cl-conditions/blob/master/example/example.py\n\nInstallation\n============\n\n::\n\n pip install conditions\n\nDocumentation\n=============\n\nhttps://python-cl-conditions.readthedocs.org/\n\nDevelopment\n===========\n\nTo run the all tests run::\n\n tox\n\nNote, to combine the coverage data from all the tox environments run:\n\n.. list-table::\n :widths: 10 90\n :stub-columns: 1\n\n - - Windows\n - ::\n\n set PYTEST_ADDOPTS=--cov-append\n tox\n\n - - Other\n - ::\n\n PYTEST_ADDOPTS=--cov-append tox\n\n\nRelated projects\n================\n\nThere is also withrestart_ python library, created with\nthe same intent as conditions_. But it have clunky API and\nweird name seems abandoned since 2010.\n\n.. _withrestart: https://pypi.python.org/pypi/withrestart\n\n\nChangelog\n=========\n\n0.2.0 (2016-04-05)\n------------------\n\n* Added context manager ``restarts`` and manager ``restart`` now gets\n only a function and returns a function like to call code\n to be restarted.\n\n0.1.0 (2016-03-29)\n------------------\n\n* First release on PyPI.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/svetlyak40wt/python-cl-conditions", "keywords": "condition,restart,error,exception,cl,common lisp", "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "conditions", "package_url": "https://pypi.org/project/conditions/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/conditions/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/svetlyak40wt/python-cl-conditions" }, "release_url": "https://pypi.org/project/conditions/0.2.0/", "requires_dist": null, "requires_python": null, "summary": "Implementation of the Common Lisp's conditions system in Python.", "version": "0.2.0" }, "last_serial": 2576592, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "a3474c5593b3031607c118a85c926d1c", "sha256": "ba32dfa4064670cc7ef12fddf41d5da68d60043c6d45037e2ec0113658a8c65a" }, "downloads": -1, "filename": "conditions-0.1.0.tar.gz", "has_sig": false, "md5_digest": "a3474c5593b3031607c118a85c926d1c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15645, "upload_time": "2016-03-29T16:19:34", "url": "https://files.pythonhosted.org/packages/b8/a7/cdb8b639ee07b73344b21afefba3ea8f619d54895dbe2c07efbc760cc4da/conditions-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "c5f2918066292c6a51898cfe41270766", "sha256": "7c6fbf49abcbe8be3654b688591fc37c7545cd8c5bd4a93ad8caff661f485cc1" }, "downloads": -1, "filename": "conditions-0.2.0.tar.gz", "has_sig": false, "md5_digest": "c5f2918066292c6a51898cfe41270766", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19319, "upload_time": "2017-01-16T06:05:19", "url": "https://files.pythonhosted.org/packages/40/06/172bf14832fea13aee9e9d530432ae5da471a152a0330f29e1caae5230f5/conditions-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c5f2918066292c6a51898cfe41270766", "sha256": "7c6fbf49abcbe8be3654b688591fc37c7545cd8c5bd4a93ad8caff661f485cc1" }, "downloads": -1, "filename": "conditions-0.2.0.tar.gz", "has_sig": false, "md5_digest": "c5f2918066292c6a51898cfe41270766", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19319, "upload_time": "2017-01-16T06:05:19", "url": "https://files.pythonhosted.org/packages/40/06/172bf14832fea13aee9e9d530432ae5da471a152a0330f29e1caae5230f5/conditions-0.2.0.tar.gz" } ] }