{ "info": { "author": "Tobias Hermann", "author_email": "editgym@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "![logo](https://github.com/Dobiasd/undictify/raw/master/logo/undictify.png)\n\n[![Build Status](https://travis-ci.org/Dobiasd/undictify.svg?branch=master)][travis]\n[![(License MIT 1.0)](https://img.shields.io/badge/license-MIT%201.0-blue.svg)][license]\n\n[travis]: https://travis-ci.org/Dobiasd/undictify\n[license]: LICENSE\n\n\nundictify\n=========\n**Python library providing type-checked function calls at runtime**\n\n\nTable of contents\n-----------------\n * [Introduction](#introduction)\n * [Use case: JSON deserialization](#use-case-json-deserialization)\n * [Details](#details)\n * [Requirements and Installation](#requirements-and-installation)\n\n\nIntroduction\n------------\nLet's start with a toy example:\n```python\ndef times_two(value):\n return 2 * value\n\nvalue = 3\nresult = times_two(value)\nprint(f'{value} * 2 == {result}')\n```\n\nThis is fine, it outputs `output: 3 * 2 = 6`.\nBut what if `value` accidentally is `'3'` instead of `3`?\nThe output will become `output: 3 * 2 = 33`, which *might* not be desired.\n\nSo you add something like\n```python\nif not isinstance(value, int):\n raise TypeError(...)\n```\nto `times_two`. This will raise an `TypeError` instead, which is better.\nBut you still only recognize the mistake when actually running the code.\nCatching it earlier in the development process might be better.\nLuckily Python allows to opt-in for static typing by offering [type annotations](https://docs.python.org/3/library/typing.html).\nSo you add them and [`mypy`](http://mypy-lang.org/) (or your IDE) will tell you about the problem early.\n```python\ndef times_two(value: int) -> int:\n return 2 * value\n\nvalue = '3'\nresult = times_two(value) # error: Argument 1 to \"times_two\"\n # has incompatible type \"str\"; expected \"int\"\nprint(f'{value} * 2 == {result}')\n```\n\nBut you may get into a situation in which there is no useful static type information,\nbecause of values:\n- coming from external non-typed functions (so actually they are of type `Any`)\n- were produced by a (rogue) function that returns different types depending on some internal decision (`Union[T, V]`)\n- being provided as a `Dict[str, Any]`\n- etc.\n\n```python\ndef times_two(value: int) -> int:\n return 2 * value\n\ndef get_value() -> Any:\n return '3'\n\nvalue = get_value()\nresult = times_two(value)\nprint(f'{value} * 2 == {result}')\n```\n\nAt least with the [appropriate settings](https://stackoverflow.com/questions/51696060/how-to-make-mypy-complain-about-assigning-an-any-to-an-int-part-2/51696314#51696314), `mypy` should dutifully complain, and now you're left with two options:\n- Drop type-checking (for example by adding ` # type: ignore` to the end of the `result = times_two(value)` line): This however catapults you back into the insane world where `2 * 3 == 33`.\n- You manually add type checks before the call (or inside of `times_two`) like `if not isinstance(value, int):`: This of course does not provide static type checking (because of the dynamic nature of `value`), but at least guarantees sane runtime behavior. \n\nBut the process of writing that boilerplate validation code can become quite cumbersome if you have multiple parameters/functions to check.\nAlso it is not very [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) since you already have the needed type information in our function signature and you just duplicated it in the check condition.\n\nThis is where undictify comes into play. Simply decorate your `times_two` function with `@type_checked_call()`:\n```python\nfrom undictify import type_checked_call\n\n@type_checked_call()\ndef times_two(value: int) -> int:\n return 2 * value\n```\n\nAnd the arguments of `times_two` will be type-checked with every call at runtime automatically. A `TypeError` will be raised if needed. \n\nThis concept of **runtime type-checks of function calls derived from static type annotations** is quite simple,\nhowever it is very powerful and brings some highly convenient consequences with it.\n\n\nUse case: JSON deserialization\n------------------------------\n\nImagine your application receives a JSON string representing an entity you need to handle:\n\n```python\ntobias_json = '''\n {\n \"id\": 1,\n \"name\": \"Tobias\",\n \"heart\": {\n \"weight_in_kg\": 0.31,\n \"pulse_at_rest\": 52\n },\n \"friend_ids\": [2, 3, 4, 5]\n }'''\n\ntobias = json.loads(tobias_json)\n```\n\nNow you start to work with it. Somewhere deep in your business logic you have:\n```python\nname_length = len(tobias['name'])\n```\nBut that's only fine if the original JSON string was well-behaved.\nIf it had `\"name\": 4,` in it, you would get:\n```\n name_length = len(tobias['name'])\nTypeError: object of type 'int' has no len()\n```\nat runtime, which is not nice. So you start to manually add type checking:\n```python\nif isinstance(tobias['name'], str):\n name_length = len(tobias['name'])\nelse:\n # todo: handle the situation somehow\n```\n\nYou quickly realize that you need to separate concerns better,\nin that case the business logic and the input data validation.\n\nSo you start to do all checks directly after receiving the data:\n```python\ntobias = json.loads(...\nif isinstance(tobias['id'], int):\n ...\nif isinstance(tobias['name'], str):\n ...\nif isinstance(... # *yawn*\n```\n\nand then transfer it into a type-safe class instance:\n```python\nclass Heart(NamedTuple):\n weight_in_kg: float\n pulse_at_rest: int\n\nclass Human(NamedTuple):\n id: int\n name: str\n nick: Optional[str]\n heart: Heart\n friend_ids: List[int]\n```\n\nHaving the safety provided by the static type annotations (and probably checking your code with `mypy`) is a great because of all the:\n- bugs that don't make it into PROD\n- manual type checks (and matching unit tests) that you don't have to write\n- help your IDE can now offer\n- better understanding people get when reading your code\n- easier and more confident refactorings\n\nBut again, writing all that boilerplate code for data validation is tedious (and not DRY).\n\nSo you decide to use a library that does JSON schema validation for you.\nBut now you have to manually adjust the schema every time your entity structure changes, which still is not DRY, and thus also brings with it all the typical possibilities to make mistakes.\n\nUndictify can help here too!\nAnnotate the classes `@type_checked_constructor` and their constructors will be wrapped in type-checked calls.\n```python\n@type_checked_constructor()\nclass Heart(NamedTuple):\n ...\n@type_checked_constructor()\nclass Human(NamedTuple):\n ...\n```\n\n(They do not need to be derived from `NamedTuple`. A normal class with a custom `__init__` function or a `@dataclass` works too. For data classes just make sure to use `@type_checked_constructor()` above the `@dataclass`, not below.)\n\nUndictify will type-check the construction of objects of type `Heart` and `Human` automatically.\n(This works for normal classes with a manually written `__init__` function too.\nYou just need to provide the type annotations to its parameters.) So you can use the usual dictionary unpacking syntax, to safely convert your untyped dictionary (i.e., `Dict[str, Any]`) resulting from the JSON string into your statically typed class:\n\n```python\ntobias = Human(**json.loads(tobias_json))\n```\n\n(Btw this application is the origin of the name of this library.)\n\nIt throws exceptions with meaningful details in their associated values in case of errors like:\n- missing a field\n- a field having the wrong type\n- etc.\n\nIt also supports optional values being omitted instead of being `None` explicitly (as shown in the example with the `nick` field).\n\n\nDetails\n-------\n\nSometimes, e.g., in case of unpacking a dictionary resulting from a JSON string,\nyou might want to just skip the fields in the dictionary that your function / constructor does not take as a parameter.\nFor these cases undictify provides `@type_checked_call(skip=True)`.\n\nIt also supports valid type conversions via `@type_checked_call(convert=True)`,\nwhich might for example come in handy when processing the arguments of an HTTP request you receive for example in a `get` handler of a `flask_restful.Resource` class:\n```python\n@type_checked_call(convert=True)\ndef target_function(some_int: int, some_str: str)\n\nclass WebController(Resource):\n def get(self) -> Any:\n # request.args is something like {\"some_int\": \"4\", \"some_str\": \"hi\"}\n result = target_function(**flask.request.args)\n```\n\nThe values in the `MultiDict` `request.args` are all strings, but the logic behind `@type_checked_call(convert=True)` tries to convert them into the desired target types with reasonable exceptions in case the conversion is not possible.\n\nThis way a request to `http://.../foo?some_int=4&some_str=hi` would be handled normally,\nbut `http://.../foo?some_int=four&some_str=hi` would raise an appropriate `TypeError`.\n\nAdditional flexibility is offered for cases in which you would like to not type-check all calls of a specific function / class constructor, but only some. You can use `type_checked_call()` at call site instead of adding the annotation for those:\n\n```python\nfrom undictify import type_checked_call\n\ndef times_two(value: int) -> int:\n return 2 * value\n\nvalue: Any = '3'\nresutl = type_checked_call()(times_two)(value)\n```\n\n\nRequirements and Installation\n-----------------------------\n\nYou need Python 3.6.5 or higher.\n\n```bash\npython3 -m pip install undictify\n```\n\nOr, if you like to use latest version from this repository:\n```bash\ngit clone https://github.com/Dobiasd/undictify\ncd undictify\npython3 -m pip install .\n```\n\n\nLicense\n-------\nDistributed under the MIT License.\n(See accompanying file [`LICENSE`](https://github.com/Dobiasd/undictify/blob/master/LICENSE) or at\n[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT))\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/Dobiasd/undictify", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "undictify", "package_url": "https://pypi.org/project/undictify/", "platform": "", "project_url": "https://pypi.org/project/undictify/", "project_urls": { "Homepage": "http://github.com/Dobiasd/undictify" }, "release_url": "https://pypi.org/project/undictify/0.6.5/", "requires_dist": null, "requires_python": "", "summary": "Type-checked function calls at runtime", "version": "0.6.5" }, "last_serial": 5301012, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "527fd575405cab4ad2cbf723414d1143", "sha256": "c4a653c3ff657b7ad1fd42c7c253eac18d3c70a69c3aa09090fc1bc1f2da5655" }, "downloads": -1, "filename": "undictify-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "527fd575405cab4ad2cbf723414d1143", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7426, "upload_time": "2018-08-02T21:27:51", "url": "https://files.pythonhosted.org/packages/0d/98/84cad4d67c3345c0a13de0c2f969920f737144c13da1bff7b53507354bb1/undictify-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6dc43b467e1f227c9d6b3e72c14101be", "sha256": "bba182d3f0c59acdf517830f9969f92d32c9c73699674c901f15c40e4a6c2726" }, "downloads": -1, "filename": "undictify-0.1.0.tar.gz", "has_sig": false, "md5_digest": "6dc43b467e1f227c9d6b3e72c14101be", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9521, "upload_time": "2018-08-02T21:27:52", "url": "https://files.pythonhosted.org/packages/2b/79/a56d20f1826c2bdfda321691f70a9db962e4546a95ea4b9b6435cd1b39ef/undictify-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "88782e0bd6e30002d4e5068eead4fb82", "sha256": "59a6f086f0c07a2cca60c7559b15f2dde276c40fe88d5e166c5c3a91b34efe13" }, "downloads": -1, "filename": "undictify-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "88782e0bd6e30002d4e5068eead4fb82", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7569, "upload_time": "2018-08-03T07:21:27", "url": "https://files.pythonhosted.org/packages/b6/03/8ed37f383aff675175467f39b427aaebde69aaa8230f92d21c960caae2b5/undictify-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5de0062dc19580a449bad04f9483e6b1", "sha256": "07808b7748309b0665e16c733608e4b8e774720e0e002fdeda1d6fe3be7f7164" }, "downloads": -1, "filename": "undictify-0.1.1.tar.gz", "has_sig": false, "md5_digest": "5de0062dc19580a449bad04f9483e6b1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9804, "upload_time": "2018-08-03T07:21:28", "url": "https://files.pythonhosted.org/packages/ea/61/10d60b24ce307266db1572ab8f7499ce8e503bc98145c92401d0557fb7f2/undictify-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "60e0dc0a2792282e70d2ce6b5ae04978", "sha256": "d9c874d9549c14a13d3ef9dd328b3fe6439df85330aeba2d1a8d524edc6c522b" }, "downloads": -1, "filename": "undictify-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "60e0dc0a2792282e70d2ce6b5ae04978", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11153, "upload_time": "2018-08-05T17:17:08", "url": "https://files.pythonhosted.org/packages/a2/3e/216c784423f6d55a596337ca3b57f8120e1e04a811671e69b01450f77530/undictify-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a1d9f1431c0f25bc5bc876fbb296e2e1", "sha256": "5dd81d2cad8679ece116be12a581a1decd3bf9393b926bf6031dfd221cae865d" }, "downloads": -1, "filename": "undictify-0.2.0.tar.gz", "has_sig": false, "md5_digest": "a1d9f1431c0f25bc5bc876fbb296e2e1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14806, "upload_time": "2018-08-05T17:17:10", "url": "https://files.pythonhosted.org/packages/17/97/7c153c7fe5c24604ee3dc7ab06506e25cabf3bd3c4643882da5cbb82f196/undictify-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "a9fb0f2f6ef2e0b2cc83c5ca926f6adc", "sha256": "b6bed47311665762eae291a6113a601b9dc7b140c24a02f3de277f708810a584" }, "downloads": -1, "filename": "undictify-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "a9fb0f2f6ef2e0b2cc83c5ca926f6adc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11392, "upload_time": "2018-08-05T19:49:01", "url": "https://files.pythonhosted.org/packages/69/94/f8d8d20d5c9c94e6a265dd61c45fa5ef74e9a88c9b648ddab65af308ef13/undictify-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bb318f96e3c995bd0d9b27f2100ebb31", "sha256": "3afb4dc7c36891f6052a1b0c6c732479a2eb809a80af826cd9d55f5b31949f38" }, "downloads": -1, "filename": "undictify-0.2.1.tar.gz", "has_sig": false, "md5_digest": "bb318f96e3c995bd0d9b27f2100ebb31", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15080, "upload_time": "2018-08-05T19:49:03", "url": "https://files.pythonhosted.org/packages/07/66/fcbb057bf88560acb9e8bc055943dac4ef116754a3a33c1a38c08056388b/undictify-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "94450349366b83472ced2550b3dc6de3", "sha256": "00bc1c8f5137c310ed11bc148bb86e2f894b5a65ae3ed04a1bbf0b216b537a54" }, "downloads": -1, "filename": "undictify-0.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "94450349366b83472ced2550b3dc6de3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11497, "upload_time": "2018-08-06T08:13:33", "url": "https://files.pythonhosted.org/packages/e5/bf/905b06772db96a78cee0cc73bea7f65e259e2f279507a4307377be0d3299/undictify-0.2.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f54c23e3abc5fbe99497fc42d25c545c", "sha256": "f2e63ae23aa23aa45c01ddd46cf599ea7133b5fdc098161e1657c4c2c59da16a" }, "downloads": -1, "filename": "undictify-0.2.2.tar.gz", "has_sig": false, "md5_digest": "f54c23e3abc5fbe99497fc42d25c545c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15174, "upload_time": "2018-08-06T08:13:36", "url": "https://files.pythonhosted.org/packages/ea/7c/55851b1ae5581ca3db2b4cea3f561f0878956e7f574ca3feaddfafd6edc4/undictify-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "5b814c51242da3c712138177adae29cd", "sha256": "2f23b0748b604d4a47a05912f4b48b5127d8eb31cdea809db4e4c221f822be3b" }, "downloads": -1, "filename": "undictify-0.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "5b814c51242da3c712138177adae29cd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12119, "upload_time": "2018-08-06T12:49:38", "url": "https://files.pythonhosted.org/packages/06/a5/2baa5a083a66cfa6e832df71b8e4dcd882c5a4cf61a39723590eb1d3d76e/undictify-0.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c60525b88e293478d973e5ab32305928", "sha256": "cf0323d056db452f2c1c7b0ee059153ff56cd8c10f051028c149e90bf6697f56" }, "downloads": -1, "filename": "undictify-0.2.3.tar.gz", "has_sig": false, "md5_digest": "c60525b88e293478d973e5ab32305928", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15902, "upload_time": "2018-08-06T12:49:39", "url": "https://files.pythonhosted.org/packages/69/ca/f5d8bbe436740394d130641bbabbfa643aed178668229ea138d039ac7037/undictify-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "5c11d4084ede42341a073521191fbcdd", "sha256": "630bb320af484721a493c8b3b9eee181a8ffd76ea62af929b81acc38c370292d" }, "downloads": -1, "filename": "undictify-0.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "5c11d4084ede42341a073521191fbcdd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12384, "upload_time": "2018-08-06T14:47:39", "url": "https://files.pythonhosted.org/packages/9a/33/5869e8cae517282a2fe7d0e715955460a48ebb732931928ff8f88ecd6263/undictify-0.2.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "24c6ab22f69ad71e2ef4507254953440", "sha256": "dd3361517ece7698f0d31998346a1ba870ca9a9618263201613d9b09d7aa8a21" }, "downloads": -1, "filename": "undictify-0.2.4.tar.gz", "has_sig": false, "md5_digest": "24c6ab22f69ad71e2ef4507254953440", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16145, "upload_time": "2018-08-06T14:47:40", "url": "https://files.pythonhosted.org/packages/84/60/5a01ef1b1e3664153a2cd96e0b00d83f3c7d7d64db66875729b63073db46/undictify-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "4ba1377e7b3a1aeadcf1fc6a56e15fbe", "sha256": "7b682cda0439365c33be8bfc2e70252609f09cc5291a0b155797edb5f3bee408" }, "downloads": -1, "filename": "undictify-0.2.5-py3-none-any.whl", "has_sig": false, "md5_digest": "4ba1377e7b3a1aeadcf1fc6a56e15fbe", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 13023, "upload_time": "2018-08-08T06:14:41", "url": "https://files.pythonhosted.org/packages/d1/0d/c4cbce6dd28035bfdf0ec6f5e620728dfe29e62a0d5e86091ca1caabb5c1/undictify-0.2.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7df5e2c9838fb0da620d9b22aba17e33", "sha256": "4b18e8375144d4b0690d7cbee6770a223f2eb8deca1893d513ade9a18c2fdc02" }, "downloads": -1, "filename": "undictify-0.2.5.tar.gz", "has_sig": false, "md5_digest": "7df5e2c9838fb0da620d9b22aba17e33", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17201, "upload_time": "2018-08-08T06:14:42", "url": "https://files.pythonhosted.org/packages/fc/4e/3c8b3d0e3a196dcf95a82527a4be743c26b3e641cbf47cf159a355272912/undictify-0.2.5.tar.gz" } ], "0.2.6": [ { "comment_text": "", "digests": { "md5": "2e4af3ec076f1b1aff715b8790ff4966", "sha256": "ee63374e8febbc3025bc0f25d7d5e8fc80971610611c5dbd04be9e554e7a6723" }, "downloads": -1, "filename": "undictify-0.2.6-py3-none-any.whl", "has_sig": false, "md5_digest": "2e4af3ec076f1b1aff715b8790ff4966", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12963, "upload_time": "2018-08-08T17:25:44", "url": "https://files.pythonhosted.org/packages/e0/2e/5c6f2d8f18e2d7ff208f96c531415dee230c11317b491f7f672e0c38409b/undictify-0.2.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "035f0505ccd9d0ff64a21639366a2bb6", "sha256": "9588c9f0afdfbe297eb2bd7a3b577a84b6c4b06def46df60fcedc006b8c3d1f1" }, "downloads": -1, "filename": "undictify-0.2.6.tar.gz", "has_sig": false, "md5_digest": "035f0505ccd9d0ff64a21639366a2bb6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17138, "upload_time": "2018-08-08T17:25:46", "url": "https://files.pythonhosted.org/packages/ee/dc/c951d61f53390c19cd51d5e7a11bdad837afd3fc7b4ea9e6d1a32f9bd1f9/undictify-0.2.6.tar.gz" } ], "0.2.7": [ { "comment_text": "", "digests": { "md5": "47d56191415a74e6e085106ee70b5e04", "sha256": "b5839cf18ec5308dc41c7ce05922bcbcaf224fd880814c4fff6ba23dec4c5cc0" }, "downloads": -1, "filename": "undictify-0.2.7-py3-none-any.whl", "has_sig": false, "md5_digest": "47d56191415a74e6e085106ee70b5e04", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12816, "upload_time": "2018-08-09T19:41:28", "url": "https://files.pythonhosted.org/packages/a5/7f/b469a6a6b03e6ecc6751cd3adfcb43356afe4509bb4fc6c24999b455ed7a/undictify-0.2.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1e938adf60da66baa361d5f209f0f61f", "sha256": "ca504a3452420717cc7cc73a6bd251edce4f1092a5018b8ed411265ec926228b" }, "downloads": -1, "filename": "undictify-0.2.7.tar.gz", "has_sig": false, "md5_digest": "1e938adf60da66baa361d5f209f0f61f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17025, "upload_time": "2018-08-09T19:41:30", "url": "https://files.pythonhosted.org/packages/89/2b/77d8a257cdbcf7bd1b45637456765856c713f64326218b57eea1fc2ef7c5/undictify-0.2.7.tar.gz" } ], "0.2.8": [ { "comment_text": "", "digests": { "md5": "1454fe4b1e2927a0580cf9f65b76bb9a", "sha256": "1a1818087462d1f2819679264000c0bfc8a27ae5e8e5d01532699f9880913de4" }, "downloads": -1, "filename": "undictify-0.2.8-py3-none-any.whl", "has_sig": false, "md5_digest": "1454fe4b1e2927a0580cf9f65b76bb9a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12907, "upload_time": "2018-08-09T19:52:55", "url": "https://files.pythonhosted.org/packages/ff/26/25d269f3808b8218ef76fde491cd2cc339172e81827d7dcd00c4cc9b9a3c/undictify-0.2.8-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d022a1b0b959f40e70cdc3cc0146066", "sha256": "4f3f4ab7c87f834144f9df4f32e6a4c3a0d14c47f6520c4c726ab0e7c04c47b6" }, "downloads": -1, "filename": "undictify-0.2.8.tar.gz", "has_sig": false, "md5_digest": "9d022a1b0b959f40e70cdc3cc0146066", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17098, "upload_time": "2018-08-09T19:52:56", "url": "https://files.pythonhosted.org/packages/23/fe/623681b57ab6c0b152047f3d6dbb8316e4e4ae65c333fec5657fa2aaaafb/undictify-0.2.8.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "34e63b3f95b9950e34d613618b33972f", "sha256": "2cee5d23d8034173852ce4a5fe86193db6c6d2d4e55a3ade4573a894d5bffa3c" }, "downloads": -1, "filename": "undictify-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "34e63b3f95b9950e34d613618b33972f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12346, "upload_time": "2018-08-10T05:42:39", "url": "https://files.pythonhosted.org/packages/3d/30/1dbb4cd67690333d5bdf68f7513cbfed0a5cf111ade472bf22d1edab1e7b/undictify-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e7aeb454990a3a0bd4d83c04ee2f9562", "sha256": "b0205879bf99d20d96b7796acd8382467f2e5f3ca74ef4fef1242ac33ea19fdb" }, "downloads": -1, "filename": "undictify-0.3.0.tar.gz", "has_sig": false, "md5_digest": "e7aeb454990a3a0bd4d83c04ee2f9562", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16177, "upload_time": "2018-08-10T05:42:40", "url": "https://files.pythonhosted.org/packages/4c/7c/c9a261337946173e00e1ba1e8293a3b11ffe1d08b7850b901b755acd8b64/undictify-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "3290a30472406afbc5e967e1b356d851", "sha256": "03abce7d7a53c1e8553a7cc44bf28805a5fac7dae9c35a48879b4ad80b69dc45" }, "downloads": -1, "filename": "undictify-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "3290a30472406afbc5e967e1b356d851", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12497, "upload_time": "2018-08-10T14:13:44", "url": "https://files.pythonhosted.org/packages/07/7e/ae7e9be1fee2585cb4bf76452c0bf37fae97ff51f6673029726ccc48fb54/undictify-0.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d81536d177892d24f22adede7221377", "sha256": "3ec842356ebdbcd7bf5d47454121dc27d14fc2df059609248f118a7ef0346413" }, "downloads": -1, "filename": "undictify-0.3.1.tar.gz", "has_sig": false, "md5_digest": "9d81536d177892d24f22adede7221377", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16342, "upload_time": "2018-08-10T14:13:46", "url": "https://files.pythonhosted.org/packages/97/1a/2600b1af4c1f03f25f5a0debba895d198696612d298dd5bf395229b3fd61/undictify-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "66b4ea8ab5453191e38d8a370029fd21", "sha256": "24841d96f3b14320bde330546297697808beac0f0e9161221eb52b80f2f511f8" }, "downloads": -1, "filename": "undictify-0.3.2-py3-none-any.whl", "has_sig": false, "md5_digest": "66b4ea8ab5453191e38d8a370029fd21", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12494, "upload_time": "2018-08-10T14:45:30", "url": "https://files.pythonhosted.org/packages/6f/19/ff56d00bcfb78eca1c7f37c1823204e1d5f40fccc20513f84e92eb2d4d53/undictify-0.3.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f301f432ed0ab0512cdd845e6a2f8e16", "sha256": "61f7086f71852c1acbb4ccc7a94254d6455242f9c52e1baeaddebc1cb5875a52" }, "downloads": -1, "filename": "undictify-0.3.2.tar.gz", "has_sig": false, "md5_digest": "f301f432ed0ab0512cdd845e6a2f8e16", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16335, "upload_time": "2018-08-10T14:45:31", "url": "https://files.pythonhosted.org/packages/df/57/f06a0cbf7a276d2683b44505642de3806aed5008fda73368191505dcb569/undictify-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "bd65998635b8884f1b7c0b826162c656", "sha256": "7ed26bfc7fc5c277cf7af96ce3d47046c72413807c00913af30b279ad647e6e2" }, "downloads": -1, "filename": "undictify-0.3.3-py3-none-any.whl", "has_sig": false, "md5_digest": "bd65998635b8884f1b7c0b826162c656", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12490, "upload_time": "2018-08-12T07:02:30", "url": "https://files.pythonhosted.org/packages/32/32/56b8d8a8b3d26292f31f3220ecf01861d1c0aa123f24199000923fed7e04/undictify-0.3.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "db27f9feb0b09b9284bdc3b32f329571", "sha256": "63fbee03a103bab5dc1a7bcc4f6d8504f4408c559645fdfd43ab53346a894086" }, "downloads": -1, "filename": "undictify-0.3.3.tar.gz", "has_sig": false, "md5_digest": "db27f9feb0b09b9284bdc3b32f329571", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16399, "upload_time": "2018-08-12T07:02:32", "url": "https://files.pythonhosted.org/packages/d3/7e/d85d3a74a7ac612ac62e29312dcfc96601b582cadbe75e76991a08b07279/undictify-0.3.3.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "3530d3a8269198b24ba38ed9b0973291", "sha256": "ec2bdfb653e5ceb1f1deaff637bbae69aa774d13413e533f4a38b203b2e0f27f" }, "downloads": -1, "filename": "undictify-0.4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "3530d3a8269198b24ba38ed9b0973291", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 13277, "upload_time": "2018-09-09T12:40:32", "url": "https://files.pythonhosted.org/packages/36/ce/9f5b14c686d85b37bc9863cc3fabe245d7888fd64aea953446ed31afdfcc/undictify-0.4.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "11d764115184c9acf44682f89b4c91a3", "sha256": "6b9601fe315b2f6df4f1525a64bb32ffd649d977dd7916d854a54ed4340574d1" }, "downloads": -1, "filename": "undictify-0.4.0.tar.gz", "has_sig": false, "md5_digest": "11d764115184c9acf44682f89b4c91a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17112, "upload_time": "2018-09-09T12:40:34", "url": "https://files.pythonhosted.org/packages/3a/ae/a3c2d055eb95cff4aef113e8023daac5d965a4b0a4ae5f2d4649a0a8958f/undictify-0.4.0.tar.gz" } ], "0.4.4": [ { "comment_text": "", "digests": { "md5": "5e5a66663b593eff7071b98c5d2545f0", "sha256": "3f87bb318e9b7e59254dced14eb994f771b1be3f58404caabaff580cbff59095" }, "downloads": -1, "filename": "undictify-0.4.4-py3-none-any.whl", "has_sig": false, "md5_digest": "5e5a66663b593eff7071b98c5d2545f0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14309, "upload_time": "2018-12-05T07:55:51", "url": "https://files.pythonhosted.org/packages/8e/0a/b5e39f88375f1e08b7f03fe15b84e3f30b3c7450e9df9539d598d67bc863/undictify-0.4.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "53f978264c9b3625ddd15ad558ce45e6", "sha256": "07a887168d548f0e878e1850e7b4dfae14c8257ba600920d5391371bc0aa22ea" }, "downloads": -1, "filename": "undictify-0.4.4.tar.gz", "has_sig": false, "md5_digest": "53f978264c9b3625ddd15ad558ce45e6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17848, "upload_time": "2018-12-05T07:55:53", "url": "https://files.pythonhosted.org/packages/33/f2/59d647bb53b2da9bd808648104df0ee59aa54a3b6a94ebf14ec1dfd1dfae/undictify-0.4.4.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "0201ff3086ada5cd8bd1c18252c11fc3", "sha256": "55cfad84974640bafcfeecd0daa6e1823f34a7892d5f5617294c5b70993b2112" }, "downloads": -1, "filename": "undictify-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0201ff3086ada5cd8bd1c18252c11fc3", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14765, "upload_time": "2019-01-07T16:10:21", "url": "https://files.pythonhosted.org/packages/dd/5c/e504a9fcf69255e8e973c0416bc7934114169eb070db0c4384d2d8b3894b/undictify-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8cc4047bad028f279f94bcd5537b4ff5", "sha256": "1eaf1c6f7f55a0603c1e44aad4c8017b203210da68e5f226daaa47a114414c56" }, "downloads": -1, "filename": "undictify-0.5.0.tar.gz", "has_sig": false, "md5_digest": "8cc4047bad028f279f94bcd5537b4ff5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18275, "upload_time": "2019-01-07T16:10:24", "url": "https://files.pythonhosted.org/packages/5c/65/849d2bb02d1edf9994e357257891368383c7f74d25cff793fa4c03eafda4/undictify-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "70a418855738567641c243b3e9d4b054", "sha256": "7ac66a6ec3ff086ea66c94c014905d806d8c7b03c037e1deb43527efbae449e6" }, "downloads": -1, "filename": "undictify-0.6.0-py3-none-any.whl", "has_sig": false, "md5_digest": "70a418855738567641c243b3e9d4b054", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15308, "upload_time": "2019-02-12T20:19:17", "url": "https://files.pythonhosted.org/packages/0c/a8/bf39c64331ce5b2a2e7a94e0b34bbfb2f1b075c313de66b78a8338920ddc/undictify-0.6.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "12bba9428a69c7e0bb04fda8280bd4c3", "sha256": "182b53a19fa906d33b02c2782e3d3ce586b77ac25862a4214b17498a1136d1b2" }, "downloads": -1, "filename": "undictify-0.6.0.tar.gz", "has_sig": false, "md5_digest": "12bba9428a69c7e0bb04fda8280bd4c3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18793, "upload_time": "2019-02-12T20:19:20", "url": "https://files.pythonhosted.org/packages/ea/af/bc3bdb3a70ed1cec21ca9969d257d344b2bfab3879f16f45efc4550a85c2/undictify-0.6.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "8780c7bcc45a4f388e6492488e325d15", "sha256": "74903009bc86da4bcc3053af1171a13b8585fc51a967e94997b0eba4a3a093ac" }, "downloads": -1, "filename": "undictify-0.6.1-py3-none-any.whl", "has_sig": false, "md5_digest": "8780c7bcc45a4f388e6492488e325d15", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15523, "upload_time": "2019-02-14T10:20:05", "url": "https://files.pythonhosted.org/packages/0a/97/ba81c6fdf4543564a5bbdac6e6dce2be90b51d703e54bb338fa67b6f9f8d/undictify-0.6.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ba210da69a87c4efc5329ea554c9c170", "sha256": "ef3e599f7c22702c40bbe3cb032b4f7cb6dd55f48375d2d0e099d4b366e96a20" }, "downloads": -1, "filename": "undictify-0.6.1.tar.gz", "has_sig": false, "md5_digest": "ba210da69a87c4efc5329ea554c9c170", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18995, "upload_time": "2019-02-14T10:20:07", "url": "https://files.pythonhosted.org/packages/cd/aa/f0014703f3d806a824bd005888b5f3e7bd3f2cee281c9cf725815a546213/undictify-0.6.1.tar.gz" } ], "0.6.2": [ { "comment_text": "", "digests": { "md5": "75494e337dddb37b794aa0bd994c5531", "sha256": "18c47cbe5e8afb19bf72ee5bfbd302731dd6cccaa501a4f281eb540d602e22fc" }, "downloads": -1, "filename": "undictify-0.6.2-py3-none-any.whl", "has_sig": false, "md5_digest": "75494e337dddb37b794aa0bd994c5531", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15586, "upload_time": "2019-02-14T14:09:36", "url": "https://files.pythonhosted.org/packages/1f/d3/a424ec58bd29e3e5102a79888721f9f3c55ef6af8f60f3a324d17f1ccc8d/undictify-0.6.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "39abcd67572d27ca1ccdabbc6df648dc", "sha256": "afab48225a3f8f7704443014648bb55fffcc2a370bde3a061bcc6ed879e0a79b" }, "downloads": -1, "filename": "undictify-0.6.2.tar.gz", "has_sig": false, "md5_digest": "39abcd67572d27ca1ccdabbc6df648dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19050, "upload_time": "2019-02-14T14:09:37", "url": "https://files.pythonhosted.org/packages/8f/1d/8f02111d948c4aa8e1f6de264e1b5468de23dfdef203f56e9288351bd64e/undictify-0.6.2.tar.gz" } ], "0.6.3": [ { "comment_text": "", "digests": { "md5": "86210780a76323d1fc1cda71eaaecf59", "sha256": "c3e1deac96fd12255876ae7ceb02a28b03676bd4cb215c61d84283b2664a1def" }, "downloads": -1, "filename": "undictify-0.6.3-py3-none-any.whl", "has_sig": false, "md5_digest": "86210780a76323d1fc1cda71eaaecf59", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16158, "upload_time": "2019-02-17T06:00:25", "url": "https://files.pythonhosted.org/packages/be/cf/25c4263389d84886d5b9d06512885d699b82238d2b292939458dceed4d6a/undictify-0.6.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b7ffe867e72d27e8e84b4a789ada75a2", "sha256": "1ef10178b223fb7dbfafbb53fea8e160ce0995738a9f85b669d921e805c596fb" }, "downloads": -1, "filename": "undictify-0.6.3.tar.gz", "has_sig": false, "md5_digest": "b7ffe867e72d27e8e84b4a789ada75a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19643, "upload_time": "2019-02-17T06:00:27", "url": "https://files.pythonhosted.org/packages/f1/73/fdbbeb0390260dff56e16df2ebd0a7cb6584b04b2c52e2cd7997133572d9/undictify-0.6.3.tar.gz" } ], "0.6.4": [ { "comment_text": "", "digests": { "md5": "59b72670e973f1055e5156d55dd214e2", "sha256": "5fe1c176e931eb1517c33a329a0a2fbd85925fa6056c9e7f05d8d803c5a211af" }, "downloads": -1, "filename": "undictify-0.6.4-py3-none-any.whl", "has_sig": false, "md5_digest": "59b72670e973f1055e5156d55dd214e2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 16159, "upload_time": "2019-02-17T06:05:20", "url": "https://files.pythonhosted.org/packages/bb/a9/f5a9b78982cf13aa71ad685f6387f60238b8b94dd10791581627c53bd3fa/undictify-0.6.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b3a6262c492e8e5f0d952d003c76548f", "sha256": "a50db3e4233dfc5a8046b6a79248be5c8a01441f00a4ade75650cfbf17323893" }, "downloads": -1, "filename": "undictify-0.6.4.tar.gz", "has_sig": false, "md5_digest": "b3a6262c492e8e5f0d952d003c76548f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19644, "upload_time": "2019-02-17T06:05:21", "url": "https://files.pythonhosted.org/packages/94/56/ff6dd63bbdfc108a90c09c4dcc9a66bbfdb60b8375133b8d1c098d662402/undictify-0.6.4.tar.gz" } ], "0.6.5": [ { "comment_text": "", "digests": { "md5": "ecc9141fc301d0118371df4d4d8dde7a", "sha256": "922696a79196eb75be96a3f829a0badae5aed425a0e0f071c0f1cc6a4ce7db01" }, "downloads": -1, "filename": "undictify-0.6.5-py3-none-any.whl", "has_sig": false, "md5_digest": "ecc9141fc301d0118371df4d4d8dde7a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17195, "upload_time": "2019-05-22T05:40:49", "url": "https://files.pythonhosted.org/packages/04/83/9fd016778fcdbb37c6874e8c8111cb40a7c20ea4e69808ac16ce5102948d/undictify-0.6.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dd6404c410efe69fe78c2f3a7090b2e9", "sha256": "7418292459c1230d5b57c6972ab71e5cc61a1d2fbf4d9b0f311155f62b4bc1ab" }, "downloads": -1, "filename": "undictify-0.6.5.tar.gz", "has_sig": false, "md5_digest": "dd6404c410efe69fe78c2f3a7090b2e9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19563, "upload_time": "2019-05-22T05:40:51", "url": "https://files.pythonhosted.org/packages/39/e9/e565d7a0a42037c29e2854c0c4347d58fe0ab90b3e7506aab8d4e9d2fd2b/undictify-0.6.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ecc9141fc301d0118371df4d4d8dde7a", "sha256": "922696a79196eb75be96a3f829a0badae5aed425a0e0f071c0f1cc6a4ce7db01" }, "downloads": -1, "filename": "undictify-0.6.5-py3-none-any.whl", "has_sig": false, "md5_digest": "ecc9141fc301d0118371df4d4d8dde7a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17195, "upload_time": "2019-05-22T05:40:49", "url": "https://files.pythonhosted.org/packages/04/83/9fd016778fcdbb37c6874e8c8111cb40a7c20ea4e69808ac16ce5102948d/undictify-0.6.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dd6404c410efe69fe78c2f3a7090b2e9", "sha256": "7418292459c1230d5b57c6972ab71e5cc61a1d2fbf4d9b0f311155f62b4bc1ab" }, "downloads": -1, "filename": "undictify-0.6.5.tar.gz", "has_sig": false, "md5_digest": "dd6404c410efe69fe78c2f3a7090b2e9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19563, "upload_time": "2019-05-22T05:40:51", "url": "https://files.pythonhosted.org/packages/39/e9/e565d7a0a42037c29e2854c0c4347d58fe0ab90b3e7506aab8d4e9d2fd2b/undictify-0.6.5.tar.gz" } ] }