{ "info": { "author": "pohmelie", "author_email": "multisosnooley@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Programming Language :: Python :: 3" ], "description": "[![travis](https://img.shields.io/travis/pohmelie/skin.svg)](https://travis-ci.org/pohmelie/skin)\n[![coveralls](https://img.shields.io/coveralls/pohmelie/skin.svg)](https://coveralls.io/github/pohmelie/skin)\n[![pypi](https://img.shields.io/pypi/v/skin.svg)](https://pypi.python.org/pypi/skin)\n\n# Skin\nGetitem-objects \u00abskin\u00bb for attribute-like access.\n\n## Reason\n[addict](https://github.com/mewwts/addict), [python-box](https://github.com/cdgriffith/Box), [tri.struct](https://github.com/TriOptima/tri.struct), [dotmap](https://github.com/drgrib/dotmap), [ddict](https://github.com/rbehzadan/ddict), [easydict](https://github.com/makinacorpus/easydict) do not respect `dict` reference transparency.\n### addict\n``` python\n>>> from addict import Dict\n>>> original = {\"foo\": [1, 2, 3]}\n>>> d = Dict(original)\n>>> d.foo\n[1, 2, 3]\n>>> type(d.foo)\n\n>>> d.foo.append(4)\n>>> original\n{'foo': [1, 2, 3]}\n>>> d.foo\n[1, 2, 3, 4]\n>>>\n```\n### python-box\n``` python\n>>> from box import Box\n>>> original = {\"foo\": [1, 2, 3]}\n>>> b = Box(original)\n>>> b.foo\n\n>>> type(b.foo)\n\n>>> b.foo.append(4)\n>>> original\n{'foo': [1, 2, 3]}\n>>> b.foo\n\n>>>\n```\n### skin\n``` python\n>>> from skin import Skin\n>>> original = {\"foo\": [1, 2, 3]}\n>>> s = Skin(original)\n>>> s.foo\nSkin([1, 2, 3])\n>>> type(s.foo)\n\n>>> type(s.foo.value)\n\n>>> s.foo.value is original[\"foo\"]\nTrue\n>>> s.foo.append(4)\n>>> original\n{'foo': [1, 2, 3, 4]}\n>>>\n```\n# Similar projects\n* [addict](https://github.com/mewwts/addict)\n* [python-box](https://github.com/cdgriffith/Box)\n* [tri.struct](https://github.com/TriOptima/tri.struct)\n* [dotmap](https://github.com/drgrib/dotmap)\n* [ddict](https://github.com/rbehzadan/ddict)\n* [easydict](https://github.com/makinacorpus/easydict)\n* [dot_access](https://github.com/kootenpv/dot_access)\n\nAnd much more, since some of them are python 2 only.\n\n# Benchmark\n\n||Skin (skin)|Dict (addict)|DotMap (dotmap)|DotAccessDict (ddict)|Box (box)|EasyDict (easydict)|Dot (dot_access)|dict (builtins)|\n|:---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n|Create from `dict`|4.0x|37.0x|45.5x|37.1x|19.0x|44.6x|4.2x|1.0x|\n|Create from key-word arguments|-|11.1x|6.4x|9.4x|16.3x|11.7x|-|1.0x|\n|Get exist element (attribute access)|33.6x|7.7x|7.1x|6.5x|132.4x|1.0x|25.4x|-|\n|Get exist element (item access)|31.1x|5.5x|3.7x|2.0x|154.1x|2.1x|26.8x|1.0x|\n|Get non-exist element (attribute access)|1.8x|1.0x|1.4x|1.2x|-|-|1.3x|-|\n|Get non-exist element (item access)|1.6x|1.0x|1.4x|-|-|-|1.2x|-|\n|Set exist element (attribute access)|10.6x|3.0x|2.3x|2.5x|47.7x|1.0x|-|-|\n|Set exist element (item access)|29.0x|6.7x|3.9x|4.2x|164.6x|4.6x|-|1.0x|\n|Set non-exist element (attribute access)|1.6x|1.3x|1.0x|1.0x|-|-|-|-|\n|Set non-exist element (item access)|1.5x|1.3x|1.0x|-|-|-|-|-|\n|Support `items` iteration|-|2.9x|3.8x|2.7x|40.5x|1.0x|-|-|\n|Support `values` iteration|-|3.9x|4.2x|3.6x|59.3x|1.0x|-|-|\n|Support `len`|13.9x|4.7x|4.3x|4.1x|80.5x|1.0x|-|-|\n|Support `copy`|1.3x|1.0x|-|-|-|-|-|-|\n|Support `deepcopy`|2.1x|1.1x|1.0x|-|3.8x|1.6x|-|-|\n|Wrapped modification affect original|1.0x|-|-|-|-|-|-|-|\n|Original modification affect wrapped|1.3x|-|-|-|-|-|1.0x|-|\n|`defaultdict` as original|1.0x|-|-|-|-|-|-|-|\n|Non-dict as original|1.3x|-|-|-|-|-|1.0x|-|\n\n`items` and `values` support mean that values of iteration will be wrapped too.\n\n# Documentation\n``` python\nSkin(value=DEFAULT_VALUE, *, allowed=ANY, forbidden=FORBIDDEN)\n```\n* value \u2014 any object with `__getitem__` method (default: `dict`).\n* allowed \u2014 tuple of allowed types to wrap or `skin.ANY` for all types allowed (default: `skin.ANY`)\n* forbidden \u2014 tuple of forbidden types to wrap (default: `(str, bytes, bytearray, memoryview, range)`)\n\nWhat is `allowed` and `forbidden`?\n\nSince skin target is not to recreate containers there should be a rule to determine is object container or endpoint-node. Some objects (listed above as `forbidden`) have `__getitem__` method, but wont act like containers.\n\nExample:\nYou have original dictionary `{\"foo\": \"bar\"}`, and you expect from skin that `Skin({\"foo\": \"bar\"}).foo` is `\"bar\"` string, not skin wrapper. But, `str`, `bytes`, etc. have `__getitiem__` method. That is why there is `allowed` and `forbidden` tuples. I hope defaults are good enough for 99% usecases.\nIn general: if `value` have no `__getitem__` or not allowed or forbidden you will get `SkinValueError` exception, which skin catches to determine if object can be wrapped.\n\n**Skin class have only one accessible attribute: `value` \u2014 original object, which skin wraps** :tada:\n\nSkin supports both \"item\" and \"attribute\" notations:\n``` python\n>>> s = Skin({\"foo\": \"bar\"})\n>>> s.foo is s[\"foo\"]\nTrue\n>>>\n```\nBut, in case of nested containers:\n``` python\n>>> s = Skin({\"foo\": {\"bar\": \"baz\"}})\n>>> s.foo is s[\"foo\"]\nFalse\n>>> s.foo.value is s[\"foo\"].value\nTrue\n>>>\n```\nBoth objects `s.foo` and `s[\"foo\"]` is instances of `Skin`, but since they are created dynamicaly they are not the same object.\n\nSkin use strict order to find \"items\":\n* in case of attribute access:\n * skin attribute\n * value attribute\n * value item\n * orphan item\n* in case of item access:\n * value item\n * orphan item\n\nOrphan item is just naming for item, which is not yet set. Example:\n``` python\n>>> s = Skin()\n>>> s.foo.bar\nSkin({})\n>>> s\nSkin({})\n>>>\n```\n\nAs you can see there is no \"foo\" or \"bar\" items. But in case of setting:\n``` python\n>>> s = Skin()\n>>> s.foo.bar = \"baz\"\n>>> s\nSkin({'foo': {'bar': 'baz'}})\n>>>\n```\nSince skin is just wrapper, which do not recreate container you can use any object with `__getitem__`:\n``` python\n>>> import collections\n>>> s = Skin(collections.defaultdict(list))\n>>> s.foo.append(1)\n>>> s\nSkin(defaultdict(, {'foo': [1]}))\n>>>\n```\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/pohmelie/skin", "keywords": "", "license": "Apache 2", "maintainer": "", "maintainer_email": "", "name": "skin", "package_url": "https://pypi.org/project/skin/", "platform": "", "project_url": "https://pypi.org/project/skin/", "project_urls": { "Homepage": "https://github.com/pohmelie/skin" }, "release_url": "https://pypi.org/project/skin/0.0.7/", "requires_dist": null, "requires_python": ">= 3.4", "summary": "Getitem-objects \u00abskin\u00bb for attribute-like access", "version": "0.0.7" }, "last_serial": 4080294, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "2b4a1f07fe9a5ce30f6718f3c370982d", "sha256": "9f7ee80b9b4bf9b18b364400f26546906416bbafbac59f0d83958f83bc874381" }, "downloads": -1, "filename": "skin-0.0.1.tar.gz", "has_sig": false, "md5_digest": "2b4a1f07fe9a5ce30f6718f3c370982d", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 3054, "upload_time": "2017-11-26T00:52:32", "url": "https://files.pythonhosted.org/packages/ea/ec/c974292a50fe5453132af6d7e7d548c0dd325b8488b1ee2371da1fcaf8e9/skin-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "a0a2b2c203c56b3dd19413a517bdf06e", "sha256": "5fd2fd7873e23ea3f9526ad36c79419045af21f24c353491b6abad0a4584dbf3" }, "downloads": -1, "filename": "skin-0.0.2.tar.gz", "has_sig": false, "md5_digest": "a0a2b2c203c56b3dd19413a517bdf06e", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 3073, "upload_time": "2017-11-26T01:08:43", "url": "https://files.pythonhosted.org/packages/c1/a4/8775b5b6fb0e74ff748fa9144f3c8eb559dbad652dd2a0541b7589544e8c/skin-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "dba54c0bd3a3257a1863747816ca8652", "sha256": "58e28af632e09701afa5cb1c5e0ce754857326af11b9c809a9fb633432ce90c9" }, "downloads": -1, "filename": "skin-0.0.3.tar.gz", "has_sig": false, "md5_digest": "dba54c0bd3a3257a1863747816ca8652", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 4131, "upload_time": "2017-11-28T01:01:26", "url": "https://files.pythonhosted.org/packages/03/98/a2eaac8dc7b4cab8a1d02539401295ecea75290fe1e30dcdd60c08bedb42/skin-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "f1bd2f6fd292a357662f85574e5e1e97", "sha256": "15f2b9b2a2908339e04dd25269c030a4fa30c9ac620cb5f823b0b27fc804da98" }, "downloads": -1, "filename": "skin-0.0.4.tar.gz", "has_sig": false, "md5_digest": "f1bd2f6fd292a357662f85574e5e1e97", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 4095, "upload_time": "2017-11-28T01:11:48", "url": "https://files.pythonhosted.org/packages/78/de/71c1ee6437e97d077d6a617eb78df9f1c220a6a9242864c871a37bc2b01d/skin-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "26ad72a1dd1e6ea427685f115b084f5c", "sha256": "913eb5e4cf7f47b410606658e6920335ecb42d8121f10fd76ae25c409b9eaf94" }, "downloads": -1, "filename": "skin-0.0.5.tar.gz", "has_sig": false, "md5_digest": "26ad72a1dd1e6ea427685f115b084f5c", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 4334, "upload_time": "2017-11-29T21:58:45", "url": "https://files.pythonhosted.org/packages/f2/02/83b563430dedea7b4bbf904088a54e6ad4dd1efb1ca1f12a39896270de8d/skin-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "7cf3f544e50b58646bd3870e48c77e35", "sha256": "f82758fd14ea337a0f8fc99cec951fdf432383aa845cf96b2a679f128b4b010a" }, "downloads": -1, "filename": "skin-0.0.6.tar.gz", "has_sig": false, "md5_digest": "7cf3f544e50b58646bd3870e48c77e35", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 4410, "upload_time": "2018-01-14T00:58:09", "url": "https://files.pythonhosted.org/packages/0e/50/9a64c996446ef36f561932176894fd83ae8529ba81a740bf6f8c0d2b4138/skin-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "8d91533dc6ac1d90eb11ae05f6bb9f5e", "sha256": "b4e17457630273570c44842bf192db792ead285dac76677345829e2994139030" }, "downloads": -1, "filename": "skin-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "8d91533dc6ac1d90eb11ae05f6bb9f5e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.4", "size": 4265, "upload_time": "2018-07-19T00:41:06", "url": "https://files.pythonhosted.org/packages/e0/c1/138d32d10f144293d6acb935f1f0a6b7f7ab2cf3d3c50697be2468dad162/skin-0.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bfb5e152d73bb2abdbf4f15531d86db2", "sha256": "8222f4a4f0cc237132c97d53179c60adfb28da91cb7a189c982dd8bf2e018396" }, "downloads": -1, "filename": "skin-0.0.7.tar.gz", "has_sig": false, "md5_digest": "bfb5e152d73bb2abdbf4f15531d86db2", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 4506, "upload_time": "2018-07-19T00:41:07", "url": "https://files.pythonhosted.org/packages/5e/f5/60f7fceae7ac0d0ba226ce7c01f5c8523e1c3ad60d2d2386807f533e0121/skin-0.0.7.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "8d91533dc6ac1d90eb11ae05f6bb9f5e", "sha256": "b4e17457630273570c44842bf192db792ead285dac76677345829e2994139030" }, "downloads": -1, "filename": "skin-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "8d91533dc6ac1d90eb11ae05f6bb9f5e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">= 3.4", "size": 4265, "upload_time": "2018-07-19T00:41:06", "url": "https://files.pythonhosted.org/packages/e0/c1/138d32d10f144293d6acb935f1f0a6b7f7ab2cf3d3c50697be2468dad162/skin-0.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bfb5e152d73bb2abdbf4f15531d86db2", "sha256": "8222f4a4f0cc237132c97d53179c60adfb28da91cb7a189c982dd8bf2e018396" }, "downloads": -1, "filename": "skin-0.0.7.tar.gz", "has_sig": false, "md5_digest": "bfb5e152d73bb2abdbf4f15531d86db2", "packagetype": "sdist", "python_version": "source", "requires_python": ">= 3.4", "size": 4506, "upload_time": "2018-07-19T00:41:07", "url": "https://files.pythonhosted.org/packages/5e/f5/60f7fceae7ac0d0ba226ce7c01f5c8523e1c3ad60d2d2386807f533e0121/skin-0.0.7.tar.gz" } ] }