Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Library does not respect warning filters #15

Closed
anuppari opened this issue Feb 8, 2020 · 4 comments
Closed

Library does not respect warning filters #15

anuppari opened this issue Feb 8, 2020 · 4 comments
Assignees
Labels
Milestone

Comments

@anuppari
Copy link

anuppari commented Feb 8, 2020

Expected Behavior

When warning filters are applied, I'd expect the warnings to be suppressed.

import warnings
from deprecated import deprecated

warnings.simplefilter("ignore")

@deprecated(version='1.2.1', reason="deprecated function")
def fun():
    print("fun")

fun()

Actual Behavior

The script emits a warning message:

test_dep.py:10: DeprecationWarning: Call to deprecated function (or staticmethod) fun. (deprecated function) -- Deprecated since version 1.2.1.
  fun()
fun

Environment

  • Python version: 3.6.9
  • Deprecated version: 1.2.7
@tantale tantale self-assigned this Feb 10, 2020
@tantale
Copy link
Owner

tantale commented Feb 10, 2020

One possibility is to use the action kwarg:

@deprecated(version='1.2.1', reason="deprecated function", action="ignore")
def fun():
    print("fun")

Does it fix your problem?

@anuppari
Copy link
Author

That was a minimum working example. In actuality, we use the deprecated decorator in a library, and want to allow clients to decide which warnings to suppress. Setting the action to "ignore" seems to negate the whole point of having the decorator in the first place.

@anuppari
Copy link
Author

anuppari commented Feb 10, 2020

The documentation seems to suggest that the python warning control system is used, which should allow users to control warnings. Even the command line warning suppression doesn't work (python -W ignore script.py), let alone the warning control filters.

@tantale
Copy link
Owner

tantale commented Feb 11, 2020

The current @deprecated behavior is to call warnings.simplefilter(action) (where action is "always" by default, see The Warnings Filter) each time the function is call. That way, this ensure the warning message is shown: when warnings.warn() is called, people expect to see a warning message. And they are happy with that.

The problem with warnings.simplefilter(...) is that it update or reset a global list of filters. filters is a module-level variable defined as follow (Python 3.7 implementation):

filters = [
    (
        'default',
        None,
        DeprecationWarning,
        '__main__',
        0,
    ),
    (
        'ignore',
        None,
        '<value is a self-reference, replaced by this string>',
        None,
        0,
    ),
    (
        'ignore',
        None,
        PendingDeprecationWarning,
        None,
        0,
    ),
    (
        'ignore',
        None,
        ImportWarning,
        None,
        0,
    ),
    (
        'ignore',
        None,
        ResourceWarning,
        None,
        0,
    ),
]

So, the current implementation modify this global variable on every call: this is bad.

A correct implementation of the @deprecated operator could be:

  • if the action is not provided (None): do not set a filter. That way, when emitting a warning, it takes the current filter (in the filters list). This is what you want: the main function can change the filters according to the user needs.

  • if the action is provided, we can use the current behavior (which restores the filter at the end of the processing).

I'll see if this implementation is feasible…

@tantale tantale added the bug label Feb 11, 2020
@tantale tantale added this to the 1.2.8 milestone Feb 11, 2020
tantale added a commit that referenced this issue Feb 11, 2020
…f 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.
@tantale tantale closed this as completed Feb 22, 2020
heidecjj added a commit to heidecjj/deprecated that referenced this issue Apr 21, 2020
…actions

other than "ignore" and "always" on Python 3
heidecjj added a commit to heidecjj/deprecated that referenced this issue Apr 21, 2020
…actions other than "ignore" and "always" on Python 3
tantale pushed a commit that referenced this issue May 13, 2020
… other than "ignore" and "always" on Python 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment