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 <rep...@bugs.python.org>
<http://bugs.python.org/issue24305>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to