{ "info": { "author": "huntzhan", "author_email": "programmer.zhx@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 1 - Planning", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries" ], "description": "# Introduction\n\n*magic-constraints* implemented (or hacked) a bunch of [abstract base classes][1] (ABCs for short) to support [type introspection][2], that is, the `isinstance`/`issubclass` operatios in Python. Specialization of ABC is support, i.e. `Sequence[int]` and `Sequence[int]` are specialized versions of `Sequence`.\n\nAlso, *magic-constraints* provides several decorators to enable runtime type/value checking on the parameters and return value of user-defined function and method. Especially, thoses decorators fit well with the type annotation feature introduced in Python 3.x:\n\n```python\nfrom magic_constraints import function_constraints, Optional\n\n\n# foobar should accept either an int object or a None object.\n@function_constraints\ndef function(foobar: Optional[int]) -> float:\n if foobar is None:\n # should fail the return type checking.\n return 42\n else:\n # good case.\n return 42.0\n```\n\nRuntime:\n\n```\n# ok.\n>>> function(1)\n42.0\n\n# failed.\n# 1.0 is float, while foobar requrie int or type(None).\n>>> function(1.0)\nTraceback (most recent call last):\n...\nmagic_constraints.exception.MagicTypeError:\nMagicTypeError: argument unmatched.\n-----------------------------------\nargument: 1.0\nparameter: Parameter(name='foobar', type_=Optional[int])\n-----------------------------------\n\n# failed.\n# when foobar is None, the function returns a float,\n# leading to unmatched return type error.\n>>> function(None)\nTraceback (most recent call last):\n...\nmagic_constraints.exception.MagicTypeError: \nMagicTypeError: return value unmatched.\n---------------------------------------\nret: 42\nreturn_type: ReturnType(type_=float)\n---------------------------------------\n```\n\n# Quick Start\n\n## Install\n\n```\n$ pip install magic-constraints\n```\n\n## Usage Of ABCs\n\n*magic-constraints* provides `Sequence/MutableSequence/ImmutableSequence`. You can invoke `isinstance`/`issubclass` operatios on :\n\n```python\nfrom magic_constraints import Sequence, MutableSequence, ImmutableSequence\n\n# True.\nisinstance([1, 2, 3], Sequence)\n# True.\nisinstance([1, 2, 3], MutableSequence)\n# True.\nisinstance((1, 2, 3), ImmutableSequence)\n\n# True, Sequence with int.\nisinstance([1, 2, 3], Sequence[int])\n# False, 2.0 is float.\nisinstance([1, 2.0, 3], Sequence[int])\n\n# True.\nisinstance([(1, 2), (3, 4)], Sequence[ImmutableSequence[int]])\n# False, 3.0 is float.\nisinstance([(1, 2), (3.0, 4)], Sequence[ImmutableSequence[int]])\n# False, [3, 4] is MutableSequence.\nisinstance([(1, 2), [3, 4]], Sequence[ImmutableSequence[int]])\n\n# True\nissubclass(MutableSequence, Sequence)\n# True\nissubclass(ImmutableSequence, Sequence)\n# False\nissubclass(MutableSequence, ImmutableSequence)\n# False\nissubclass(ImmutableSequence, MutableSequence)\n```\n\nMore avaliable ABCs:\n\n| name | supported specialization(s) |\n| --- | --- |\n| Sequence | [ type ] , [ type , ... ] |\n| MutableSequence | [ type ] , [ type , ... ] |\n| ImmutableSequence | [ type ] , [ type , ... ] |\n| Set | [ type ] |\n| MutableSet | [ type ] |\n| ImmutableSet | [ type ] |\n| Mapping | [ type , type ] |\n| MutableMapping | [ type , type ] |\n| ImmutableMapping | [ type , type ] |\n| Iterator | [ type ] , [ type , ... ] |\n| Iterable | [ type ] , [ type , ... ] |\n| Callable | [ [ type , ... ] , type ] , [ Ellipsis , type ] |\n| Any | *not support* |\n| Union | [ type , ... ] |\n| Optional | [ type ] |\n| NoneType | *not support* |\n\n\n## Usage Of Decorators\n\nDeclaration on function parameters and return value:\n\n```python\nfrom magic_constraints import (\n function_constraints,\n Sequence, Mapping,\n)\n\n@function_constraints\ndef func1(foo: str, bar: Sequence[int]) -> Mapping[str, Sequence[int]]:\n return {foo: bar}\n```\n\nMore decorators:\n\n```python\nfrom magic_constraints.decorator import (\n function_constraints,\n method_constraints,\n class_initialization_constraints,\n)\n```\n\n## Runtime Type/Value Checking\n\nExceptoin would be raised if there's something wrong in the invocation of decorated function, i.e. input argument is not an instance of declared type. \n\nOnly derived classes of `SyntaxError` and `TypeError` would be raised:\n\n1. anything related to types, such as failing to pass `isinstance`, would raise an exception with derived type of `TypeError`.\n2. besides (1), anything related to the promise of interface (function) invocation, would raise an exception with derived type of `SyntaxError`.\n\nExample:\n\n```\n# ok.\n>>> func1('key', [1, 2, 3])\n{'key': [1, 2, 3]}\n\n# failed, bar requires a sequnce.\n>>> func1('42 is not a sequence', 42)\nTraceback (most recent call last):\n...\nmagic_constraints.exception.MagicTypeError: \nMagicTypeError: argument unmatched.\n-----------------------------------\nargument: 42\nparameter: Parameter(name='bar', type_=Sequence[int])\n-----------------------------------\n\n# failed, bar requires a sequence of ints.\n>>> func1('2.0 is not int', [1, 2.0, 3])\nTraceback (most recent call last):\n...\nmagic_constraints.exception.MagicTypeError: \nMagicTypeError: argument unmatched.\n-----------------------------------\nargument: [1, 2.0, 3]\nparameter: Parameter(name='bar', type_=Sequence[int])\n-----------------------------------\n```\n\n# For more...\n\n* [magic_constrains.types][3].\n* [magic_constrains.decorator][4].\n\n\n[1]: https://docs.python.org/3/glossary.html#term-abstract-base-class\n[2]: https://en.wikipedia.org/wiki/Type_introspection\n[3]: https://github.com/huntzhan/magic-constraints/wiki/magic_constrains.types\n[4]: https://github.com/huntzhan/magic-constraints/wiki/magic_constraints.decorator", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/huntzhan/magic-constraints", "keywords": null, "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "magic_constraints", "package_url": "https://pypi.org/project/magic_constraints/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/magic_constraints/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/huntzhan/magic-constraints" }, "release_url": "https://pypi.org/project/magic_constraints/0.4.0/", "requires_dist": null, "requires_python": null, "summary": "Magic Type Introspection And Runtime Parameter Type/Value Checking.", "version": "0.4.0" }, "last_serial": 2096371, "releases": { "0.2.0": [ { "comment_text": "", "digests": { "md5": "a116d246b2be749ec11470d52bd7a945", "sha256": "3c954915ab0965e29d4e0130cc13652aaf81c46058bfe3ee986c5b346fc9d243" }, "downloads": -1, "filename": "magic_constraints-0.2.0.tar.gz", "has_sig": false, "md5_digest": "a116d246b2be749ec11470d52bd7a945", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21047, "upload_time": "2016-04-25T06:00:28", "url": "https://files.pythonhosted.org/packages/ef/7e/8eb1945f9e850b22dc88d89fb9f039702e41a94d8cf011ea58f93ecbd53f/magic_constraints-0.2.0.tar.gz" } ], "0.2.0rc1": [ { "comment_text": "", "digests": { "md5": "53b29a2adb048509989fbf71e13eb9d0", "sha256": "f5d35e3302aa90deaa6a78689a0b657f93cd92466763f19dc6647c665ee5c3b6" }, "downloads": -1, "filename": "magic_constraints-0.2.0rc1.tar.gz", "has_sig": false, "md5_digest": "53b29a2adb048509989fbf71e13eb9d0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21904, "upload_time": "2016-04-20T16:26:44", "url": "https://files.pythonhosted.org/packages/4e/3c/2e3e796ddf6842970bb82e3a1a8bb96582225d0b9da817b7b8cc9395fb21/magic_constraints-0.2.0rc1.tar.gz" } ], "0.2.0rc2": [ { "comment_text": "", "digests": { "md5": "506bb0e11d8074a76895affc072b6699", "sha256": "d0194c1bc15eb783ab6930e117acbcffa5fa29e60ebe09718cce64641ba5aa73" }, "downloads": -1, "filename": "magic_constraints-0.2.0rc2.tar.gz", "has_sig": false, "md5_digest": "506bb0e11d8074a76895affc072b6699", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21946, "upload_time": "2016-04-22T04:59:32", "url": "https://files.pythonhosted.org/packages/04/b2/92eccac24da30a69f16586ce3200a233e18b0c93ad059489f046fb4654d8/magic_constraints-0.2.0rc2.tar.gz" } ], "0.2.0rc3": [ { "comment_text": "", "digests": { "md5": "390aead96ec5bfbc509299e48b320229", "sha256": "d9532704811591a67a60825d2c54f899fed3bd98bc6a73d198d1a5321242e0bd" }, "downloads": -1, "filename": "magic_constraints-0.2.0rc3.tar.gz", "has_sig": false, "md5_digest": "390aead96ec5bfbc509299e48b320229", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 37077, "upload_time": "2016-04-23T10:40:39", "url": "https://files.pythonhosted.org/packages/a5/b7/c46b4a33a574fc0a0b8cef27a95a9d7214336dfdb5333fa73d92b0795c70/magic_constraints-0.2.0rc3.tar.gz" } ], "0.2.0rc4": [ { "comment_text": "", "digests": { "md5": "46457e9e97563ea9f27333687ea620fb", "sha256": "0832fb7f06bdaf484acf6924cab324bd44e2bc0e1402fbc2eeb123db2fd9f44a" }, "downloads": -1, "filename": "magic_constraints-0.2.0rc4.tar.gz", "has_sig": false, "md5_digest": "46457e9e97563ea9f27333687ea620fb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19457, "upload_time": "2016-04-23T20:08:39", "url": "https://files.pythonhosted.org/packages/db/82/7e4e2139aea4512cbcb5be546953990a8be1876edeb34f07f52b852896f5/magic_constraints-0.2.0rc4.tar.gz" } ], "0.2.0rc5": [ { "comment_text": "", "digests": { "md5": "eea5e44b23146ab2007dff7871da5a41", "sha256": "26faa48cfca84df04939a39573141cd1611565455846e37bfe74a41ff72e4d8c" }, "downloads": -1, "filename": "magic_constraints-0.2.0rc5.tar.gz", "has_sig": false, "md5_digest": "eea5e44b23146ab2007dff7871da5a41", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21683, "upload_time": "2016-04-24T15:47:22", "url": "https://files.pythonhosted.org/packages/99/d2/6a76afff8537b3f6be91bf6ab0ca6db176428777398fecef95220b2645d2/magic_constraints-0.2.0rc5.tar.gz" } ], "0.2.0rc6": [ { "comment_text": "", "digests": { "md5": "dd5f3c9baaff9dac1984733dd210b9c0", "sha256": "874178c98400fd09681773ee02424b48f1bcc4b67acc81edb305ee7bccaf03ed" }, "downloads": -1, "filename": "magic_constraints-0.2.0rc6.tar.gz", "has_sig": false, "md5_digest": "dd5f3c9baaff9dac1984733dd210b9c0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18890, "upload_time": "2016-04-24T17:37:46", "url": "https://files.pythonhosted.org/packages/9c/78/2d719949ebbf7cfed84791b1f932807360bfd8927bcac8235e373172caaf/magic_constraints-0.2.0rc6.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "9e03d996c04b7cc5d59334832f62f510", "sha256": "14231319c3759d3cdafbfc8a2d8f0532b11de3d7dc8628b8693d6ba14b4676b3" }, "downloads": -1, "filename": "magic_constraints-0.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9e03d996c04b7cc5d59334832f62f510", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 21105, "upload_time": "2016-04-25T13:35:29", "url": "https://files.pythonhosted.org/packages/e4/3d/3ba3b8ae7a6cc6ae0ebf57ad827df0923082b676d8e626011e77d16b00c5/magic_constraints-0.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d7a2ee2900da657449e0fd611bec3efb", "sha256": "7d55a1e1e465125d7fc627add17c5d6b558491fa31b21fe946e798f458b3fcb1" }, "downloads": -1, "filename": "magic_constraints-0.3.0.tar.gz", "has_sig": false, "md5_digest": "d7a2ee2900da657449e0fd611bec3efb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21889, "upload_time": "2016-04-25T13:35:19", "url": "https://files.pythonhosted.org/packages/f6/76/a76bfcd6fcd76edfec2e456520a733112d8dbd805e93f71742308d1280b5/magic_constraints-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "afd2720e64402674ed0ad9ea93f76a6d", "sha256": "d4cd99f628ec566b082d3331848e9e99c1d3c0058d0249d776e14a4c04a824ca" }, "downloads": -1, "filename": "magic_constraints-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "afd2720e64402674ed0ad9ea93f76a6d", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 17081, "upload_time": "2016-05-03T05:35:11", "url": "https://files.pythonhosted.org/packages/a8/4e/5ce24d89b0a4c81b2a4f23c108235981df6baf48d4415165e2dc2c2a4d28/magic_constraints-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d9922a13e334ab1eca92afd742d275c", "sha256": "1019fa0d601e263ea53e434f6ce5a79652ab0c631408b0f1b8e6d6352e00bab6" }, "downloads": -1, "filename": "magic_constraints-0.4.0.tar.gz", "has_sig": false, "md5_digest": "0d9922a13e334ab1eca92afd742d275c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20604, "upload_time": "2016-05-03T05:35:05", "url": "https://files.pythonhosted.org/packages/4b/ec/3b1300c280a17f28cdc3dc0d5875af0868b426fca6e38bf455a4b05ffa29/magic_constraints-0.4.0.tar.gz" } ], "0.4rc0": [ { "comment_text": "", "digests": { "md5": "e345de9c66358e66d629869412402de2", "sha256": "f9aa1486d6eb17476a1fec6285995542ed5737ed4ba512b74b7d2ed12163bfa7" }, "downloads": -1, "filename": "magic_constraints-0.4rc0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e345de9c66358e66d629869412402de2", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 17098, "upload_time": "2016-05-03T05:27:24", "url": "https://files.pythonhosted.org/packages/de/c9/89c17e61f28211d863804a52c5903aaa8a0892b2080f672ba635701fbbca/magic_constraints-0.4rc0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "af40bcab3161ff8eba6fbb260f70fa23", "sha256": "d3f89057134778a788b6f599a8334a583911e70184f87052b63c55dd3f722da8" }, "downloads": -1, "filename": "magic_constraints-0.4rc0.tar.gz", "has_sig": false, "md5_digest": "af40bcab3161ff8eba6fbb260f70fa23", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20707, "upload_time": "2016-05-03T05:27:18", "url": "https://files.pythonhosted.org/packages/fc/49/9abcd890f5bb9e57f515792b13e86dd47591fea685331a371c5bce97b639/magic_constraints-0.4rc0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "afd2720e64402674ed0ad9ea93f76a6d", "sha256": "d4cd99f628ec566b082d3331848e9e99c1d3c0058d0249d776e14a4c04a824ca" }, "downloads": -1, "filename": "magic_constraints-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "afd2720e64402674ed0ad9ea93f76a6d", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 17081, "upload_time": "2016-05-03T05:35:11", "url": "https://files.pythonhosted.org/packages/a8/4e/5ce24d89b0a4c81b2a4f23c108235981df6baf48d4415165e2dc2c2a4d28/magic_constraints-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d9922a13e334ab1eca92afd742d275c", "sha256": "1019fa0d601e263ea53e434f6ce5a79652ab0c631408b0f1b8e6d6352e00bab6" }, "downloads": -1, "filename": "magic_constraints-0.4.0.tar.gz", "has_sig": false, "md5_digest": "0d9922a13e334ab1eca92afd742d275c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20604, "upload_time": "2016-05-03T05:35:05", "url": "https://files.pythonhosted.org/packages/4b/ec/3b1300c280a17f28cdc3dc0d5875af0868b426fca6e38bf455a4b05ffa29/magic_constraints-0.4.0.tar.gz" } ] }