{ "info": { "author": "Dave Shawley", "author_email": "daveshawley@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 1 - Planning", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Text Processing" ], "description": "coercion\n========\n|ReadTheDocs| |TravisCI| |CodeCov|\n\nThis library provides functions that coerce datastructures into\nnormalized forms. For example, converting an arbitrary ``dict``\ninto a form that is suitable for passing to ``json.dumps``.\n\nThe `tornado`_ framework has a function called `recursive_unicode`_\nin the ``tornado.escape`` module. It is a very simple recursive\nwalk of datastructure that switches on type and transforms string\nvalues into unicode strings. I use this in production software\nregularly and it works like a charm. Or at least it did until my\nsoftware encountered a deeply nested dictionary and I received a\n``RuntimeError: maximum recursion depth exceeded`` error in my\nservice log. This is one of the exceptions that strikes fear into\nmost engineers when it rears it's head in production.\n\nThat is the primary reason for this library existing. It provides\nthe same simple string encoding function iteratively instead of\nrecursively. At the same time, the need to coerce values into a\nnormalized string form is something that I've had to do repeatedly\nso it might as well be plopped into a reusable library.\n\nExamples\n--------\nThe following example shows one of the underlying reasons that this\nlibrary was created. The commonly used msgpack implementation for\npython returns everything as byte strings which is problematic if\nyou want to dump it as JSON since it will raise a ``TypeError`` if\ndictionary keys are not strings. (This is where `recursive_unicode`_\nwas so handy.)\n\n.. code-block:: python\n\n >>> import json\n >>> import coercion\n >>> import msgpack\n >>> bin_msg = msgpack.packb({u'\\u00DCnicode': b'bytes', b'bytes': 'str'})\n >>> decoded = msgpack.unpackb(bin_msg)\n >>> decoded\n {b'bytes': b'str', b'\\xc3\\x9cnicode': b'bytes'}\n >>> json.dumps(decoded)\n Traceback (most recent call last):\n File \"\", line 1, in \n File \"/Users/daveshawley/opt/lib/python3.5/json/__init__.py\", line 230, in dumps\n return _default_encoder.encode(obj)\n File \"/Users/daveshawley/opt/lib/python3.5/json/encoder.py\", line 199, in encode\n chunks = self.iterencode(o, _one_shot=True)\n File \"/Users/daveshawley/opt/lib/python3.5/json/encoder.py\", line 257, in iterencode\n return _iterencode(o, 0)\n TypeError: keys must be a string\n >>> json.dumps(coercion.normalize_collection(decoded))\n '{\"bytes\": \"str\", \"\\\\u00dcnicode\": \"bytes\"}'\n\n\n.. _tornado: http://www.tornadoweb.org/\n.. _recursive_unicode: http://www.tornadoweb.org/en/stable/escape.html\n #tornado.escape.recursive_unicode\n\n.. |ReadTheDocs| image:: https://readthedocs.org/projects/coercion/badge/\n ?version=latest\n :target: https://coercion.readthedocs.org/\n :alt: [Documentation]\n.. |TravisCI| image:: https://travis-ci.org/dave-shawley/coercion.svg\n ?branch=master\n :target: https://travis-ci.org/dave-shawley/coercion\n :alt: [Build Status]\n.. |CodeCov| image:: https://codecov.io/github/dave-shawley/coercion/\n coverage.svg?branch=master\n :target: https://codecov.io/github/dave-shawley/coercion?branch=master\n :alt: [Test Coverage]", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/dave-shawley/coercion", "keywords": "", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "coercion", "package_url": "https://pypi.org/project/coercion/", "platform": "any", "project_url": "https://pypi.org/project/coercion/", "project_urls": { "Homepage": "https://github.com/dave-shawley/coercion" }, "release_url": "https://pypi.org/project/coercion/1.0.0/", "requires_dist": null, "requires_python": "", "summary": "Coercing data into a normalized form", "version": "1.0.0" }, "last_serial": 1797793, "releases": { "0.0.0": [ { "comment_text": "", "digests": { "md5": "0bb33256c1ce70f213178d327bc21fc5", "sha256": "b9a03324618f29a15d23cfa85fab1025e06653c61171cf63f3412bd097030595" }, "downloads": -1, "filename": "coercion-0.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0bb33256c1ce70f213178d327bc21fc5", "packagetype": "bdist_wheel", "python_version": "any", "requires_python": null, "size": 4092, "upload_time": "2015-10-31T16:22:05", "url": "https://files.pythonhosted.org/packages/a1/71/c6fed642192b6fe58c93845e4dfb2599868ff9b2890afb085e2de4ee76fe/coercion-0.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0a35c7e511bf96d33df9989ebd62a188", "sha256": "4c3aa7d9fcad1f9f52b68ff0c116d1e92adb591136aea0d62f1827b383d1edab" }, "downloads": -1, "filename": "coercion-0.0.0.tar.gz", "has_sig": false, "md5_digest": "0a35c7e511bf96d33df9989ebd62a188", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3766, "upload_time": "2015-10-31T16:21:43", "url": "https://files.pythonhosted.org/packages/25/04/cd491aa084c9a711b36e4b413060dc9dd5b264cebfb55f365a36f60e3fad/coercion-0.0.0.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "e6c9f1046a46c6c31084c439d7e7e840", "sha256": "0ede1ee36a6aa5f44333c1354968ef20031b4e513d4e33b180578c4d9d3c47bd" }, "downloads": -1, "filename": "coercion-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e6c9f1046a46c6c31084c439d7e7e840", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6970, "upload_time": "2015-11-02T18:54:09", "url": "https://files.pythonhosted.org/packages/04/1a/67ea039a9d19f2a3bb26c8dfd1f0a6786c1d11cef3bb4e5e542479352859/coercion-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "07510272def74390b77b12f7df0245cf", "sha256": "cd1c27a47b26d0458d86ebb7c1d85838a63e37ba1c019531f9265b290031fe2c" }, "downloads": -1, "filename": "coercion-1.0.0.tar.gz", "has_sig": false, "md5_digest": "07510272def74390b77b12f7df0245cf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7896, "upload_time": "2015-11-02T18:54:21", "url": "https://files.pythonhosted.org/packages/7a/97/f1965afc2ae27074a05e5201236540364f53eff24c26d6ee04aa81d53b80/coercion-1.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e6c9f1046a46c6c31084c439d7e7e840", "sha256": "0ede1ee36a6aa5f44333c1354968ef20031b4e513d4e33b180578c4d9d3c47bd" }, "downloads": -1, "filename": "coercion-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e6c9f1046a46c6c31084c439d7e7e840", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6970, "upload_time": "2015-11-02T18:54:09", "url": "https://files.pythonhosted.org/packages/04/1a/67ea039a9d19f2a3bb26c8dfd1f0a6786c1d11cef3bb4e5e542479352859/coercion-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "07510272def74390b77b12f7df0245cf", "sha256": "cd1c27a47b26d0458d86ebb7c1d85838a63e37ba1c019531f9265b290031fe2c" }, "downloads": -1, "filename": "coercion-1.0.0.tar.gz", "has_sig": false, "md5_digest": "07510272def74390b77b12f7df0245cf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7896, "upload_time": "2015-11-02T18:54:21", "url": "https://files.pythonhosted.org/packages/7a/97/f1965afc2ae27074a05e5201236540364f53eff24c26d6ee04aa81d53b80/coercion-1.0.0.tar.gz" } ] }