{ "info": { "author": "Ryan McDevitt", "author_email": "mcdevitt.ryan@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Topic :: Software Development :: Libraries", "Topic :: Utilities" ], "description": "# Data Records\n[![PyPI version](https://badge.fury.io/py/data-records.svg)](https://badge.fury.io/py/data-records)\n[![pipeline status](https://gitlab.com/mc706/data-records/badges/master/pipeline.svg)](https://gitlab.com/mc706/data-records/commits/master)\n[![coverage report](https://gitlab.com/mc706/data-records/badges/master/coverage.svg)](https://gitlab.com/mc706/data-records/commits/master)\n[![PyPI](https://img.shields.io/pypi/pyversions/data-records.svg)](https://pypi.org/project/data-records/)\n[![Documentation Status](https://readthedocs.org/projects/data-records/badge/?version=latest)](https://data-records.readthedocs.io/en/latest/?badge=latest)\n[![Downloads](https://pepy.tech/badge/data-records)](https://pepy.tech/project/data-records)\n\nIn certain Functional languages there is a concept of Records. They are a Product Data Type of immutable data that \nhas typed attributes. \n\n## Goals\nThe following are the goals and the \"north star\" for design during the development of this project:\n\n* Ease Of Use\n * Simple Interface\n * Does the obvious thing in most cases\n* Immutability\n * Follow Immutability Patterns such as replace and pattern matching\n* Safety\n * Include Type Coercion Where Possible\n * Guarantee that a record has the resulting types\n * Throw Warning when it is implemented Incorrectly\n\n## Motivation\n\n## Enforced Typing\nI love `@dataclass`, and was ecstatic when it was added to python. However certain things like:\n\n```python \n>>> from dataclasses import dataclass, field\n\n>>> @dataclass\n... class Foo:\n... bar: str\n... baz: int\n\n>>> Foo(1, 2)\nFoo(bar=1, baz=2)\n\n```\n\nis not what I would expect when coming from other typed languages. In statically typed languages, this should throw an \nerror because `bar` should be a string. In languages with type coercion, I would expect that `bar` would be `\"1\"`. The default\nbehavior of dataclasses here does neither, and if I were to use this dataclass somewhere that expected bar to be a string\nit would fail with a runtime exception; exactly what the types were supposed to help prevent.\n\n```python \n>>> from data_records import datarecord\n\n>>> @datarecord\n... class Foo:\n... bar: str\n... baz: int\n\n>>> Foo(1, 2)\nFoo(bar='1', baz=2)\n\n>>> Foo(\"a\", \"b\")\nTraceback (most recent call last):\n ...\nValueError: invalid literal for int() with base 10: 'b'\n\n```\n\n## Extraneous Field Handling\n\nAnother Problem with dataclasses occurs when trying to pass in a dictionary that has more keys than are required for\ncreating a dataclass:\n\n```python \n>>> from dataclasses import dataclass\n\n>>> @dataclass\n... class Foo:\n... bar: str\n... baz: int\n\n>>> Foo(**{'bar': 'test', 'baz': 1, 'other': 'nothing'})\nTraceback (most recent call last):\n ...\nTypeError: __init__() got an unexpected keyword argument 'other'\n\n```\n\nThis makes it hard to pull data records out of larger database calls or received data.\n\n```python\n>>> from data_records import datarecord \n\n>>> @datarecord\n... class Foo:\n... bar: str\n... baz: int\n\n>>> Foo(**{'bar': 'test', 'baz': 1, 'other': 'test'})\nFoo(bar='test', baz=1)\n\n>>> Foo.from_dict({'bar': 'test', 'baz': 1, 'other': 'test'})\nFoo(bar='test', baz=1)\n\n```\n\n## Immutable Handling\nData records are immutable (much like frozen dataclasses) and the handling for such is builtin:\n\n```python \n>>> from data_records import datarecord\n\n>>> @datarecord\n... class Foo:\n... bar: str\n... baz: int\n... lat: float\n... long: float\n\n>>> example = Foo('test', 2, 65.1, -127.5)\n>>> example2 = example.replace(bar='testing')\n\n>>> example\nFoo(bar='test', baz=2, lat=65.1, long=-127.5)\n\n>>> example2\nFoo(bar='testing', baz=2, lat=65.1, long=-127.5)\n\n>>> latitude, longitude = example.extract('lat', 'long')\n>>> latitude\n65.1\n\n```\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": "https://gitlab.com/mc706/data-records", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "data-records", "package_url": "https://pypi.org/project/data-records/", "platform": "", "project_url": "https://pypi.org/project/data-records/", "project_urls": { "Bug Reports/Issues": "https://gitlab.com/mc706/data-records/issues", "Docs": "https://data-records.readthedocs.io/en/stable/#", "Homepage": "https://gitlab.com/mc706/data-records", "Source": "https://gitlab.com/mc706/data-records" }, "release_url": "https://pypi.org/project/data-records/0.4.2/", "requires_dist": [ "prospector ; extra == 'dev'", "coverage ; extra == 'dev'", "mypy ; extra == 'dev'", "pytest ; extra == 'dev'", "pytest-cov ; extra == 'dev'" ], "requires_python": "", "summary": "Immutable Data Records with Type Coercion", "version": "0.4.2" }, "last_serial": 5020899, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "b28c7f03d1f81cc360412635758bb520", "sha256": "7b650cf39b8245a9226a382a57522fea02d77cc23ade39906960973826ad7140" }, "downloads": -1, "filename": "data_records-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b28c7f03d1f81cc360412635758bb520", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 4309, "upload_time": "2019-03-28T20:49:08", "url": "https://files.pythonhosted.org/packages/c2/8a/0df6e04b92e5a7b7ba4750c413e1c5686c2476e78bf19979f8cf84e769dc/data_records-0.0.1-py3-none-any.whl" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "d0a172a4971d0e3a48ea9bcd0c6d3a98", "sha256": "7d822aef847586ee8311757a63aae6a8861e1b6498335fee0b6149d6808089b5" }, "downloads": -1, "filename": "data_records-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "d0a172a4971d0e3a48ea9bcd0c6d3a98", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7139, "upload_time": "2019-03-31T13:54:25", "url": "https://files.pythonhosted.org/packages/ce/2f/60d51407b1f36f4278372bd2b4c106663ac1c3e193c427c0c61cac0580ee/data_records-0.1.0-py3-none-any.whl" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "4c6b4784b4c2176f5c4d489b68937d5d", "sha256": "d20542fceb14d96d5646e191c284447aa7c45f179658633bcbb55253734ab6d6" }, "downloads": -1, "filename": "data_records-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "4c6b4784b4c2176f5c4d489b68937d5d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8840, "upload_time": "2019-03-31T20:20:24", "url": "https://files.pythonhosted.org/packages/ea/bc/dd4f3fd38588b12786a4ab1d01edd77700da6b002d7fa389e2c919a1ef49/data_records-0.1.1-py3-none-any.whl" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "d75a74dfef14ca0d2d84bc8e2d254362", "sha256": "3cc3bef0c05e6f26c94fde8ffb8fc67fc5ded508b133a6e8f6b1f3f37ea2340d" }, "downloads": -1, "filename": "data_records-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "d75a74dfef14ca0d2d84bc8e2d254362", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 8943, "upload_time": "2019-03-31T22:09:16", "url": "https://files.pythonhosted.org/packages/4d/cf/0f4fd22b9e5073d99f0f8da042b55a94f2104c8d29beb0054204a4d09ce5/data_records-0.2.0-py3-none-any.whl" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "67b4731bdc785aafcce4070f74eb43c6", "sha256": "75f3aebea9b30d9e35c06326c6e593f6229824095879423d4d64f373c08e506a" }, "downloads": -1, "filename": "data_records-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "67b4731bdc785aafcce4070f74eb43c6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9114, "upload_time": "2019-04-01T01:59:10", "url": "https://files.pythonhosted.org/packages/b8/cb/dfa4d36537724b5eb69708d32d5c45c64f214b5b0e2325dfecde109786f4/data_records-0.3.0-py3-none-any.whl" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "f33bc4fc7d22f9ef3a9f755cff9d3ce6", "sha256": "e6ce0e16837399b4a63f2c8645183a321074183d7e3ffa7945a9f82550d4ad3b" }, "downloads": -1, "filename": "data_records-0.4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f33bc4fc7d22f9ef3a9f755cff9d3ce6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9122, "upload_time": "2019-04-01T03:46:40", "url": "https://files.pythonhosted.org/packages/cf/5b/897571911fab757d8e83c326f0d0610bcf195ffaf35ddd320a75672e110d/data_records-0.4.0-py3-none-any.whl" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "645f7ae3edf5129fd1c25b80938fd405", "sha256": "c219188dc8570ee7f7382101bbf6626dcf1ac2ec029ed68a822d6af4da633191" }, "downloads": -1, "filename": "data_records-0.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "645f7ae3edf5129fd1c25b80938fd405", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9136, "upload_time": "2019-04-01T13:17:42", "url": "https://files.pythonhosted.org/packages/1e/25/2b25b8b841f78b570f6807caf3a071ca398b7e88fba316360f42d9ce2d02/data_records-0.4.1-py3-none-any.whl" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "ba4b7321723994c7894ff01dbc6f0d0d", "sha256": "47c905401016e5119a0bf96a5aab9f921b777ae6fe78d59ef2388353bd8c1595" }, "downloads": -1, "filename": "data_records-0.4.2-py3-none-any.whl", "has_sig": false, "md5_digest": "ba4b7321723994c7894ff01dbc6f0d0d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9177, "upload_time": "2019-04-01T13:57:47", "url": "https://files.pythonhosted.org/packages/b4/a5/4d7992133a1945f901e65af60ed8a3bcb8c3b4436387bb175dcf3042decc/data_records-0.4.2-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ba4b7321723994c7894ff01dbc6f0d0d", "sha256": "47c905401016e5119a0bf96a5aab9f921b777ae6fe78d59ef2388353bd8c1595" }, "downloads": -1, "filename": "data_records-0.4.2-py3-none-any.whl", "has_sig": false, "md5_digest": "ba4b7321723994c7894ff01dbc6f0d0d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9177, "upload_time": "2019-04-01T13:57:47", "url": "https://files.pythonhosted.org/packages/b4/a5/4d7992133a1945f901e65af60ed8a3bcb8c3b4436387bb175dcf3042decc/data_records-0.4.2-py3-none-any.whl" } ] }