===============================
PyMaybe
===============================
.. image:: https://travis-ci.org/ekampf/pymaybe.svg?branch=master
:target: https://travis-ci.org/ekampf/pymaybe
.. image:: https://coveralls.io/repos/ekampf/pymaybe/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/ekampf/pymaybe?branch=master
.. image:: https://img.shields.io/pypi/v/pymaybe.svg
:target: https://pypi.python.org/pypi/pymaybe
A Python implementation of the Maybe pattern.
Installation
------------
::
pip install pymaybe
Getting Started
---------------
::
from pymaybe import maybe
first_name = maybe(deep_hash)['account']['user_profile']['first_name'].or_else("<unknown>")
Documentation
-------------
Maybe monad is a programming pattern that allows to treat None values that same way as non-none values.
This is done by wrapping the value, which may or may not be None to, a wrapper class.
The implementation includes two classes: *Maybe* and *Something*.
*Something* represents a value while *Nothing* represents a None value.
There's also a method *maybe* which wraps a regular value and and returns *Something* or *Nothing* instance.
::
>>> maybe("I'm a value")
"I'm a value"
>>> maybe(None);
None
Both *Something* and *Nothing* implement 4 methods allowing you to test their real value: *is_some*, *is_none*, *get* and *or_else*
::
>>> maybe("I'm a value").is_some()
True
>>> maybe("I'm a value").is_none()
False
>>> maybe(None).is_some()
False
>>> maybe(None).is_none()
True
>>> maybe("I'm a value").get()
"I'm a value"
>>> maybe("I'm a value").or_else(lambda: "No value")
"I'm a value"
>>> maybe(None).get()
Traceback (most recent call last):
...
Exception: No such element
>>> maybe(None).or_else(lambda: "value")
'value'
>>> maybe(None).or_else("value")
'value'
In addition, *Something* and *Nothing* implement the Python magic methods allowing you to treat them as dictionaries:
::
>>> nested_dict = maybe(nested_dict)
>>> nested_dict['store']['name']
'MyStore'
>>> nested_dict['store']['address']
None
>>> nested_dict['store']['address']['street'].or_else('No Address Specified')
'No Address Specified'
All other method calls on *Something* are forwarded to its real *value*:
::
>>> maybe('VALUE').lower()
'value'
>>> maybe(None).invalid().method().or_else('unknwon')
'unknwon'
Examples & Use Cases
--------------------
The Maybe pattern helps you avoid nasty try..except blocks.
Consider the following code:
::
try:
url = rss.load_feeds()[0].url.domain
except (TypeError, IndexError, KeyError, AttributeError):
url = "planetpython.org"
With Maybe you could simply do:
::
url = maybe(rss).load_feeds()[0]['url'].domain.or_else("planetpython.org")
Getting the current logged in user's name.
Without maybe:
::
def get_user_zipcode():
address = getattr(request.user, 'address', None)
if address:
return getattr(address, 'zipcode', '')
return ''
With maybe:
::
def get_user_zipcode():
return maybe(request.user).address.zipcode.or_else('')
Further Reading
---------------
* `Option (Scala) <http://www.scala-lang.org/api/current/scala/Option.html>`_
* `Maybe (Java) <https://github.com/npryce/maybe-java>`_
* `Maybe pattern (Python recipe) <http://code.activestate.com/recipes/577248-maybe-pattern/>`_
* `Data.Maybe (Haskell) <http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html>`_
* `Maybe (Ruby) <https://github.com/bhb/maybe>`_
Copyright and License
---------------------
Copyright 2015 - `Eran Kampf <http://www.developerzen.com>`_
* Free software: BSD license
* Documentation: https://pymaybe.readthedocs.org.
* Code is hosted on `GitHub <http://www.github.com/ekampf/pymaybe>`_
History
-------
0.1.0 (2015-01-11)
---------------------
* First release on PyPI.
Raw data
{
"_id": null,
"home_page": "https://github.com/ekampf/pymaybe",
"name": "pymaybe",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "pymaybe",
"author": "Eran Kampf",
"author_email": "eran@ekampf.com",
"download_url": "https://files.pythonhosted.org/packages/fe/86/0bbefee601f7f5ce5fdd11ee59cbae36ce9cb48b96c44f960f38cbfe6d0a/pymaybe-0.1.6.tar.gz",
"platform": "UNKNOWN",
"description": "===============================\nPyMaybe\n===============================\n\n.. image:: https://travis-ci.org/ekampf/pymaybe.svg?branch=master\n :target: https://travis-ci.org/ekampf/pymaybe\n\n.. image:: https://coveralls.io/repos/ekampf/pymaybe/badge.svg?branch=master&service=github\n :target: https://coveralls.io/github/ekampf/pymaybe?branch=master\n\n.. image:: https://img.shields.io/pypi/v/pymaybe.svg\n :target: https://pypi.python.org/pypi/pymaybe\n\nA Python implementation of the Maybe pattern.\n\nInstallation\n------------\n\n::\n\n pip install pymaybe\n\nGetting Started\n---------------\n\n::\n\n from pymaybe import maybe\n first_name = maybe(deep_hash)['account']['user_profile']['first_name'].or_else(\"<unknown>\")\n\nDocumentation\n-------------\nMaybe monad is a programming pattern that allows to treat None values that same way as non-none values.\nThis is done by wrapping the value, which may or may not be None to, a wrapper class.\n\nThe implementation includes two classes: *Maybe* and *Something*.\n*Something* represents a value while *Nothing* represents a None value.\nThere's also a method *maybe* which wraps a regular value and and returns *Something* or *Nothing* instance.\n\n::\n\n >>> maybe(\"I'm a value\")\n \"I'm a value\"\n\n >>> maybe(None);\n None\n\nBoth *Something* and *Nothing* implement 4 methods allowing you to test their real value: *is_some*, *is_none*, *get* and *or_else*\n\n::\n\n >>> maybe(\"I'm a value\").is_some()\n True\n\n >>> maybe(\"I'm a value\").is_none()\n False\n\n >>> maybe(None).is_some()\n False\n\n >>> maybe(None).is_none()\n True\n\n >>> maybe(\"I'm a value\").get()\n \"I'm a value\"\n\n >>> maybe(\"I'm a value\").or_else(lambda: \"No value\")\n \"I'm a value\"\n\n >>> maybe(None).get()\n Traceback (most recent call last):\n ...\n Exception: No such element\n\n >>> maybe(None).or_else(lambda: \"value\")\n 'value'\n\n >>> maybe(None).or_else(\"value\")\n 'value'\n\nIn addition, *Something* and *Nothing* implement the Python magic methods allowing you to treat them as dictionaries:\n\n::\n >>> nested_dict = maybe(nested_dict)\n >>> nested_dict['store']['name']\n 'MyStore'\n\n >>> nested_dict['store']['address']\n None\n\n >>> nested_dict['store']['address']['street'].or_else('No Address Specified')\n 'No Address Specified'\n\nAll other method calls on *Something* are forwarded to its real *value*:\n\n::\n\n >>> maybe('VALUE').lower()\n 'value'\n\n >>> maybe(None).invalid().method().or_else('unknwon')\n 'unknwon'\n\nExamples & Use Cases\n--------------------\n\nThe Maybe pattern helps you avoid nasty try..except blocks.\nConsider the following code:\n\n::\n try:\n url = rss.load_feeds()[0].url.domain\n except (TypeError, IndexError, KeyError, AttributeError):\n url = \"planetpython.org\"\n\nWith Maybe you could simply do:\n\n::\n\n url = maybe(rss).load_feeds()[0]['url'].domain.or_else(\"planetpython.org\")\n\nGetting the current logged in user's name.\nWithout maybe:\n\n::\n\n def get_user_zipcode():\n address = getattr(request.user, 'address', None)\n if address:\n return getattr(address, 'zipcode', '')\n\n return ''\n\nWith maybe:\n\n::\n\n def get_user_zipcode():\n return maybe(request.user).address.zipcode.or_else('')\n\nFurther Reading\n---------------\n\n* `Option (Scala) <http://www.scala-lang.org/api/current/scala/Option.html>`_\n* `Maybe (Java) <https://github.com/npryce/maybe-java>`_\n* `Maybe pattern (Python recipe) <http://code.activestate.com/recipes/577248-maybe-pattern/>`_\n* `Data.Maybe (Haskell) <http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Maybe.html>`_\n* `Maybe (Ruby) <https://github.com/bhb/maybe>`_\n\nCopyright and License\n---------------------\nCopyright 2015 - `Eran Kampf <http://www.developerzen.com>`_\n\n* Free software: BSD license\n* Documentation: https://pymaybe.readthedocs.org.\n* Code is hosted on `GitHub <http://www.github.com/ekampf/pymaybe>`_\n\n\n\n\nHistory\n-------\n\n0.1.0 (2015-01-11)\n---------------------\n\n* First release on PyPI.",
"bugtrack_url": null,
"license": "BSD",
"summary": "A Python implementation of the Maybe pattern.",
"version": "0.1.6",
"split_keywords": [
"pymaybe"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "5e37221b3280109ea436700a996ec747",
"sha256": "01d0f71b98e1c155ecfecd9db44ce49f37ae374b5cb8f1d27c0ee00c3d7aa4dd"
},
"downloads": -1,
"filename": "pymaybe-0.1.6-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "5e37221b3280109ea436700a996ec747",
"packagetype": "bdist_wheel",
"python_version": "2.7",
"requires_python": null,
"size": 7826,
"upload_time": "2015-09-28T21:23:53",
"upload_time_iso_8601": "2015-09-28T21:23:53.940342Z",
"url": "https://files.pythonhosted.org/packages/83/f8/3bd91975bfbed25e453589d079cbf4f8f0b44a9cf6a82bfebbd69506b060/pymaybe-0.1.6-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "30c7a1af361f327abb0e58191072ae01",
"sha256": "77ed1602e1b9e8b05dccd0d84891ede4ee2004728170e52af7f9c08d4c62378c"
},
"downloads": -1,
"filename": "pymaybe-0.1.6.tar.gz",
"has_sig": false,
"md5_digest": "30c7a1af361f327abb0e58191072ae01",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16670,
"upload_time": "2015-09-28T21:23:47",
"upload_time_iso_8601": "2015-09-28T21:23:47.688354Z",
"url": "https://files.pythonhosted.org/packages/fe/86/0bbefee601f7f5ce5fdd11ee59cbae36ce9cb48b96c44f960f38cbfe6d0a/pymaybe-0.1.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2015-09-28 21:23:47",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "ekampf",
"github_project": "pymaybe",
"travis_ci": true,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "wheel",
"specs": [
[
"==",
"0.23.0"
]
]
},
{
"name": "tox",
"specs": []
},
{
"name": "coverage",
"specs": []
},
{
"name": "flake8",
"specs": []
},
{
"name": "Sphinx",
"specs": []
}
],
"tox": true,
"lcname": "pymaybe"
}