{ "info": { "author": "Matthias Bussonnier", "author_email": "bussonniermatthias@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License" ], "description": "warn\n====\n\nBetter warnings.\n\nSee the full `documentation `__.\n\nThe Python standard `warning\nmodule `__ is extremely\ngood, and I believe underutilized; Though it missed a few functionality;\nin particular it allows filtering only on the code that triggered/called\na deprecated functions, but have no ability to filter depending on the\nmodule that emitted the warning.\n\nThis is an attempt to fix that.\n\nToo long didn't read:\n---------------------\n\nExplicit is better than implicit:\n\n::\n\n from warn import patch\n patch()\n\n # use the warning module as usual\n\nThough the ``warnings.filterwarning`` function has now gained the\n``emodule`` keyword parameter to filer by the module that emitted the\nwarning; example:\n\n::\n\n import warnings\n warnings.filter('default', category=DeprecationWarnings, emodule='matplotlib\\.pyplot.*')\n\nAll warnings from ``matplotlib.pyplot`` and its submodule will now be\nshow by default, regardless of whether you trigger them directly, via\npandas, seaborn, your own code...\n\nWarning emitter, warning caller.\n--------------------------------\n\nPython warnings are a beautiful relative simple piece of code which is\nextremely powerful in the right hands once you learned how to use it.\n\nIt allows you to determine a posteriori whether you want a particular\npiece of code to trigger an exception, display a message to the user or\nsimply do nothing.\n\nIt is difficult to show the full power of the waring with a simple piece\nof code, but in large code base, and once you start having several layer\nof dependency a parsimonious usage of warning , and in particular\n``DeprecationWarning`` can make a large difference.\n\nCaller, vs Emitter\n~~~~~~~~~~~~~~~~~~\n\nLet's clear up some vocabulary first, to differentiate the warning\n\"Caller\" from the warning \"Emitter\"\n\n.. code:: python\n\n # file emitter.py\n\n def public_api(param1, deprecated_parameter=None)::\n\n if deprecated_parameter:\n return _deprecated_function(param1, deprecated_parameter):\n else:\n return normal_buisnell_logic(param1)\n\n\n def _deprecated_function(param1, deprecated_parameter):\n import warningsA\n # warning emitted here\n warnings.warn('using `deprecated_parameter` is deprecated ',\n DeprecationWarning,\n stacklevel=3)\n\n.. code:: python\n\n # file caller.py\n from emitter import public_api\n public_api(1, True) # warning triggered here.\n\nyou can now do something like\n\n.. code:: python\n\n from warn import path\n patch()\n\n import warnings\n warnings.filter('default', category=DeprecationWarnings, emodule='emitter.*')\n import emitter\n emitter.bar() # will log the warning !\n\nChange this to \"error\" in your test-suite, and filter by all your\ndependencies !\n\nThe Python built-in module allow you to filter warning by caller\n(assuming the emitter have set the ``stacklevel`` options right, which\nis not always obvious to do). This is extremely useful when you are\ndeveloping the caller; but not that much when you are developing the\nemitter.\n\nIt is common for a caller to actually have many underlying library the\ncan trigger warnings, or for a developer to only care about a subset of\nthe emitter warnings.\n\nMany libraries are going around this limitation by sub-classing\nWarnings; two example are\n`Matplolib `__\nand\n`sympy `__\nin order to selectively enable them. Still this only give a coarse way\nof filtering warnings, and it required to know where the warnings are\ndefined in order to import and filter for them.\n\nBecause of Python default choice to filter out deprecation warnings,\nthis also forced either inherit ``UserWarning`` (choice of matplotlib),\nwhich removes the semantic meaning of ``DeprecationWarning`` offered by\nPython or to inject a custom filter in the warnings filter module on\nimport (choice of Sympy), which can lead to surprising behavior.\n\nAvailability on Python 2\n------------------------\n\nI don't know if if works on Python 2; I don't really have the time to\ninvestigate; I don't particularly care a lot; but feel free to send a PR\nthat ads support if necessary I would be happy to merge it.\n\nlimitations\n-----------\n\nThis does not work on packages that either :\n\n- Got and keep a reference on ``warnings.warn`` before ``patch()`` have\n been called; that is to say things of the form:\n ``from warnings iport warn``\n\n- Cannot work on C-extensions (aka won't filter on ``numpy``) ; Both of\n the above are technically possible with Assembly Patching which I'm\n not confortable with.\n\nThe Ugly\n--------\n\nAs Warnings filters *have to be 5 tuples with specific types* this works\nby shoving dummy instances in the filters list and using this as keys\nfor a proxy to lookup real filter keys. So worse case scenario the\nfilter you insert with this module will just be no-op. But you will\nincur a performance penalty if you use this, especially if your codebase\ntriggers a lot of warnings.\n\nGet the upstream\n----------------\n\nI'd **love** feedback and have a nicer API to deal with warnings at\nCPython level in order to provide custom filters, and custom filters\nfunctions.\n\nApart\u00e9\n======\n\nGood Deprecation Warnings.\n--------------------------\n\nA good warning and in particular Deprecation warning is extremely\nhelpful and can make the difference for the adoption of an API. Take the\nfollowing fiction example:\n\n.. code:: python\n\n >>> import warnings\n\n >>> warnings.simplefilter('default')\n\n >>> from quezetraste import frobulate, constribule\n\n >>> frobulate('HI', 3)\n DeprecationWarning: The 'frobulate' function is deprecated.\n\n >>> contribule('Hi', 3)\n\n DeprecationWarning: The 'constribule(message, recipient_id)' function of the\n 'quezetraste' package is deprecated since version 7.3. It\n haz been replaced by 'Recipient(id).send(message)' which\n was available since 7.2. See http://url.to/documentation/#1337\n\nTurn the DeprecationWarnings into error in your test-suite!\n-----------------------------------------------------------\n\nAt least make them visible; at best once you fixed a deprecation warning\nturn **this specific one** into an error to not reproduce it.\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Carreau/warn", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "warn", "package_url": "https://pypi.org/project/warn/", "platform": "", "project_url": "https://pypi.org/project/warn/", "project_urls": { "Homepage": "https://github.com/Carreau/warn" }, "release_url": "https://pypi.org/project/warn/0.1.0/", "requires_dist": null, "requires_python": "~=3.3", "summary": "A more flexible warning module. ", "version": "0.1.0" }, "last_serial": 2324652, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "e50eec36dfdd72bd0f592565ed0730f9", "sha256": "3c6c75e90ee426ab402ff5eff80d6fa061b1c8ffab4c58817cd6dddf10f2ae44" }, "downloads": -1, "filename": "warn-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "e50eec36dfdd72bd0f592565ed0730f9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">3", "size": 14904, "upload_time": "2016-08-27T00:34:55", "url": "https://files.pythonhosted.org/packages/46/57/0ad7aceae59194e778a9fff9b05923b8a7990ad153b829f316d58708adc4/warn-0.0.1-py3-none-any.whl" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "b2a4edddf402c8c0bebb0146415b3294", "sha256": "12d7b9728cea836a5835a3014ee5dca6b881928aa3c6825c1c7aff2ad1470181" }, "downloads": -1, "filename": "warn-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b2a4edddf402c8c0bebb0146415b3294", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": "~=3.3", "size": 23622, "upload_time": "2016-09-04T23:24:35", "url": "https://files.pythonhosted.org/packages/00/73/8f83635cecd46458d6fbffc6e6a3906babd0c79ab96fa72624bc0580c9a0/warn-0.1.0-py2.py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "b2a4edddf402c8c0bebb0146415b3294", "sha256": "12d7b9728cea836a5835a3014ee5dca6b881928aa3c6825c1c7aff2ad1470181" }, "downloads": -1, "filename": "warn-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b2a4edddf402c8c0bebb0146415b3294", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": "~=3.3", "size": 23622, "upload_time": "2016-09-04T23:24:35", "url": "https://files.pythonhosted.org/packages/00/73/8f83635cecd46458d6fbffc6e6a3906babd0c79ab96fa72624bc0580c9a0/warn-0.1.0-py2.py3-none-any.whl" } ] }