PEP 565: Address Guido & Serhiy's comments
- note advice for test runners in abstract - add explicit sections for test runner and interactive shell guidance - simplify the warning category descriptions by moving the test runner details to their new section - make it clear FutureWarning is gaining a second use case, while also keeping its old one - note that IPython already follows the new guidance for interactive shells (and use their approach as an example) - reword the advice for library and framework authors wanting seeking noisier compatibility warnings on earlier Python versions
This commit is contained in:
parent
749a7a060c
commit
aaa64f53d0
123
pep-0565.rst
123
pep-0565.rst
|
@ -37,10 +37,18 @@ The PEP also proposes a number of small adjustments to the reference
|
|||
interpreter and standard library documentation to help make the warnings
|
||||
subsystem more approachable for new Python developers.
|
||||
|
||||
As part of the documentation updates, it will be made clearer that the
|
||||
``unittest`` test runner displays all warnings by default when executing
|
||||
test cases, and that other test runners are advised to follow that example.
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
|
||||
New default warnings filter entry
|
||||
---------------------------------
|
||||
|
||||
The current set of default warnings filters consists of::
|
||||
|
||||
ignore::DeprecationWarning
|
||||
|
@ -82,42 +90,87 @@ While continuing to be hidden by default for:
|
|||
* code imported from an executable script wrapper generated at installation time
|
||||
based on a ``console_scripts`` or ``gui_scripts`` entry point definition
|
||||
|
||||
As a result, API deprecation warnings encountered by development tools written
|
||||
in Python should continue to be hidden by default for users of those tools
|
||||
This means that tool developers that create an installable or executable
|
||||
artifact (such as a ``zipapp`` archive) for distribution to their users
|
||||
shouldn't see any change from the status quo, while users of more ad hoc
|
||||
personal or locally distributed scripts are likely to start seeing relevant
|
||||
deprecation warnings again (as they did in Python 2.6 and earlier).
|
||||
|
||||
While not its originally intended purpose, the standard library documentation
|
||||
will also be updated to explicitly recommend the use of ``FutureWarning`` (rather
|
||||
than ``DeprecationWarning``) for backwards compatibility warnings that are
|
||||
intended to be seen by *users* of an application.
|
||||
|
||||
Additional use case for ``FutureWarning``
|
||||
-----------------------------------------
|
||||
|
||||
The standard library documentation will be updated to explicitly recommend the
|
||||
use of ``FutureWarning`` (rather than ``DeprecationWarning``) for backwards
|
||||
compatibility warnings that are intended to be seen by *users* of an
|
||||
application. (This will be in addition to the existing use of ``FutureWarning``
|
||||
to warn about constructs that will remain valid code in the future,
|
||||
but will have different semantics).
|
||||
|
||||
This will give the following three distinct categories of backwards
|
||||
compatibility warning, with three different intended audiences:
|
||||
|
||||
* ``PendingDeprecationWarning``: reported by default only in test runners that
|
||||
override the default set of warning filters. The intended audience is Python
|
||||
developers that take an active interest in ensuring the future compatibility
|
||||
of their software (e.g. professional Python application developers with
|
||||
specific support obligations).
|
||||
* ``PendingDeprecationWarning``: hidden by default for all code.
|
||||
The intended audience is Python developers that take an active interest in
|
||||
ensuring the future compatibility of their software (e.g. professional
|
||||
Python application developers with specific support obligations).
|
||||
* ``DeprecationWarning``: reported by default for code that runs directly in
|
||||
the ``__main__`` module (as such code is considered relatively unlikely to
|
||||
have a dedicated test suite), but relies on test suite based reporting for
|
||||
code in other modules. The intended audience is Python developers that are at
|
||||
risk of upgrades to their dependencies (including upgrades to Python itself)
|
||||
breaking their software (e.g. developers using Python to script environments
|
||||
where someone else is in control of the timing of dependency upgrades).
|
||||
* ``FutureWarning``: always reported by default. The intended audience is users
|
||||
of applications written in Python, rather than other Python developers
|
||||
(e.g. warning about use of a deprecated setting in a configuration file
|
||||
format).
|
||||
have a dedicated test suite), but hidden by default for code in other modules.
|
||||
The intended audience is Python developers that are at risk of upgrades to
|
||||
their dependencies (including upgrades to Python itself) breaking their
|
||||
software (e.g. developers using Python to script environments where someone
|
||||
else is in control of the timing of dependency upgrades).
|
||||
* ``FutureWarning``: reported by default for all code.
|
||||
The intended audience is users of applications written in Python, rather than
|
||||
other Python developers (e.g. warning about use of a deprecated setting in a
|
||||
configuration file format).
|
||||
|
||||
Given its presence in the standard library since Python 2.3, ``FutureWarning``
|
||||
would then also have a secondary use case for libraries and frameworks that
|
||||
support multiple Python versions: as a more reliably visible alternative to
|
||||
``DeprecationWarning`` in Python 2.7 and versions of Python 3.x prior to 3.7.
|
||||
For libraries and framework authors that want to ensure their API compatibility
|
||||
warnings are more reliably seen by their users, the recommendation is to use a
|
||||
custom warning class that derives from ``DeprecationWarning`` in Python 3.7+,
|
||||
and from ``FutureWarning`` in earlier versions.
|
||||
|
||||
|
||||
Documentation Updates
|
||||
=====================
|
||||
Recommended filter settings for test runners
|
||||
--------------------------------------------
|
||||
|
||||
Developers of test runners are advised to implement logic equivalent to the
|
||||
following when determining their default warnings filters::
|
||||
|
||||
if not sys.warnoptions:
|
||||
warnings.simplefilter("default")
|
||||
|
||||
This effectively enables all warnings by default, as if the ``-Wd`` command
|
||||
line option had been passed.
|
||||
|
||||
Note that actually enabling ``BytesWarning`` in a test suite still requires
|
||||
passing the ``-b`` option to the interpreter at the command line. For implicit
|
||||
bytes conversion and bytes comparison warnings, the warnings filter machinery
|
||||
is only used to determine whether they should be printed as warnings or raised
|
||||
as exceptions - when the command line flag isn't set, the interpreter doesn't
|
||||
even emit the warning in the first place.
|
||||
|
||||
|
||||
Recommended filter settings for interactive shells
|
||||
--------------------------------------------------
|
||||
|
||||
Developers of interactive shells are advised to add a filter that enables
|
||||
``DeprecationWarning`` in the namespace where user code is entered and executed.
|
||||
|
||||
If that namespace is ``__main__`` (as it is for the default CPython REPL), then
|
||||
no changes are needed beyond those in this PEP.
|
||||
|
||||
Interactive shell implementations which use a namespace other than
|
||||
``__main__`` will need to add their own filter. For example, IPython uses the
|
||||
following command ([8_]) to set up a suitable filter::
|
||||
|
||||
warnings.filterwarnings("default", category=DeprecationWarning,
|
||||
module=self.user_ns.get("__name__"))
|
||||
|
||||
|
||||
Other documentation updates
|
||||
---------------------------
|
||||
|
||||
The current reference documentation for the warnings system is relatively short
|
||||
on specific *examples* of possible settings for the ``-W`` command line option
|
||||
|
@ -226,18 +279,18 @@ and 3.2.
|
|||
This PEP does not solve all known problems with the current approach to handling
|
||||
deprecation warnings. Most notably:
|
||||
|
||||
* the default ``unittest`` test runner does not currently report deprecation
|
||||
* The default ``unittest`` test runner does not currently report deprecation
|
||||
warnings emitted at module import time, as the warnings filter override is only
|
||||
put in place during test execution, not during test discovery and loading.
|
||||
* the default ``unittest`` test runner does not currently report deprecation
|
||||
* The default ``unittest`` test runner does not currently report deprecation
|
||||
warnings in subprocesses, as the warnings filter override is applied directly
|
||||
to the loaded ``warnings`` module, not to the ``PYTHONWARNINGS`` environment
|
||||
variable.
|
||||
* the standard library doesn't provide a straightforward way to opt-in to seeing
|
||||
* The standard library doesn't provide a straightforward way to opt-in to seeing
|
||||
all warnings emitted *by* a particular dependency prior to upgrading it
|
||||
(the third-party ``warn`` module [3_] does provide this, but enabling it
|
||||
involves monkeypatching the standard library's ``warnings`` module).
|
||||
* re-enabling deprecation warnings by default in __main__ doesn't help in
|
||||
* Re-enabling deprecation warnings by default in ``__main__`` doesn't help in
|
||||
handling cases where software has been factored out into support modules, but
|
||||
those modules still have little or no automated test coverage. Near term, the
|
||||
best currently available answer is to run such applications with
|
||||
|
@ -247,7 +300,7 @@ deprecation warnings. Most notably:
|
|||
working on static analysis of Python code: how to reliably find usage of
|
||||
deprecated APIs, and how to infer that an API or parameter is deprecated
|
||||
based on ``warnings.warn`` calls, without actually running either the code
|
||||
providing the API or the code accessing it
|
||||
providing the API or the code accessing it.
|
||||
|
||||
While these are real problems with the status quo, they're excluded from
|
||||
consideration in this PEP because they're going to require more complex
|
||||
|
@ -290,9 +343,15 @@ References
|
|||
.. [5] Tracker issue for PEP 565 implementation
|
||||
(https://bugs.python.org/issue31975)
|
||||
|
||||
.. [6] python-dev discussion thread for this PEP
|
||||
.. [6] First python-dev discussion thread
|
||||
(https://mail.python.org/pipermail/python-dev/2017-November/150477.html)
|
||||
|
||||
.. [7] Second python-dev discussion thread
|
||||
(https://mail.python.org/pipermail/python-dev/2017-November/150819.html)
|
||||
|
||||
.. [8] IPython's DeprecationWarning auto-configuration
|
||||
(https://github.com/ipython/ipython/blob/6.2.x/IPython/core/interactiveshell.py#L619)
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
|
Loading…
Reference in New Issue