noattr


Namenoattr JSON
Version 0.0.9 PyPI version JSON
download
home_pagehttps://github.com/elapouya/noattr
SummaryTo avoid NoneType AttributeError exception on chained attributes
upload_time2020-10-06 08:44:32
maintainer
docs_urlNone
authorEric Lapouyade
requires_python
licenseLGPL 2.1
keywords attribute attrdict
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
======
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"
}
        
Elapsed time: 0.02425s