======
NoAttr
======
When accessing an object with chained attributes, ::
info = obj.a.b.c.d or 'Unknown'
naïvely this will fail as soon as one of the intermediate attributes returns ``None``: ::
>>> obj.a
None
>>> obj.a.b.c.
AttributeError: 'NoneType' object has no attribute 'b'
*NoAttr* gives you a way around this in cases where a series of ``None`` checks would be too much effort and result in complex code.
Instead of returning ``None``, you want to return an instance of ``NoAttr``, which will caused hierarchical attribute accesses to keep returning ``NoAttr`` until the end of the chain ::
>>> from noattr import NoAttr
>>> obj = NoAttr
>>> obj.a
NoAttr
>>> obj.a.b.c.d
NoAttr
*NoAttr* behaves as a "falsy" value, meaning that it can stand for ``None``, ``False``, ``0``, ``''``, ``[]`` or ``{}``, depending on context. Here are some examples: ::
>>> obj.a
NoAttr
>>> obj.a.b.c.d or 'Unknown' # behaves like a falsy value
'Unknown'
>>> for i in obj.a.b.c.d: # behaves like an enumerable that does not yield a value
... print(i)
(no output)
>>> len(obj.a.b.c.d) # behaves like an empty collection
0
>>> obj.a.b.c.d + 1 # behaves like a 0
1
>>> obj.a.b.c.d.anyfunc() # behaves like a callable
NoAttr
However, for ``ljust()``, ``rjust()``, ``rfind()``, ``find()``, ``rindex()``, ``index()``, and ``count()``, *NoAttr* is seen as a single whitespace character (``' '``) to preserve the expected behavior of these methods: ::
>>> obj.a.b.c.d.ljust(3)
' '
Installation
############
$ ``pip install noattr``
News
====
0.0.8 (2018-08-24)
------------------
__iter__() now returns an empty iter
0.0.7 (2018-08-21)
------------------
Update code for python3 compatibility
0.0.6 (2016-03-11)
------------------
remove __or__ and __rshift__ definition for python_textops
0.0.5 (2015-10-13)
------------------
add as_list property
0.0.4 (2015-08-19)
------------------
add __setattr__ to avoid any modification
0.0.3 (2015-07-27)
------------------
First official version
Raw data
{
"_id": null,
"home_page": "https://github.com/elapouya/noattr",
"name": "noattr",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "attribute,AttrDict",
"author": "Eric Lapouyade",
"author_email": "elapouya@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/2d/5a/67861635b4331f2192438741232e8ac7e3b69b0a4cc1bd352d52c2544413/noattr-0.0.9.tar.gz",
"platform": "",
"description": "\n======\nNoAttr\n======\n\nWhen accessing an object with chained attributes, ::\n\n info = obj.a.b.c.d or 'Unknown'\n\nna\u00efvely this will fail as soon as one of the intermediate attributes returns ``None``: ::\n\n >>> obj.a \n None\n\n >>> obj.a.b.c.\n AttributeError: 'NoneType' object has no attribute 'b'\n\n*NoAttr* gives you a way around this in cases where a series of ``None`` checks would be too much effort and result in complex code. \nInstead of returning ``None``, you want to return an instance of ``NoAttr``, which will caused hierarchical attribute accesses to keep returning ``NoAttr`` until the end of the chain ::\n\n >>> from noattr import NoAttr\n >>> obj = NoAttr\n\n >>> obj.a\n NoAttr\n\n >>> obj.a.b.c.d\n NoAttr\n\n*NoAttr* behaves as a \"falsy\" value, meaning that it can stand for ``None``, ``False``, ``0``, ``''``, ``[]`` or ``{}``, depending on context. Here are some examples: ::\n\n >>> obj.a\n NoAttr\n\n >>> obj.a.b.c.d or 'Unknown' # behaves like a falsy value\n 'Unknown'\n\n >>> for i in obj.a.b.c.d: # behaves like an enumerable that does not yield a value\n ... print(i)\n (no output)\n\n >>> len(obj.a.b.c.d) # behaves like an empty collection\n 0\n\n >>> obj.a.b.c.d + 1 # behaves like a 0\n 1\n\n >>> obj.a.b.c.d.anyfunc() # behaves like a callable\n NoAttr\n\nHowever, for ``ljust()``, ``rjust()``, ``rfind()``, ``find()``, ``rindex()``, ``index()``, and ``count()``, *NoAttr* is seen as a single whitespace character (``' '``) to preserve the expected behavior of these methods: ::\n\n >>> obj.a.b.c.d.ljust(3)\n ' '\n\nInstallation\n############\n\n$ ``pip install noattr``\n\n\nNews\n====\n0.0.8 (2018-08-24)\n------------------\n__iter__() now returns an empty iter\n\n0.0.7 (2018-08-21)\n------------------\nUpdate code for python3 compatibility\n\n0.0.6 (2016-03-11)\n------------------\nremove __or__ and __rshift__ definition for python_textops\n\n0.0.5 (2015-10-13)\n------------------\nadd as_list property\n\n0.0.4 (2015-08-19)\n------------------\nadd __setattr__ to avoid any modification\n\n0.0.3 (2015-07-27)\n------------------\nFirst official version\n\n\n\n",
"bugtrack_url": null,
"license": "LGPL 2.1",
"summary": "To avoid NoneType AttributeError exception on chained attributes",
"version": "0.0.9",
"split_keywords": [
"attribute",
"attrdict"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "ad095398c96c755aefbef6b3d09ef88b79fbbc4131021095343ea7e0c2a7e3c2",
"md5": "a0cee82752008e5c85a4bc35e0e13ef7",
"sha256": "75660b845a4727982529764f02133f688ac5ca01d1469e696fea7b4901dc1904"
},
"downloads": -1,
"filename": "noattr-0.0.9-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a0cee82752008e5c85a4bc35e0e13ef7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 4849,
"upload_time": "2020-10-06T08:44:30",
"upload_time_iso_8601": "2020-10-06T08:44:30.747657Z",
"url": "https://files.pythonhosted.org/packages/ad/09/5398c96c755aefbef6b3d09ef88b79fbbc4131021095343ea7e0c2a7e3c2/noattr-0.0.9-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2d5a67861635b4331f2192438741232e8ac7e3b69b0a4cc1bd352d52c2544413",
"md5": "5ce27264964be8b6eca226e672cffb85",
"sha256": "1d65d4134327fa3f921bdae02326c8784383c4262864e2f5e57dca6ae1999b4b"
},
"downloads": -1,
"filename": "noattr-0.0.9.tar.gz",
"has_sig": false,
"md5_digest": "5ce27264964be8b6eca226e672cffb85",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 3305,
"upload_time": "2020-10-06T08:44:32",
"upload_time_iso_8601": "2020-10-06T08:44:32.030359Z",
"url": "https://files.pythonhosted.org/packages/2d/5a/67861635b4331f2192438741232e8ac7e3b69b0a4cc1bd352d52c2544413/noattr-0.0.9.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2020-10-06 08:44:32",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "elapouya",
"github_project": "noattr",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "noattr"
}