[New-bugs-announce] [issue24305] The new import system makes it impossible to correctly issue a deprecation warning for a module

Nathaniel Smith report at bugs.python.org
Thu May 28 01:36:49 CEST 2015


New submission from Nathaniel Smith:

(Noticed while fixing the IPython equivalent of issue 24294)

The obvious way to deprecate a module is to issue a DeprecationWarning inside the main body of the module, i.e.

# thirdpartymodule.py
import warnings
warnings.warn("{} is deprecated".format(__name__), DeprecationWarning)

# mymodule.py
import thirdpartymodule

But this is problematic, because the resulting message will claim that the problem is in thirdpartymodule.py, not in mymodule.py. And this is especially bad if I am doing things correctly (!) and using a warnings filter that enables display of DeprecationWarnings for mymodule, but not for third-party modules. (This need for correct attribution comes up in the interactive use case cited above, but I actually have packages where the CI infrastructure requires the elimination of DeprecationWarnings triggered by my own code -- for this to work it's crucial that warnings be attributed correctly.)

So the obvious fix is to instead write:

# thirdpartymodule.py
import warnings
warnings.warn("{} is deprecated".format(__name__), DeprecationWarning,
              stacklevel=2)

which says "the code that needs fixing is the code that called me".

On Python 2.7, this works, because all the code that executes in between 'import thirdpartymodule' and the call to 'warnings.warn' is C code, so it doesn't create any intermediate stack frames.

On more recent versions of Python, the import system itself is written in Python, so this doesn't work at all.

On Python 3.3, the correct way to deprecate a module is:

warnings.warn("this module is deprecated", DeprecationWarning,
              stacklevel=10)

and on Python 3.4, the correct way to deprecate a module is:

warnings.warn("this module is deprecated", DeprecationWarning,
              stacklevel=8)

(See https://github.com/ipython/ipython/pull/8480#issuecomment-106107638 for test code.)

Obviously this is not desireable.

I'm not sure what best solution is. Maybe there should be some collaboration between the import code and the warnings module, so that when the warnings module walks the stack, it skips over stack frames that come from inside the guts of import system?

----------
messages: 244225
nosy: njs
priority: normal
severity: normal
status: open
title: The new import system makes it impossible to correctly issue a deprecation warning for a module
type: behavior

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue24305>
_______________________________________


More information about the New-bugs-announce mailing list