[Python-modules-commits] [python-deprecation] 01/03: import python-deprecation_1.0.1.orig.tar.gz
Ondrej Koblizek
kobla-guest at moszumanska.debian.org
Fri Aug 4 16:39:08 UTC 2017
This is an automated email from the git hooks/post-receive script.
kobla-guest pushed a commit to branch master
in repository python-deprecation.
commit 83c47129f909290e996f04ae216b1bc3e164f529
Author: Ondřej Kobližek <ondrej.koblizek at firma.seznam.cz>
Date: Fri Aug 4 11:34:53 2017 -0400
import python-deprecation_1.0.1.orig.tar.gz
---
LICENSE | 201 +++++++++++++++++++++++++++++++++++++++++++
MANIFEST.in | 1 +
README.rst | 83 ++++++++++++++++++
deprecation.py | 212 ++++++++++++++++++++++++++++++++++++++++++++++
docs/Makefile | 20 +++++
docs/conf.py | 154 +++++++++++++++++++++++++++++++++
docs/index.rst | 104 +++++++++++++++++++++++
docs/sample.rst | 10 +++
example.py | 10 +++
sample.py | 41 +++++++++
setup.py | 33 ++++++++
test-requirements.txt | 4 +
tests/__init__.py | 0
tests/test_deprecation.py | 128 ++++++++++++++++++++++++++++
tox.ini | 24 ++++++
15 files changed, 1025 insertions(+)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8dada3e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..1aba38f
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+include LICENSE
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..75d8d93
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,83 @@
+deprecation
+===========
+
+.. image:: https://readthedocs.org/projects/deprecation/badge/?version=latest
+ :target: http://deprecation.readthedocs.io/en/latest/
+ :alt: Documentation Status
+
+.. image:: https://travis-ci.org/briancurtin/deprecation.svg?branch=master
+ :target: https://travis-ci.org/briancurtin/deprecation
+
+.. image:: https://codecov.io/gh/briancurtin/deprecation/branch/master/graph/badge.svg
+ :target: https://codecov.io/gh/briancurtin/deprecation
+
+The ``deprecation`` library provides a ``deprecated`` decorator and a
+``fail_if_not_removed`` decorator for your tests. Together, the two
+enable the automation of several things:
+
+1. The docstring of a deprecated method gets the deprecation details
+ appended to the end of it. If you generate your API docs direct
+ from your source, you don't need to worry about writing your own
+ notification. You also don't need to worry about forgetting to
+ write it. It's done for you.
+2. Rather than having code live on forever because you only deprecated
+ it but never actually moved on from it, you can have your tests
+ tell you when it's time to remove the code. The ``@deprecated``
+ decorator can be told when it's time to entirely remove the code,
+ which causes ``@fail_if_not_removed`` to raise an ``AssertionError``,
+ causing either your unittest or py.test tests to fail.
+
+See http://deprecation.readthedocs.io/ for the full documentation.
+
+Installation
+============
+
+ ::
+
+ pip install deprecation
+
+Usage
+=====
+
+ ::
+
+ import deprecation
+
+ @deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
+ current_version=__version__,
+ details="Use the bar function instead")
+ def foo():
+ """Do some stuff"""
+ return 1
+
+...but doesn't Python ignore ``DeprecationWarning``?
+====================================================
+
+Yes, by default since 2.7—and for good reason [#]_ —and this works fine
+with that.
+
+1. It often makes sense for you to run your tests with a ``-W`` flag or
+ the ``PYTHONWARNINGS`` environment variable so you catch warnings
+ in development and handle them appropriately. The warnings raised by
+ this library show up there, as they're subclasses of the built-in
+ ``DeprecationWarning``. See the `Command Line
+ <https://docs.python.org/2/using/cmdline.html#cmdoption-W>`_
+ and `Environment Variable
+ <https://docs.python.org/2/using/cmdline.html#envvar-PYTHONWARNINGS>`_
+ documentation for more details.
+2. Even if you don't enable those things, the behavior of this library
+ remains the same. The docstrings will still be updated and the tests
+ will still fail when they need to. You'll get the benefits regardless
+ of what Python cares about ``DeprecationWarning``.
+
+----
+
+.. [#] Exposing application users to ``DeprecationWarning``\s that are
+ emitted by lower-level code needlessly involves end-users in
+ "how things are done." It often leads to users raising issues
+ about warnings they're presented, which on one hand is done
+ rightfully so, as it's been presented to them as some sort of
+ issue to resolve. However, at the same time, the warning could
+ be well known and planned for. From either side, loud
+ ``DeprecationWarning``\s can be seen as noise that isn't
+ necessary outside of development.
diff --git a/deprecation.py b/deprecation.py
new file mode 100644
index 0000000..4a07e0f
--- /dev/null
+++ b/deprecation.py
@@ -0,0 +1,212 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from distutils import version
+import functools
+import warnings
+
+__version__ = "1.0"
+
+# This is mostly here so automodule docs are ordered more ideally.
+__all__ = ["deprecated", "fail_if_not_removed",
+ "DeprecatedWarning", "UnsupportedWarning"]
+
+
+class DeprecatedWarning(DeprecationWarning):
+ """A warning class for deprecated methods
+
+ This is a specialization of the built-in :class:`DeprecationWarning`,
+ adding parameters that allow us to get information into the __str__
+ that ends up being sent through the :mod:`warnings` system.
+ The attributes aren't able to be retrieved after the warning gets
+ raised and passed through the system as only the class--not the
+ instance--and message are what gets preserved.
+
+ :param function: The function being deprecated.
+ :param deprecated_in: The version that ``function`` is deprecated in
+ :param removed_in: The version that ``function`` gets removed in
+ :param details: Optional details about the deprecation. Most often
+ this will include directions on what to use instead
+ of the now deprecated code.
+ """
+
+ def __init__(self, function, deprecated_in, removed_in, details=""):
+ # NOTE: The docstring only works for this class if it appears up
+ # near the class name, not here inside __init__. I think it has
+ # to do with being an exception class.
+ self.function = function
+ self.deprecated_in = deprecated_in
+ self.removed_in = removed_in
+ self.details = details
+ super(DeprecatedWarning, self).__init__()
+
+ def __str__(self):
+ return ("%s is deprecated as of %s and will "
+ "be removed in %s. %s" % (self.function, self.deprecated_in,
+ self.removed_in, self.details))
+
+
+class UnsupportedWarning(DeprecatedWarning):
+ """A warning class for methods to be removed
+
+ This is a subclass of :class:`~deprecation.DeprecatedWarning` and is used
+ to output a proper message about a function being unsupported.
+ Additionally, the :func:`~deprecation.fail_if_not_removed` decorator
+ will handle this warning and cause any tests to fail if the system
+ under test uses code that raises this warning.
+ """
+
+ def __str__(self):
+ return ("%s is unsupported as of %s. %s" % (self.function,
+ self.removed_in,
+ self.details))
+
+
+def deprecated(deprecated_in=None, removed_in=None, current_version=None,
+ details=""):
+ """Decorate a function to signify its deprecation
+
+ This function wraps a method that will soon be removed and does two things:
+ * The docstring of the method will be modified to include a notice
+ about deprecation, e.g., "Deprecated since 0.9.11. Use foo instead."
+ * Raises a :class:`~deprecation.DeprecatedWarning`
+ via the :mod:`warnings` module, which is a subclass of the built-in
+ :class:`DeprecationWarning`. Note that built-in
+ :class:`DeprecationWarning`\s are ignored by default, so for users
+ to be informed of said warnings they will need to enable them--see
+ the :mod:`warnings` module documentation for more details.
+
+ :param deprecated_in: The version at which the decorated method is
+ considered deprecated. This will usually be the
+ next version to be released when the decorator is
+ added. The default is **None**, which effectively
+ means immediate deprecation. If this is not
+ specified, then the `removed_in` and
+ `current_version` arguments are ignored.
+ :param removed_in: The version when the decorated method will be removed.
+ The default is **None**, specifying that the function
+ is not currently planned to be removed.
+ Note: This cannot be set to a value if
+ `deprecated_in=None`.
+ :param current_version: The source of version information for the
+ currently running code. This will usually be
+ a `__version__` attribute on your library.
+ The default is `None`.
+ When `current_version=None` the automation to
+ determine if the wrapped function is actually
+ in a period of deprecation or time for removal
+ does not work, causing a
+ :class:`~deprecation.DeprecatedWarning`
+ to be raised in all cases.
+ :param details: Extra details to be added to the method docstring and
+ warning. For example, the details may point users to
+ a replacement method, such as "Use the foo_bar
+ method instead". By default there are no details.
+ """
+ # You can't just jump to removal. It's weird, unfair, and also makes
+ # building up the docstring weird.
+ if deprecated_in is None and removed_in is not None:
+ raise TypeError("Cannot set removed_in to a value "
+ "without also setting deprecated_in")
+
+ # Only warn when it's appropriate. There may be cases when it makes sense
+ # to add this decorator before a formal deprecation period begins.
+ # In CPython, PendingDeprecatedWarning gets used in that period,
+ # so perhaps mimick that at some point.
+ is_deprecated = False
+ is_unsupported = False
+
+ # StrictVersion won't take a None or a "", so make whatever goes to it
+ # is at least *something*.
+ if current_version:
+ current_version = version.StrictVersion(current_version)
+
+ if (removed_in
+ and current_version >= version.StrictVersion(removed_in)):
+ is_unsupported = True
+ elif (deprecated_in
+ and current_version >= version.StrictVersion(deprecated_in)):
+ is_deprecated = True
+ else:
+ # If we can't actually calculate that we're in a period of
+ # deprecation...well, they used the decorator, so it's deprecated.
+ # This will cover the case of someone just using
+ # @deprecated("1.0") without the other advantages.
+ is_deprecated = True
+
+ should_warn = any([is_deprecated, is_unsupported])
+
+ def _function_wrapper(function):
+ if should_warn:
+ # Everything *should* have a docstring, but just in case...
+ existing_docstring = function.__doc__ or ""
+
+ # The various parts of this decorator being optional makes for
+ # a number of ways the deprecation notice could go. The following
+ # makes for a nicely constructed sentence with or without any
+ # of the parts.
+ parts = {
+ "deprecated_in":
+ " in %s" % deprecated_in if deprecated_in else "",
+ "removed_in":
+ ", to be removed in %s" % removed_in if removed_in else "",
+ "period":
+ "." if deprecated_in or removed_in or details else "",
+ "details":
+ " %s" % details if details else ""}
+
+ deprecation_note = ("*Deprecated{deprecated_in}{removed_in}"
+ "{period}{details}*".format(**parts))
+
+ function.__doc__ = "\n\n".join([existing_docstring,
+ deprecation_note])
+
+ @functools.wraps(function)
+ def _inner(*args, **kwargs):
+ if should_warn:
+ if is_unsupported:
+ cls = UnsupportedWarning
+ else:
+ cls = DeprecatedWarning
+
+ the_warning = cls(function.__name__, deprecated_in,
+ removed_in, details)
+ warnings.warn(the_warning)
+
+ return function(*args, **kwargs)
+ return _inner
+ return _function_wrapper
+
+
+def fail_if_not_removed(method):
+ """Decorate a test method to track removal of deprecated code
+
+ This decorator catches :class:`~deprecation.UnsupportedWarning`
+ warnings that occur during testing and causes unittests to fail,
+ making it easier to keep track of when code should be removed.
+
+ :raises: :class:`AssertionError` if an
+ :class:`~deprecation.UnsupportedWarning`
+ is raised while running the test method.
+ """
+ def _inner(*args, **kwargs):
+ with warnings.catch_warnings(record=True) as caught_warnings:
+ warnings.simplefilter("always")
+ rv = method(*args, **kwargs)
+
+ for warning in caught_warnings:
+ if warning.category == UnsupportedWarning:
+ raise AssertionError(
+ ("%s uses a function that should be removed: %s" %
+ (method, str(warning.message))))
+ return rv
+ return _inner
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..7aebaba
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SPHINXPROJ = deprecation
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..ee9da7e
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# deprecation documentation build configuration file, created by
+# sphinx-quickstart on Fri Jan 13 16:03:40 2017.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+sys.path.insert(0, os.path.abspath('../'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']
+intersphinx_mapping = {'python': ('https://docs.python.org/dev', None)}
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'deprecation'
+copyright = '2017, Brian Curtin'
+author = 'Brian Curtin'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '1.0'
+# The full version, including alpha/beta/rc tags.
+release = '1.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'nature'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+
+# -- Options for HTMLHelp output ------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'deprecationdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'deprecation.tex', 'deprecation Documentation',
+ 'Brian Curtin', 'manual'),
+]
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'deprecation', 'deprecation Documentation',
+ [author], 1)
+]
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'deprecation', 'deprecation Documentation',
+ author, 'deprecation', 'A library to handle automated deprecations.',
+ 'Miscellaneous'),
+]
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..321a0c9
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,104 @@
+.. deprecation documentation master file, created by
+ sphinx-quickstart on Fri Jan 13 16:03:40 2017.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+``deprecation``
+===============
+
+``deprecation`` is a library that enables automated deprecations. It offers
+the :func:`~deprecation.deprecated` decorator to wrap functions, providing
+proper warnings both in documentation and via Python's :mod:`warnings` system,
+as well as the :func:`deprecation.fail_if_not_removed` decorator for test
+methods to ensure that deprecated code is eventually removed.
+
+See `API Documentation`_ to jump straight into the options.
+
+Installation
+============
+
+ ::
+
+ pip install deprecation
+
+Using ``@deprecated``
+=====================
+
+To mark a function or method as deprecated, wrap it in the
+:func:`~deprecation.deprecated` decorator. This does several things for you:
+
+1. The docstring of the wrapped function will have details appended
+ to it from the arguments you set on :func:`~deprecation.deprecated`.
+ This takes care of telling your users not only that the function
+ is deprecated, but can also tell them when it's going away and
+ what they can do in the meantime.
+2. In conjunction with the :func:`~deprecation.fail_if_not_removed`
+ decorator it removes the need for any sort of manual tracking of
+ when a sufficiently deprecated piece of code should be removed
+ from the codebase. It causes tests to fail when they contain
+ code which should be removed.
+
+ ::
+
+ import deprecation
+
+ @deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
+ current_version=__version__,
+ details="Use the bar function instead")
+ def foo():
+ """Do some stuff"""
+ return 1
+
+Now look at the docs. If you you generate API documentation from your source
+like the :doc:`sample` module does, you'll see that the a sentence has been
+appended to a deprecated function's docstring to include information about
+when the function is deprecated, when it'll be removed, and what you can do
+instead. For example, run ``help(foo)`` and this is what you'll get:
+
+ ::
+
+ Help on function foo in module example:
+
+ foo()
+ Do some stuff
+
+ *Deprecated in 1.0, to be removed in 2.0. Use the bar function instead*
+
+You can pass varying amounts of detail to this decorator, but note that
+in most cases it removes the ability to use
+:func:`~deprecation.fail_if_not_removed`. See the `API Documentation`_
+for full details.
+
+Using ``@fail_if_not_removed``
+==============================
+
+Once you've marked code for deprecation via :func:`~deprecation.deprecated`,
+you can sit back and relax as most of the work has been done for you.
+Assuming you've provided sufficient detail to the decorator, you now just
+wait for your tests to tell you it's time to delete the code in question.
+
+If you wrap test methods which use your now deprecated code in
+:func:`~deprecation.fail_if_not_removed`, the test will fail with a message
+notifying you that you should remove this code.
+
+ ::
+
+ @deprecation.fail_if_not_removed
+ def test_won(self):
+ self.assertEqual(1, won())
+
+Looking at the :doc:`sample` docs, we can see that this function would
+fail the tests at version 2.0, when it should be removed. The following
+shows what test output will look like for a failure.
+
+ ::
+
+ AssertionError: <function Tests.test_won at 0x10af33268> uses a function
+ that should be removed: who is unsupported as of 2.0. Use the ``one``
+ function instead
+
+API Documentation
+=================
+
+.. automodule:: deprecation
+ :members:
diff --git a/docs/sample.rst b/docs/sample.rst
new file mode 100644
index 0000000..d27d673
--- /dev/null
+++ b/docs/sample.rst
@@ -0,0 +1,10 @@
+:orphan:
+
+``sample`` module
+=================
+
+The following documents the ``sample`` module to show what documentation
+looks like when :func:`~deprecation.deprecated` has modified it.
+
+.. automodule:: sample
+ :members:
diff --git a/example.py b/example.py
new file mode 100644
index 0000000..44dff18
--- /dev/null
+++ b/example.py
@@ -0,0 +1,10 @@
+import deprecation
+__version__ = "1.5"
+
+
+ at deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
+ current_version=__version__,
+ details="Use the bar function instead")
+def foo():
+ """Do some stuff"""
+ return 1
diff --git a/sample.py b/sample.py
new file mode 100644
index 0000000..be00938
--- /dev/null
+++ b/sample.py
@@ -0,0 +1,41 @@
+import unittest2
+
+import deprecation
+
+__version__ = "1.5"
+
+
+ at deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
+ current_version=__version__,
+ details="Use the ``one`` function instead")
+def won():
+ """This function returns 1"""
+ # Oops, it's one, not won. Let's deprecate this and get it right.
+ return 1
+
+
+def one():
+ """This function returns 1"""
+ return 1
+
+
+ at deprecation.deprecated(deprecated_in="1.0", removed_in="1.5",
+ current_version=__version__,
+ details="Why would you ever do this anyway?")
+def why():
+ """This isn't necessary"""
+ return None
+
+
+class Tests(unittest2.TestCase):
+
+ @deprecation.fail_if_not_removed
+ def test_won(self):
+ self.assertEqual(1, won())
+
+ @deprecation.fail_if_not_removed
+ def test_why(self):
+ self.assertIsNone(why())
+
+ def test_one(self):
+ self.assertEqual(1, one())
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..ea8feed
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,33 @@
+import io
+from setuptools import setup
+
+AUTHOR = "Brian Curtin"
+EMAIL = "brian at python.org"
+
+
+setup(name="deprecation",
+ version="1.0.1",
+ description="A library to handle automated deprecations",
+ license="Apache 2",
+ url="http://deprecation.readthedocs.io/",
+ author=AUTHOR,
+ author_email=EMAIL,
+ maintainer=AUTHOR,
+ maintainer_email=EMAIL,
+ keywords=["deprecation"],
+ long_description=io.open("README.rst", encoding="utf-8").read(),
+ py_modules=["deprecation"],
+ classifiers=[
+ "Development Status :: 5 - Production/Stable",
+ "License :: OSI Approved :: Apache Software License",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.4",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: Implementation :: CPython",
+ "Programming Language :: Python :: Implementation :: PyPy",
+ "Topic :: Software Development :: Libraries :: Python Modules"]
+ )
diff --git a/test-requirements.txt b/test-requirements.txt
new file mode 100644
index 0000000..b292a77
--- /dev/null
+++ b/test-requirements.txt
@@ -0,0 +1,4 @@
+codecov>=2.0
+coverage>=4.3
+flake8>=3.2
+unittest2>=1.1
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_deprecation.py b/tests/test_deprecation.py
new file mode 100644
index 0000000..3364f9c
--- /dev/null
+++ b/tests/test_deprecation.py
@@ -0,0 +1,128 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# As we unfortunately support Python 2.7, it lacks TestCase.subTest which
+# is in 3.4+ or in unittest2
+import unittest2
+import warnings
+
+import deprecation
+
+
+class Test_deprecated(unittest2.TestCase):
+
... 136 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-deprecation.git
More information about the Python-modules-commits
mailing list