diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2018-01-08 02:45:02 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-08 02:45:02 (GMT) |
commit | 9b99747386b690007027c3be2a5d7cfe3d3634f5 (patch) | |
tree | ba319d02ddc0e437bd0f90d520a4409efa7af6e2 /Doc | |
parent | d13889214a4c81b78fa8683d35bdbd17ff22f4fe (diff) | |
download | cpython-9b99747386b690007027c3be2a5d7cfe3d3634f5.zip cpython-9b99747386b690007027c3be2a5d7cfe3d3634f5.tar.gz cpython-9b99747386b690007027c3be2a5d7cfe3d3634f5.tar.bz2 |
bpo-31975 (PEP 565): Show DeprecationWarning in __main__ (GH-4458)
- primary change is to add a new default filter entry for
'default::DeprecationWarning:__main__'
- secondary change is an internal one to cope with plain
strings in the warning module's internal filter list
(this avoids the need to create a compiled regex object
early on during interpreter startup)
- assorted documentation updates, including many more
examples of configuring the warnings settings
- additional tests to ensure that both the pure Python and
the C accelerated warnings modules have the expected
default configuration
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/library/exceptions.rst | 19 | ||||
-rw-r--r-- | Doc/library/warnings.rst | 221 | ||||
-rw-r--r-- | Doc/tools/susp-ignored.csv | 19 | ||||
-rw-r--r-- | Doc/using/cmdline.rst | 72 | ||||
-rw-r--r-- | Doc/whatsnew/3.7.rst | 40 |
5 files changed, 256 insertions, 115 deletions
diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index c8d32cf..aa31410 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -661,11 +661,13 @@ depending on the system error code. :pep:`3151` - Reworking the OS and IO exception hierarchy +.. _warning-categories-as-exceptions: + Warnings -------- -The following exceptions are used as warning categories; see the :mod:`warnings` -module for more information. +The following exceptions are used as warning categories; see the +:ref:`warning-categories` documentation for more details. .. exception:: Warning @@ -679,12 +681,14 @@ module for more information. .. exception:: DeprecationWarning - Base class for warnings about deprecated features. + Base class for warnings about deprecated features when those warnings are + intended for other Python developers. .. exception:: PendingDeprecationWarning - Base class for warnings about features which will be deprecated in the future. + Base class for warnings about features which will be deprecated in the + future. .. exception:: SyntaxWarning @@ -699,8 +703,8 @@ module for more information. .. exception:: FutureWarning - Base class for warnings about constructs that will change semantically in the - future. + Base class for warnings about deprecated features when those warnings are + intended for end users of applications that are written in Python. .. exception:: ImportWarning @@ -720,7 +724,8 @@ module for more information. .. exception:: ResourceWarning - Base class for warnings related to resource usage. + Base class for warnings related to resource usage. Ignored by the default + warning filters. .. versionadded:: 3.2 diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index f67f4bc..b04bd79 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -51,8 +51,17 @@ Warning Categories ------------------ There are a number of built-in exceptions that represent warning categories. -This categorization is useful to be able to filter out groups of warnings. The -following warnings category classes are currently defined: +This categorization is useful to be able to filter out groups of warnings. + +While these are technically +:ref:`built-in exceptions <warning-categories-as-exceptions>`, they are +documented here, because conceptually they belong to the warnings mechanism. + +User code can define additional warning categories by subclassing one of the +standard warning categories. A warning category must always be a subclass of +the :exc:`Warning` class. + +The following warnings category classes are currently defined: .. tabularcolumns:: |l|p{0.6\linewidth}| @@ -66,7 +75,9 @@ following warnings category classes are currently defined: | :exc:`UserWarning` | The default category for :func:`warn`. | +----------------------------------+-----------------------------------------------+ | :exc:`DeprecationWarning` | Base category for warnings about deprecated | -| | features (ignored by default). | +| | features when those warnings are intended for | +| | other Python developers (ignored by default, | +| | unless triggered by code in ``__main__``). | +----------------------------------+-----------------------------------------------+ | :exc:`SyntaxWarning` | Base category for warnings about dubious | | | syntactic features. | @@ -74,8 +85,10 @@ following warnings category classes are currently defined: | :exc:`RuntimeWarning` | Base category for warnings about dubious | | | runtime features. | +----------------------------------+-----------------------------------------------+ -| :exc:`FutureWarning` | Base category for warnings about constructs | -| | that will change semantically in the future. | +| :exc:`FutureWarning` | Base category for warnings about deprecated | +| | features when those warnings are intended for | +| | end users of applications that are written in | +| | Python. | +----------------------------------+-----------------------------------------------+ | :exc:`PendingDeprecationWarning` | Base category for warnings about features | | | that will be deprecated in the future | @@ -95,13 +108,12 @@ following warnings category classes are currently defined: | | resource usage. | +----------------------------------+-----------------------------------------------+ - -While these are technically built-in exceptions, they are documented here, -because conceptually they belong to the warnings mechanism. - -User code can define additional warning categories by subclassing one of the -standard warning categories. A warning category must always be a subclass of -the :exc:`Warning` class. +.. versionchanged:: 3.7 + Previously :exc:`DeprecationWarning` and :exc:`FutureWarning` were + distinguished based on whether a feature was being removed entirely or + changing its behaviour. They are now distinguished based on their + intended audience and the way they're handled by the default warnings + filters. .. _warning-filter: @@ -114,7 +126,7 @@ into errors (raising an exception). Conceptually, the warnings filter maintains an ordered list of filter specifications; any specific warning is matched against each filter -specification in the list in turn until a match is found; the match determines +specification in the list in turn until a match is found; the filter determines the disposition of the match. Each entry is a tuple of the form (*action*, *message*, *category*, *module*, *lineno*), where: @@ -123,19 +135,19 @@ the disposition of the match. Each entry is a tuple of the form (*action*, +---------------+----------------------------------------------+ | Value | Disposition | +===============+==============================================+ + | ``"default"`` | print the first occurrence of matching | + | | warnings for each location (module + | + | | line number) where the warning is issued | + +---------------+----------------------------------------------+ | ``"error"`` | turn matching warnings into exceptions | +---------------+----------------------------------------------+ | ``"ignore"`` | never print matching warnings | +---------------+----------------------------------------------+ | ``"always"`` | always print matching warnings | +---------------+----------------------------------------------+ - | ``"default"`` | print the first occurrence of matching | - | | warnings for each location where the warning | - | | is issued | - +---------------+----------------------------------------------+ | ``"module"`` | print the first occurrence of matching | | | warnings for each module where the warning | - | | is issued | + | | is issued (regardless of line number) | +---------------+----------------------------------------------+ | ``"once"`` | print only the first occurrence of matching | | | warnings, regardless of location | @@ -157,33 +169,119 @@ the disposition of the match. Each entry is a tuple of the form (*action*, Since the :exc:`Warning` class is derived from the built-in :exc:`Exception` class, to turn a warning into an error we simply raise ``category(message)``. +If a warning is reported and doesn't match any registered filter then the +"default" action is applied (hence its name). + + +.. _describing-warning-filters: + +Describing Warning Filters +~~~~~~~~~~~~~~~~~~~~~~~~~~ + The warnings filter is initialized by :option:`-W` options passed to the Python -interpreter command line. The interpreter saves the arguments for all -:option:`-W` options without interpretation in ``sys.warnoptions``; the -:mod:`warnings` module parses these when it is first imported (invalid options -are ignored, after printing a message to ``sys.stderr``). +interpreter command line and the :envvar:`PYTHONWARNINGS` environment variable. +The interpreter saves the arguments for all supplied entries without +interpretation in ``sys.warnoptions``; the :mod:`warnings` module parses these +when it is first imported (invalid options are ignored, after printing a +message to ``sys.stderr``). + +Individual warnings filters are specified as a sequence of fields separated by +colons:: + action:message:category:module:line -Default Warning Filters -~~~~~~~~~~~~~~~~~~~~~~~ +The meaning of each of these fields is as described in :ref:`warning-filter`. +When listing multiple filters on a single line (as for +:envvar:`PYTHONWARNINGS`), the individual filters are separated by commas,and +the filters listed later take precedence over those listed before them (as +they're applied left-to-right, and the most recently applied filters take +precedence over earlier ones). + +Commonly used warning filters apply to either all warnings, warnings in a +particular category, or warnings raised by particular modules or packages. +Some examples:: + + default # Show all warnings (even those ignored by default) + ignore # Ignore all warnings + error # Convert all warnings to errors + error::ResourceWarning # Treat ResourceWarning messages as errors + default::DeprecationWarning # Show DeprecationWarning messages + ignore,default:::mymodule # Only report warnings triggered by "mymodule" + error:::mymodule[.*] # Convert warnings to errors in "mymodule" + # and any subpackages of "mymodule" + + +.. _default-warning-filter: + +Default Warning Filter +~~~~~~~~~~~~~~~~~~~~~~ By default, Python installs several warning filters, which can be overridden by -the command-line options passed to :option:`-W` and calls to -:func:`filterwarnings`. +the :option:`-W` command-line option, the :envvar:`PYTHONWARNINGS` environment +variable and calls to :func:`filterwarnings`. -* :exc:`DeprecationWarning` and :exc:`PendingDeprecationWarning`, and - :exc:`ImportWarning` are ignored. +In regular release builds, the default warning filter has the following entries +(in order of precedence):: -* :exc:`BytesWarning` is ignored unless the :option:`-b` option is given once or - twice; in this case this warning is either printed (``-b``) or turned into an - exception (``-bb``). + default::DeprecationWarning:__main__ + ignore::DeprecationWarning + ignore::PendingDeprecationWarning + ignore::ImportWarning + ignore::ResourceWarning -* :exc:`ResourceWarning` is ignored unless Python was built in debug mode. +In debug builds, the list of default warning filters is empty. .. versionchanged:: 3.2 :exc:`DeprecationWarning` is now ignored by default in addition to :exc:`PendingDeprecationWarning`. +.. versionchanged:: 3.7 + :exc:`DeprecationWarning` is once again shown by default when triggered + directly by code in ``__main__``. + +.. versionchanged:: 3.7 + :exc:`BytesWarning` no longer appears in the default filter list and is + instead configured via :data:`sys.warnoptions` when :option:`-b` is specified + twice. + + +.. _warning-disable: + +Overriding the default filter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Developers of applications written in Python may wish to hide *all* Python level +warnings from their users by default, and only display them when running tests +or otherwise working on the application. The :data:`sys.warnoptions` attribute +used to pass filter configurations to the interpreter can be used as a marker to +indicate whether or not warnings should be disabled:: + + import sys + + if not sys.warnoptions: + import warnings + warnings.simplefilter("ignore") + +Developers of test runners for Python code are advised to instead ensure that +*all* warnings are displayed by default for the code under test, using code +like:: + + import sys + + if not sys.warnoptions: + import os, warnings + warnings.simplefilter("default") # Change the filter in this process + os.environ["PYTHONWARNINGS"] = "default" # Also affect subprocesses + +Finally, developers of interactive shells that run user code in a namespace +other than ``__main__`` are advised to ensure that :exc:`DeprecationWarning` +messages are made visible by default, using code like the following (where +``user_ns`` is the module used to execute code entered interactively):: + + import warnings + warnings.filterwarnings("default", category=DeprecationWarning, + module=user_ns.get("__name__")) + .. _warning-suppress: @@ -191,7 +289,8 @@ Temporarily Suppressing Warnings -------------------------------- If you are using code that you know will raise a warning, such as a deprecated -function, but do not want to see the warning, then it is possible to suppress +function, but do not want to see the warning (even when warnings have been +explicitly configured via the command line), then it is possible to suppress the warning using the :class:`catch_warnings` context manager:: import warnings @@ -261,38 +360,30 @@ entries from the warnings list before each new operation). .. _warning-ignored: -Updating Code For New Versions of Python ----------------------------------------- - -Warnings that are only of interest to the developer are ignored by default. As -such you should make sure to test your code with typically ignored warnings -made visible. You can do this from the command-line by passing :option:`-Wd <-W>` -to the interpreter (this is shorthand for :option:`!-W default`). This enables -default handling for all warnings, including those that are ignored by default. -To change what action is taken for encountered warnings you simply change what -argument is passed to :option:`-W`, e.g. :option:`!-W error`. See the -:option:`-W` flag for more details on what is possible. - -To programmatically do the same as :option:`!-Wd`, use:: - - warnings.simplefilter('default') - -Make sure to execute this code as soon as possible. This prevents the -registering of what warnings have been raised from unexpectedly influencing how -future warnings are treated. - -Having certain warnings ignored by default is done to prevent a user from -seeing warnings that are only of interest to the developer. As you do not -necessarily have control over what interpreter a user uses to run their code, -it is possible that a new version of Python will be released between your -release cycles. The new interpreter release could trigger new warnings in your -code that were not there in an older interpreter, e.g. -:exc:`DeprecationWarning` for a module that you are using. While you as a -developer want to be notified that your code is using a deprecated module, to a -user this information is essentially noise and provides no benefit to them. - -The :mod:`unittest` module has been also updated to use the ``'default'`` -filter while running tests. +Updating Code For New Versions of Dependencies +---------------------------------------------- + +Warning categories that are primarily of interest to Python developers (rather +than end users of applications written in Python) are ignored by default. + +Notably, this "ignored by default" list includes :exc:`DeprecationWarning` +(for every module except ``__main__``), which means developers should make sure +to test their code with typically ignored warnings made visible in order to +receive timely notifications of future breaking API changes (whether in the +standard library or third party packages). + +In the ideal case, the code will have a suitable test suite, and the test runner +will take care of implicitly enabling all warnings when running tests +(the test runner provided by the :mod:`unittest` module does this). + +In less ideal cases, applications can be checked for use of deprecated +interfaces by passing :option:`-Wd <-W>` to the Python interpreter (this is +shorthand for :option:`!-W default`) or setting ``PYTHONWARNINGS=default`` in +the environment. This enables default handling for all warnings, including those +that are ignored by default. To change what action is taken for encountered +warnings you can change what argument is passed to :option:`-W` (e.g. +:option:`!-W error`). See the :option:`-W` flag for more details on what is +possible. .. _warning-functions: diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 48dd53f..cfdd526 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -259,12 +259,8 @@ tutorial/stdlib2,,:start,extra = data[start:start+extra_size] tutorial/stdlib2,,:start,"fields = struct.unpack('<IIIHH', data[start:start+16])" tutorial/stdlib2,,:start,filename = data[start:start+filenamesize] tutorial/stdlib2,,:Warning,WARNING:root:Warning:config file server.conf not found -using/cmdline,,:category,action:message:category:module:line using/cmdline,,:errorhandler,:errorhandler -using/cmdline,,:line,action:message:category:module:line using/cmdline,,:line,file:line: category: message -using/cmdline,,:message,action:message:category:module:line -using/cmdline,,:module,action:message:category:module:line using/unix,,:Packaging,https://en.opensuse.org/Portal:Packaging whatsnew/2.0,,:len, whatsnew/2.3,,::, @@ -302,6 +298,20 @@ whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf library/re,,`,!#$%&'*+-.^_`|~: library/re,,`,!\#\$%\&'\*\+\-\.\^_`\|\~: library/tarfile,,:xz,'x:xz' +library/warnings,,:message,action:message:category:module:line +library/warnings,,:category,action:message:category:module:line +library/warnings,,:module,action:message:category:module:line +library/warnings,,:line,action:message:category:module:line +library/warnings,,::,error::ResourceWarning +library/warnings,,::,default::DeprecationWarning +library/warnings,,::,default:::mymodule +library/warnings,,:mymodule,default:::mymodule +library/warnings,,::,error:::mymodule +library/warnings,,:mymodule,error:::mymodule +library/warnings,,::,ignore::DeprecationWarning +library/warnings,,::,ignore::PendingDeprecationWarning +library/warnings,,::,ignore::ImportWarning +library/warnings,,::,ignore::ResourceWarning library/xml.etree.elementtree,,:sometag,prefix:sometag library/xml.etree.elementtree,,:fictional,"<actors xmlns:fictional=""http://characters.example.com""" library/xml.etree.elementtree,,:character,<fictional:character>Lancelot</fictional:character> @@ -330,3 +340,4 @@ whatsnew/3.7,,`,'`' whatsnew/3.7,,::,error::BytesWarning whatsnew/changelog,,::,error::BytesWarning whatsnew/changelog,,::,default::BytesWarning +whatsnew/changelog,,::,default::DeprecationWarning diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index b1bd47f..1e9ed6e 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -356,49 +356,27 @@ Miscellaneous options :option:`-W` options are ignored (though, a warning message is printed about invalid options when the first warning is issued). - Warnings can also be controlled from within a Python program using the + Warnings can also be controlled using the :envvar:`PYTHONWARNINGS` + environment variable and from within a Python program using the :mod:`warnings` module. - The simplest form of argument is one of the following action strings (or a - unique abbreviation): - - ``ignore`` - Ignore all warnings. - ``default`` - Explicitly request the default behavior (printing each warning once per - source line). - ``all`` - Print a warning each time it occurs (this may generate many messages if a - warning is triggered repeatedly for the same source line, such as inside a - loop). - ``module`` - Print each warning only the first time it occurs in each module. - ``once`` - Print each warning only the first time it occurs in the program. - ``error`` - Raise an exception instead of printing a warning message. - - The full form of argument is:: - - action:message:category:module:line - - Here, *action* is as explained above but only applies to messages that match - the remaining fields. Empty fields match all values; trailing empty fields - may be omitted. The *message* field matches the start of the warning message - printed; this match is case-insensitive. The *category* field matches the - warning category. This must be a class name; the match tests whether the - actual warning category of the message is a subclass of the specified warning - category. The full class name must be given. The *module* field matches the - (fully-qualified) module name; this match is case-sensitive. The *line* - field matches the line number, where zero matches all line numbers and is - thus equivalent to an omitted line number. + The simplest settings apply a particular action unconditionally to all + warnings emitted by a process (even those that are otherwise ignored by + default):: - .. seealso:: - :mod:`warnings` -- the warnings module + -Wdefault # Warn once per call location + -Werror # Convert to exceptions + -Walways # Warn every time + -Wmodule # Warn once per calling module + -Wonce # Warn once per Python process + -Wignore # Never warn - :pep:`230` -- Warning framework + The action names can be abbreviated as desired (e.g. ``-Wi``, ``-Wd``, + ``-Wa``, ``-We``) and the interpreter will resolve them to the appropriate + action name. - :envvar:`PYTHONWARNINGS` + See :ref:`warning-filter` and :ref:`describing-warning-filters` for more + details. .. cmdoption:: -x @@ -659,7 +637,23 @@ conflict. This is equivalent to the :option:`-W` option. If set to a comma separated string, it is equivalent to specifying :option:`-W` multiple - times. + times, with filters later in the list taking precedence over those earlier + in the list. + + The simplest settings apply a particular action unconditionally to all + warnings emitted by a process (even those that are otherwise ignored by + default):: + + PYTHONWARNINGS=default # Warn once per call location + PYTHONWARNINGS=error # Convert to exceptions + PYTHONWARNINGS=always # Warn every time + PYTHONWARNINGS=module # Warn once per calling module + PYTHONWARNINGS=once # Warn once per Python process + PYTHONWARNINGS=ignore # Never warn + + See :ref:`warning-filter` and :ref:`describing-warning-filters` for more + details. + .. envvar:: PYTHONFAULTHANDLER diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 9785d59..992d9ba 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -70,6 +70,7 @@ Summary -- Release highlights New Features ============ + .. _whatsnew37-pep538: PEP 538: Legacy C Locale Coercion @@ -107,6 +108,7 @@ locale remains active when the core interpreter is initialized. :pep:`538` -- Coercing the legacy C locale to a UTF-8 based locale PEP written and implemented by Nick Coghlan. + .. _whatsnew37-pep553: PEP 553: Built-in breakpoint() @@ -203,6 +205,44 @@ resolution on Linux and Windows. PEP written and implemented by Victor Stinner +.. _whatsnew37-pep565: + +PEP 565: Show DeprecationWarning in ``__main__`` +------------------------------------------------ + +The default handling of :exc:`DeprecationWarning` has been changed such that +these warnings are once more shown by default, but only when the code +triggering them is running directly in the ``__main__`` module. As a result, +developers of single file scripts and those using Python interactively should +once again start seeing deprecation warnings for the APIs they use, but +deprecation warnings triggered by imported application, library and framework +modules will continue to be hidden by default. + +As a result of this change, the standard library now allows developers to choose +between three different deprecation warning behaviours: + +* :exc:`FutureWarning`: always displayed by default, recommended for warnings + intended to be seen by application end users (e.g. for deprecated application + configuration settings). +* :exc:`DeprecationWarning`: displayed by default only in ``__main__`` and when + running tests, recommended for warnings intended to be seen by other Python + developers where a version upgrade may result in changed behaviour or an + error. +* :exc:`PendingDeprecationWarning`: displayed by default only when running + tests, intended for cases where a future version upgrade will change the + warning category to :exc:`DeprecationWarning` or :exc:`FutureWarning`. + +Previously both :exc:`DeprecationWarning` and :exc:`PendingDeprecationWarning` +were only visible when running tests, which meant that developers primarily +writing single file scripts or using Python interactively could be surprised +by breaking changes in the APIs they used. + +.. seealso:: + + :pep:`565` -- Show DeprecationWarning in ``__main__`` + PEP written and implemented by Nick Coghlan + + PEP 540: Add a new UTF-8 mode ----------------------------- |