from deprecated import deprecated
@deprecated(reason='this should happen once', action='once')
def a():
return
a()
a()
a()
I expect the deprecation warning to print once:
$ python3 once.py
once.py:6: DeprecationWarning: Call to deprecated function (or staticmethod) a. (this should happen once)
a()
Actual Behavior
Tell us what happens instead.
$ python3 once.py
once.py:6: DeprecationWarning: Call to deprecated function (or staticmethod) a. (this should happen once)
a()
once.py:7: DeprecationWarning: Call to deprecated function (or staticmethod) a. (this should happen once)
a()
once.py:8: DeprecationWarning: Call to deprecated function (or staticmethod) a. (this should happen once)
a()
Environment
Python version: Python 3.6.9
Deprecated version: 1.2.9
Additional Info
Note: this issue is slightly different from the issue #24 aims to solve. #24 deals with actions specified by global warning filters while this issue deals with actions specified to the @deprecated decorator.
This is not a problem in Python 2. This is only a problem in Python 3 due to the way warnings.catch_warnings() works. Entering and exiting the warnings.catch_warnings() context manager causes Python 3 to clear out its warning registries. The warning registries keep track of which warnings have fired in order to enforce actions like "once", "default", and "module". When deprecated fires its warning inside warnings.catch_warnings(), the warning registries will always be empty, so "once", "default", and "module" end up behaving like "always". I'm not sure there's much we can do to fix this problem.
Expected Behavior
Paste the following into a file named
once.py
I expect the deprecation warning to print once:
Actual Behavior
Tell us what happens instead.
Environment
Additional Info
Note: this issue is slightly different from the issue #24 aims to solve. #24 deals with actions specified by global warning filters while this issue deals with actions specified to the
@deprecated
decorator.This is not a problem in Python 2. This is only a problem in Python 3 due to the way
warnings.catch_warnings()
works. Entering and exiting thewarnings.catch_warnings()
context manager causes Python 3 to clear out its warning registries. The warning registries keep track of which warnings have fired in order to enforce actions like "once", "default", and "module". Whendeprecated
fires its warning insidewarnings.catch_warnings()
, the warning registries will always be empty, so "once", "default", and "module" end up behaving like "always". I'm not sure there's much we can do to fix this problem.