[Git][debian-gis-team/python-deprecated][upstream] New upstream version 1.2.8

Bas Couwenberg gitlab at salsa.debian.org
Mon Apr 6 04:54:19 BST 2020



Bas Couwenberg pushed to branch upstream at Debian GIS Project / python-deprecated


Commits:
dbbd9d74 by Bas Couwenberg at 2020-04-06T05:46:12+02:00
New upstream version 1.2.8
- - - - -


24 changed files:

- .bumpversion.cfg
- CHANGELOG.rst
- MANIFEST.in
- README.md
- deprecated/__init__.py
- deprecated/classic.py
- deprecated/sphinx.py
- + docs/source/_static/banner.png
- docs/source/_static/logo-full.png
- docs/source/conf.py
- docs/source/index.rst
- + docs/source/sphinx/calc_mean.py
- + docs/source/sphinx/calc_mean_deco.py
- docs/source/tutorial/v5/sphinx_demo.py → docs/source/sphinx/sphinx_demo.py
- + docs/source/sphinx/use_calc_mean_deco.py
- + docs/source/sphinx_deco.rst
- docs/source/tutorial.rst
- + docs/source/tutorial/warning_ctrl/filter_action_demo.py
- + docs/source/tutorial/warning_ctrl/filter_warnings_demo.py
- + docs/source/tutorial/warning_ctrl/warning_classes_demo.py
- python-deprecated.spec
- setup.py
- tests/test_deprecated.py
- tox.ini


Changes:

=====================================
.bumpversion.cfg
=====================================
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 1.2.7
+current_version = 1.2.8
 commit = True
 tag = False
 message = Prepare next version {new_version} (unreleased)


=====================================
CHANGELOG.rst
=====================================
@@ -18,6 +18,40 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
       (only in comment or documentation).
 
 
+v1.2.8 (2020-04-05)
+===================
+
+Bug fix release
+
+Fix
+---
+
+- Fix #15: The ``@deprecated`` decorator doesn't set a warning filter if the *action* keyword argument is
+  not provided or ``None``. In consequences, the warning messages are only emitted if the global filter allow it.
+  For more information, see `The Warning Filter <https://docs.python.org/3/library/warnings.html#the-warnings-filter>`_
+  in the Python documentation.
+
+- Fix #13: Warning displays the correct filename and line number when decorating a class if wrapt
+  does not have the compiled c extension.
+
+Documentation
+-------------
+
+- The :ref:`api` documentation and the :ref:`tutorial` is improved to explain how to use
+  custom warning categories and local filtering (warning filtering at function call).
+
+- Fix #17: Customize the sidebar to add links to the documentation to the source in GitHub and to the Bug tracker.
+  Add a logo in the sidebar and change the logo in the main page to see the library version.
+
+- Add a detailed documentation about :ref:`sphinx_deco`.
+
+
+Other
+-----
+
+- Change the Tox configuration to test the library with Wrapt 1.12.x.
+
+
 v1.2.7 (2019-11-11)
 ===================
 
@@ -26,7 +60,7 @@ Bug fix release
 Fix
 ---
 
-- Warning displays the correct filename and line number when decorating a function if wrapt
+- Fix #13: Warning displays the correct filename and line number when decorating a function if wrapt
   does not have the compiled c extension.
 
 Other


=====================================
MANIFEST.in
=====================================
@@ -8,6 +8,8 @@ include .coveragerc
 include .editorconfig
 
 include *.rst
+include *.spec
+include *.yaml
 include *.yml
 include Makefile
 include tox.ini


=====================================
README.md
=====================================
@@ -59,7 +59,7 @@ def some_old_function(x, y):
 ## Authors
 
 The authors of this library are:
-[Marcos CARDOSO](https://github.com/tantale), and
+[Marcos CARDOSO](https://github.com/vrcmarcos), and
 [Laurent LAPORTE](https://github.com/tantale).
 
 The original code was made in [this StackOverflow post](https://stackoverflow.com/questions/2536307) by


=====================================
deprecated/__init__.py
=====================================
@@ -8,6 +8,6 @@ Python ``@deprecated`` decorator to deprecate old python classes, functions or m
 """
 
 #: Module Version Number, see `PEP 396 <https://www.python.org/dev/peps/pep-0396/>`_.
-__version__ = "1.2.7"
+__version__ = "1.2.8"
 
 from deprecated.classic import deprecated


=====================================
deprecated/classic.py
=====================================
@@ -5,6 +5,7 @@ Classic deprecation warning
 
 Classic ``@deprecated`` decorator to deprecate old python classes, functions or methods.
 
+.. _The Warnings Filter: https://docs.python.org/3/library/warnings.html#the-warnings-filter
 """
 import functools
 import inspect
@@ -17,11 +18,11 @@ try:
     # stack level that should be passed to warnings.warn should be 2. However, if using
     # a pure python wrapt, a extra stacklevel is required.
     import wrapt._wrappers
+
     _stacklevel = 2
 except ImportError:
     _stacklevel = 3
 
-
 string_types = (type(b''), type(u''))
 
 
@@ -76,7 +77,7 @@ class ClassicAdapter(wrapt.AdapterFactory):
            return x + y
     """
 
-    def __init__(self, reason="", version="", action='always', category=DeprecationWarning):
+    def __init__(self, reason="", version="", action=None, category=DeprecationWarning):
         """
         Construct a wrapper adapter.
 
@@ -94,7 +95,8 @@ class ClassicAdapter(wrapt.AdapterFactory):
         :param action:
             A warning filter used to activate or not the deprecation warning.
             Can be one of "error", "ignore", "always", "default", "module", or "once".
-            By default the deprecation warning is always emitted (the value is "always").
+            If ``None`` or empty, the the global filtering mechanism is used.
+            See: `The Warnings Filter`_ in the Python documentation.
 
         :type  category: type
         :param category:
@@ -144,6 +146,9 @@ class ClassicAdapter(wrapt.AdapterFactory):
 
         .. versionchanged:: 1.2.4
            Don't pass arguments to :meth:`object.__new__` (other than *cls*).
+
+        .. versionchanged:: 1.2.8
+           The warning filter is not set if the *action* parameter is ``None`` or empty.
         """
         if inspect.isclass(wrapped):
             old_new1 = wrapped.__new__
@@ -151,8 +156,9 @@ class ClassicAdapter(wrapt.AdapterFactory):
             def wrapped_cls(cls, *args, **kwargs):
                 msg = self.get_deprecated_msg(wrapped, None)
                 with warnings.catch_warnings():
-                    warnings.simplefilter(self.action, self.category)
-                    warnings.warn(msg, category=self.category, stacklevel=2)
+                    if self.action:
+                        warnings.simplefilter(self.action, self.category)
+                    warnings.warn(msg, category=self.category, stacklevel=_stacklevel)
                 if old_new1 is object.__new__:
                     return old_new1(cls)
                 # actually, we don't know the real signature of *old_new1*
@@ -199,8 +205,8 @@ def deprecated(*args, **kwargs):
        class SomeOldClass(object):
            pass
 
-    You can give a "reason" message to help the developer to choose another function/class,
-    and a "version" number to specify the starting version number of the deprecation.
+    You can give a *reason* message to help the developer to choose another function/class,
+    and a *version* number to specify the starting version number of the deprecation.
 
     .. code-block:: python
 
@@ -211,6 +217,33 @@ def deprecated(*args, **kwargs):
        def some_old_function(x, y):
            return x + y
 
+    The *category* keyword argument allow you to specify the deprecation warning class of your choice.
+    By default, :exc:`DeprecationWarning` is ued but you can choose :exc:`FutureWarning`,
+    :exc:`PendingDeprecationWarning` or a custom subclass.
+
+    .. code-block:: python
+
+       from deprecated import deprecated
+
+
+       @deprecated(category=PendingDeprecationWarning)
+       def some_old_function(x, y):
+           return x + y
+
+    The *action* keyword argument allow you to locally change the warning filtering.
+    *action* can be one of "error", "ignore", "always", "default", "module", or "once".
+    If ``None``, empty or missing, the the global filtering mechanism is used.
+    See: `The Warnings Filter`_ in the Python documentation.
+
+    .. code-block:: python
+
+       from deprecated import deprecated
+
+
+       @deprecated(action="error")
+       def some_old_function(x, y):
+           return x + y
+
     """
     if args and isinstance(args[0], string_types):
         kwargs['reason'] = args[0]
@@ -220,7 +253,7 @@ def deprecated(*args, **kwargs):
         raise TypeError(repr(type(args[0])))
 
     if args:
-        action = kwargs.get('action', 'always')
+        action = kwargs.get('action')
         category = kwargs.get('category', DeprecationWarning)
         adapter_cls = kwargs.pop('adapter_cls', ClassicAdapter)
         adapter = adapter_cls(**kwargs)
@@ -236,7 +269,8 @@ def deprecated(*args, **kwargs):
             def wrapper_function(wrapped_, instance_, args_, kwargs_):
                 msg = adapter.get_deprecated_msg(wrapped_, instance_)
                 with warnings.catch_warnings():
-                    warnings.simplefilter(action, category)
+                    if action:
+                        warnings.simplefilter(action, category)
                     warnings.warn(msg, category=category, stacklevel=_stacklevel)
                 return wrapped_(*args_, **kwargs_)
 


=====================================
deprecated/sphinx.py
=====================================
@@ -40,7 +40,7 @@ class SphinxAdapter(ClassicAdapter):
     - The reason message is obviously added in the directive block if not empty.
     """
 
-    def __init__(self, directive, reason="", version="", action='always', category=DeprecationWarning):
+    def __init__(self, directive, reason="", version="", action=None, category=DeprecationWarning):
         """
         Construct a wrapper adapter.
 
@@ -62,7 +62,8 @@ class SphinxAdapter(ClassicAdapter):
         :param action:
             A warning filter used to activate or not the deprecation warning.
             Can be one of "error", "ignore", "always", "default", "module", or "once".
-            By default the deprecation warning is always emitted (the value is "always").
+            If ``None`` or empty, the the global filtering mechanism is used.
+            See: `The Warnings Filter`_ in the Python documentation.
 
         :type  category: type
         :param category:
@@ -170,7 +171,7 @@ def deprecated(*args, **kwargs):
     -   "action":
         A warning filter used to activate or not the deprecation warning..
         Can be one of "error", "ignore", "always", "default", "module", or "once".
-        By default the deprecation warning is always emitted (the value is "always").
+        If ``None``, empty or missing, the the global filtering mechanism is used.
 
     -   "category":
         The warning category to use for the deprecation warning.


=====================================
docs/source/_static/banner.png
=====================================
Binary files /dev/null and b/docs/source/_static/banner.png differ


=====================================
docs/source/_static/logo-full.png
=====================================
Binary files a/docs/source/_static/logo-full.png and b/docs/source/_static/logo-full.png differ


=====================================
docs/source/conf.py
=====================================
@@ -61,7 +61,7 @@ author = 'Marcos CARDOSO & Laurent LAPORTE'
 # built documents.
 #
 # The full version, including alpha/beta/rc tags.
-release = "1.2.7"
+release = "1.2.8"
 # The short X.Y version.
 version = release.rpartition('.')[0]
 


=====================================
docs/source/index.rst
=====================================
@@ -1,7 +1,7 @@
 Welcome to Deprecated
 =====================
 
-.. image:: _static/logo-full.png
+.. image:: _static/banner.png
    :alt: Deprecated: When once-stable features are removed in upcoming releases
 
 Welcome to Deprecated’s Documentation.
@@ -23,6 +23,7 @@ instructions for using Deprecated.
    installation
    introduction
    tutorial
+   sphinx_deco
    white_paper
 
 


=====================================
docs/source/sphinx/calc_mean.py
=====================================
@@ -0,0 +1,12 @@
+def mean(values):
+    """
+    Compute the arithmetic mean (“average”) of values.
+
+    :type  values: list[float]
+    :param values: List of floats
+    :return: Mean of values.
+
+    .. deprecated:: 2.5.0
+       Since Python 3.4, you can use the standard function :func:`statistics.mean`.
+    """
+    return sum(values) / len(values)


=====================================
docs/source/sphinx/calc_mean_deco.py
=====================================
@@ -0,0 +1,16 @@
+from deprecated.sphinx import deprecated
+
+
+ at deprecated(
+    reason="""Since Python 3.4, you can use the standard function :func:`statistics.mean`.""",
+    version="2.5.0",
+)
+def mean(values):
+    """
+    Compute the arithmetic mean (“average”) of values.
+
+    :type  values: list[float]
+    :param values: List of floats
+    :return: Mean of values.
+    """
+    return sum(values) / len(values)


=====================================
docs/source/tutorial/v5/sphinx_demo.py → docs/source/sphinx/sphinx_demo.py
=====================================
@@ -8,18 +8,18 @@ from deprecated.sphinx import versionchanged
     reason="""
     This is deprecated, really. So you need to use another function.
     But I don\'t know which one.
-    
+
        - The first,
        - The second.
-    
+
     Just guess!
     """,
     version='0.3.0',
 )
 @versionchanged(
     reason='Well, I add a new feature in this function. '
-    'It is very useful as you can see in the example below, so try it. '
-    'This is a very very very very very long sentence.',
+           'It is very useful as you can see in the example below, so try it. '
+           'This is a very very very very very long sentence.',
     version='0.2.0',
 )
 @versionadded(reason='Here is my new function.', version='0.1.0')
@@ -31,6 +31,3 @@ def successor(n):
     :return: number + 1
     """
     return n + 1
-
-
-help(successor)


=====================================
docs/source/sphinx/use_calc_mean_deco.py
=====================================
@@ -0,0 +1,3 @@
+from calc_mean_deco import mean
+
+print(mean.__doc__)


=====================================
docs/source/sphinx_deco.rst
=====================================
@@ -0,0 +1,157 @@
+.. _Sphinx: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html
+.. _Sphinx directives: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html
+.. _reStructuredText: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html
+.. _Markdown: https://www.sphinx-doc.org/en/master/usage/markdown.html
+.. _docstring: https://docs.python.org/3/glossary.html#term-docstring
+.. _autodoc: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html
+
+.. _sphinx_deco:
+
+The "Sphinx" decorators
+=======================
+
+Overview
+--------
+
+Developers use the Deprecated library to decorate deprecated functions or classes. This is very practical,
+but you know that this library does more: you can also document your source code! How?
+It's very simple: instead of using the "classic" decorator, you can use one of the "Sphinx" decorators.
+
+The "Sphinx" decorators have the same function as the "classic" decorator but also allow you to add
+`Sphinx directives`_ in your functions or classes documentation (inside the docstring_).
+
+.. attention::
+
+   In Python 3.3 and previous versions, the docstring of a class is immutable [#f1]_, this means that you cannot
+   use the "Sphinx" decorators. Naturally, this limitation does not exist in Python 3.4 and above.
+
+What is a Sphinx directive?
+---------------------------
+
+Sphinx_ is a tool that makes it easy to create intelligent and beautiful documentation.
+This tool uses the reStructuredText_ (or Markdown_) syntax to generate the documentation in different formats,
+the most common being HTML. Developers generally use this syntax to document the source code of their applications.
+
+Sphinx_ offers several directives allowing to introduce a text block with a predefined role.
+Among all the directives, the ones that interest us are those related to the functions (or classes)
+life cycle, namely: ``versionadded``, ``versionchanged`` and ``deprecated``.
+
+In the following example, the *mean()* function can be documented as follows:
+
+.. literalinclude:: sphinx/calc_mean.py
+
+Therefore, the "Sphinx" decorators allow you to add a Sphinx directive to your functions
+or classes documentation. In the case of the ``deprecated`` directive, it obviously allows you to emit a
+:exc:`DeprecationWarning` warning.
+
+Using the "Sphinx" decorators
+-----------------------------
+
+The previous example can be writen using a "Sphinx" decorator:
+
+.. literalinclude:: sphinx/calc_mean_deco.py
+
+You can see the generated documentation with this simple call:
+
+.. literalinclude:: sphinx/use_calc_mean_deco.py
+
+The documentation of the *mean()* function looks like this:
+
+.. code-block:: rst
+
+   Compute the arithmetic mean (“average”) of values.
+
+   :type  values: list[float]
+   :param values: List of floats
+   :return: Mean of values.
+
+   .. deprecated:: 2.5.0
+      Since Python 3.4, you can use the standard function
+      :func:`statistics.mean`.
+
+More elaborate example
+----------------------
+
+The Deprecated library offers you 3 decorators:
+
+- :func:`~deprecated.sphinx.deprecated`: insert a ``deprecated`` directive in docstring, and emit a warning on each call.
+- :func:`~deprecated.sphinx.versionadded`: insert a ``versionadded`` directive in docstring, don't emit warning.
+- :func:`~deprecated.sphinx.versionchanged`: insert a ``versionchanged`` directive in docstring, don't emit warning.
+
+The decorators can be combined to reflect the life cycle of a function:
+
+- When it is added in your API, with the ``@versionadded`` decorator,
+- When it has an important change, with the ``@versionchanged`` decorator,
+- When it is deprecated, with the ``@deprecated`` decorator.
+
+The example bellow illustrate this life cycle:
+
+.. literalinclude:: sphinx/sphinx_demo.py
+
+To see the result, you can use the builtin function :func:`help` to display a formatted help message
+of the *successor()* function. It is something like this:
+
+.. code-block:: text
+
+   Help on function successor in module __main__:
+
+   successor(n)
+       Calculate the successor of a number.
+
+       :param n: a number
+       :return: number + 1
+
+
+       .. versionadded:: 0.1.0
+          Here is my new function.
+
+
+       .. versionchanged:: 0.2.0
+          Well, I add a new feature in this function. It is very useful as
+          you can see in the example below, so try it. This is a very very
+          very very very long sentence.
+
+
+       .. deprecated:: 0.3.0
+          This is deprecated, really. So you need to use another function.
+          But I don't know which one.
+
+             - The first,
+             - The second.
+
+          Just guess!
+
+.. note:: Decorators must be writen in reverse order: recent first, older last.
+
+Building the documentation
+--------------------------
+
+The easiest way to build your API documentation is to use the autodoc_ plugin.
+The directives like ``automodule``, ``autoclass``, ``autofunction`` scan your source code
+and generate the documentation from your docstrings.
+
+Usually, the first thing that we need to do is indicate where the Python package that contains your
+source code is in relation to the ``conf.py`` file.
+
+But here, that will not work! The reason is that your modules must be imported during build:
+the Deprecated decorators must be interpreted.
+
+So, to build the API documentation of your project with Sphinx_ you need to setup a virtualenv,
+and install Sphinx, external themes and/or plugins and also your project..
+Nowadays, this is the right way to do it.
+
+For instance, you can configure a documentation building task in your ``tox.ini`` file, for instance:
+
+.. code-block:: ini
+
+   [testenv:docs]
+   basepython = python
+   deps =
+       sphinx
+   commands =
+       sphinx-build -b html -d {envtmpdir}/doctrees docs/source/ {envtmpdir}/html
+
+
+.. rubric:: Footnotes
+
+.. [#f1] See Issue 12773: `classes should have mutable docstrings <https://bugs.python.org/issue12773>`_.


=====================================
docs/source/tutorial.rst
=====================================
@@ -29,10 +29,10 @@ If the user tries to use the deprecated functions, he will have a warning for ea
 
    $ python use_liberty.py
 
-   using_liberty.py:4: DeprecationWarning: Call to deprecated function print_value.
+   using_liberty.py:4: DeprecationWarning: Call to deprecated function (or staticmethod) print_value.
      liberty.print_value("hello")
    'hello'
-   using_liberty.py:5: DeprecationWarning: Call to deprecated function print_value.
+   using_liberty.py:5: DeprecationWarning: Call to deprecated function (or staticmethod) print_value.
      liberty.print_value("hello again")
    'hello again'
    'Hi Tom!'
@@ -52,10 +52,10 @@ When the user calls the deprecated functions, he will have a more useful message
 
    $ python use_liberty.py
 
-   using_liberty.py:4: DeprecationWarning: Call to deprecated function print_value (This function is rotten, use 'better_print' instead).
+   using_liberty.py:4: DeprecationWarning: Call to deprecated function (or staticmethod) print_value. (This function is rotten, use 'better_print' instead)
      liberty.print_value("hello")
    'hello'
-   using_liberty.py:5: DeprecationWarning: Call to deprecated function print_value (This function is rotten, use 'better_print' instead).
+   using_liberty.py:5: DeprecationWarning: Call to deprecated function (or staticmethod) print_value. (This function is rotten, use 'better_print' instead)
      liberty.print_value("hello again")
    'hello again'
    'Hi Tom!'
@@ -78,10 +78,10 @@ He will have:
 
    $ python use_liberty.py
 
-   using_liberty.py:5: DeprecationWarning: Call to deprecated function print_value (This method is rotten, use 'better_print' instead).
+   using_liberty.py:5: DeprecationWarning: Call to deprecated method print_value. (This method is rotten, use 'better_print' instead)
      obj.print_value()
    'Greeting'
-   using_liberty.py:6: DeprecationWarning: Call to deprecated function print_value (This method is rotten, use 'better_print' instead).
+   using_liberty.py:6: DeprecationWarning: Call to deprecated method print_value. (This method is rotten, use 'better_print' instead)
      obj.print_value()
    'Greeting'
    'Greeting'
@@ -109,7 +109,7 @@ Once the object is initialised, no more warning are emitted.
 
    $ python use_liberty.py
 
-   using_liberty.py:4: DeprecationWarning: Call to deprecated class Liberty (This class is not perfect).
+   using_liberty.py:4: DeprecationWarning: Call to deprecated class Liberty. (This class is not perfect)
      obj = liberty.Liberty("Salutation")
    'Salutation'
    'Salutation'
@@ -121,3 +121,124 @@ As a reminder, the magic method ``__new__`` will be called when instance is bein
 Using this method you can customize the instance creation.
 the :func:`~deprecated.deprecated` decorator patches the ``__new__`` method in order to
 emmit the warning message before instance creation.
+
+
+Controlling warnings
+--------------------
+
+.. _Python warning control: https://docs.python.org/3/library/warnings.html
+.. _-W: https://docs.python.org/3/using/cmdline.html#cmdoption-w
+.. _PYTHONWARNINGS: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS
+
+Warnings are emitted using the `Python warning control`_. By default, Python installs several warning filters,
+which can be overridden by the `-W`_ command-line option, the `PYTHONWARNINGS`_ environment variable and
+calls to :func:`warnings.filterwarnings`. The warnings filter controls whether warnings are ignored, displayed,
+or turned into errors (raising an exception).
+
+For instance:
+
+.. literalinclude:: tutorial/warning_ctrl/filter_warnings_demo.py
+
+When the user runs this script, the deprecation warnings are ignored in the main program,
+so no warning message are emitted:
+
+.. code-block:: sh
+
+   $ python filter_warnings_demo.py
+
+   fun
+
+
+Deprecation warning classes
+---------------------------
+
+The :func:`deprecated.classic.deprecated` and :func:`deprecated.sphinx.deprecated` functions
+are using the :exc:`DeprecationWarning` category but you can customize them by using your own category
+(or hierarchy of categories).
+
+* *category* classes which you can use (among other) are:
+
+  +----------------------------------+-----------------------------------------------+
+  | Class                            | Description                                   |
+  +==================================+===============================================+
+  | :exc:`DeprecationWarning`        | Base category for warnings about deprecated   |
+  |                                  | features when those warnings are intended for |
+  |                                  | other Python developers (ignored by default,  |
+  |                                  | unless triggered by code in ``__main__``).    |
+  +----------------------------------+-----------------------------------------------+
+  | :exc:`FutureWarning`             | Base category for warnings about deprecated   |
+  |                                  | features when those warnings are intended for |
+  |                                  | end users of applications that are written in |
+  |                                  | Python.                                       |
+  +----------------------------------+-----------------------------------------------+
+  | :exc:`PendingDeprecationWarning` | Base category for warnings about features     |
+  |                                  | that will be deprecated in the future         |
+  |                                  | (ignored by default).                         |
+  +----------------------------------+-----------------------------------------------+
+
+You can define your own deprecation warning hierarchy based on the standard deprecation classes.
+
+For instance:
+
+.. literalinclude:: tutorial/warning_ctrl/warning_classes_demo.py
+
+When the user runs this script, the deprecation warnings for the 3.0 version are ignored:
+
+.. code-block:: sh
+
+   $ python warning_classes_demo.py
+
+    foo
+    bar
+    warning_classes_demo.py:30: DeprecatedIn26: Call to deprecated function (or staticmethod) foo. (deprecated function)
+      foo()
+
+
+Filtering warnings locally
+--------------------------
+
+The :func:`deprecated.classic.deprecated` and :func:`deprecated.sphinx.deprecated` functions
+can change the warning filtering locally (at function calls).
+
+* *action* is one of the following strings:
+
+  +---------------+----------------------------------------------+
+  | Value         | Disposition                                  |
+  +===============+==============================================+
+  | ``"default"`` | print the first occurrence of matching       |
+  |               | warnings for each location (module +         |
+  |               | line number) where the warning is issued     |
+  +---------------+----------------------------------------------+
+  | ``"error"``   | turn matching warnings into exceptions       |
+  +---------------+----------------------------------------------+
+  | ``"ignore"``  | never print matching warnings                |
+  +---------------+----------------------------------------------+
+  | ``"always"``  | always print matching warnings               |
+  +---------------+----------------------------------------------+
+  | ``"module"``  | print the first occurrence of matching       |
+  |               | warnings for each module where the warning   |
+  |               | is issued (regardless of line number)        |
+  +---------------+----------------------------------------------+
+  | ``"once"``    | print only the first occurrence of matching  |
+  |               | warnings, regardless of location             |
+  +---------------+----------------------------------------------+
+
+You can define the *action* keyword parameter to override the filtering warnings locally.
+
+For instance:
+
+.. literalinclude:: tutorial/warning_ctrl/filter_action_demo.py
+
+In this example, even if the global filter is set to "ignore", a call to the ``foo()``
+function will raise an exception because the *action* is set to "error".
+
+.. code-block:: sh
+
+   $ python filter_action_demo.py
+
+   Traceback (most recent call last):
+     File "filter_action_demo.py", line 12, in <module>
+       foo()
+     File "path/to/deprecated/classic.py", line 274, in wrapper_function
+       warnings.warn(msg, category=category, stacklevel=_stacklevel)
+   DeprecationWarning: Call to deprecated function (or staticmethod) foo. (do not call it)


=====================================
docs/source/tutorial/warning_ctrl/filter_action_demo.py
=====================================
@@ -0,0 +1,12 @@
+import warnings
+from deprecated import deprecated
+
+
+ at deprecated(reason="do not call it", action="error")
+def foo():
+    print("foo")
+
+
+if __name__ == '__main__':
+    warnings.simplefilter("ignore")
+    foo()


=====================================
docs/source/tutorial/warning_ctrl/filter_warnings_demo.py
=====================================
@@ -0,0 +1,12 @@
+import warnings
+from deprecated import deprecated
+
+
+ at deprecated(version='1.2.1', reason="deprecated function")
+def fun():
+    print("fun")
+
+
+if __name__ == '__main__':
+    warnings.simplefilter("ignore", category=DeprecationWarning)
+    fun()


=====================================
docs/source/tutorial/warning_ctrl/warning_classes_demo.py
=====================================
@@ -0,0 +1,31 @@
+import warnings
+
+from deprecated import deprecated
+
+
+class MyDeprecationWarning(DeprecationWarning):
+    """ My DeprecationWarning """
+
+
+class DeprecatedIn26(MyDeprecationWarning):
+    """ deprecated in 2.6 """
+
+
+class DeprecatedIn30(MyDeprecationWarning):
+    """ deprecated in 3.0 """
+
+
+ at deprecated(category=DeprecatedIn26, reason="deprecated function")
+def foo():
+    print("foo")
+
+
+ at deprecated(category=DeprecatedIn30, reason="deprecated function")
+def bar():
+    print("bar")
+
+
+if __name__ == '__main__':
+    warnings.filterwarnings("ignore", category=DeprecatedIn30)
+    foo()
+    bar()


=====================================
python-deprecated.spec
=====================================
@@ -2,7 +2,7 @@
 %global pkgname deprecated
 
 Name:           python-%{pkgname}
-Version:        1.2.7
+Version:        1.2.8
 Release:        2%{?dist}
 Summary:        Python decorator to deprecate old python classes, functions or methods
 License:        MIT
@@ -42,8 +42,8 @@ rm -rf %{pkgname}.egg-info
 
 
 %changelog
-* Fri Jul 26 2019 Petr Hracek <phracek at redhat.com> - 1.2.7-2
+* Fri Jul 26 2019 Petr Hracek <phracek at redhat.com> - 1.2.8-2
 - Fix python3_sitelib issue
 
-* Fri Jul 26 2019 Petr Hracek <phracek at redhat.com> - 1.2.7-1
+* Fri Jul 26 2019 Petr Hracek <phracek at redhat.com> - 1.2.8-1
 - Initial package


=====================================
setup.py
=====================================
@@ -143,7 +143,7 @@ from setuptools import setup
 
 setup(
     name='Deprecated',
-    version='1.2.7',
+    version='1.2.8',
     url='https://github.com/tantale/deprecated',
     project_urls={
         "Documentation": "https://deprecated.readthedocs.io/en/latest/",


=====================================
tests/test_deprecated.py
=====================================
@@ -241,3 +241,15 @@ def test_specific_warning_cls_is_used():
         foo()
     warn = warns[0]
     assert issubclass(warn.category, MyDeprecationWarning)
+
+
+def test_respect_global_filter():
+    @deprecated.classic.deprecated(version='1.2.1', reason="deprecated function")
+    def fun():
+        print("fun")
+
+    warnings.simplefilter("ignore", category=DeprecationWarning)
+
+    with warnings.catch_warnings(record=True) as warns:
+        fun()
+    assert len(warns) == 0


=====================================
tox.ini
=====================================
@@ -9,7 +9,7 @@
 [tox]
 # py32 not supported by tox and pytest
 envlist =
-    py{27,34,35,36,37,38}-wrapt{1.10,1.11}
+    py{27,34,35,36,37,38}-wrapt{1.10,1.11,1.12}
     pypy
     docs
 
@@ -23,6 +23,7 @@ deps =
     py35,py36,py37,py38,pypy: PyTest-Cov
     wrapt1.10: wrapt ~= 1.10.0
     wrapt1.11: wrapt ~= 1.11.0
+    wrapt1.12: wrapt ~= 1.12.0
 
 [testenv:docs]
 basepython = python



View it on GitLab: https://salsa.debian.org/debian-gis-team/python-deprecated/-/commit/dbbd9d74089fb17d0d0c79728c28932cbf700505

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/python-deprecated/-/commit/dbbd9d74089fb17d0d0c79728c28932cbf700505
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20200406/9ccc6c79/attachment-0001.html>


More information about the Pkg-grass-devel mailing list