classification
Title: Simplify hiding developer warnings in user facing applications
Type: enhancement Stage: needs patch
Components: Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: ncoghlan, r.david.murray
Priority: normal Keywords:

Created on 2017-12-06 04:33 by ncoghlan, last changed 2017-12-06 14:32 by r.david.murray.

Messages (5)
msg307701 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-12-06 04:33
One of the observations coming out of the PEP 565 discussions is that it's surprisingly tricky to opt-in to getting all warnings from a particular package and its subpackages, while opting out of warnings in general.

The simplest approximation is to do the following:

    if not sys.warnoptions:
        warnings.simplefilter("ignore")
        warnings.filterwarnings("default", module="app_pkg.*")

That shows warnings for any module or package starting with `app_pkg`. A stricter filter that avoided warnings from top-level packages that merely shared the prefix would look like:

    if not sys.warnoptions:
        warnings.simplefilter("ignore")
        warnings.filterwarnings("default", module="^app_pkg(\..*)?$")

It could be helpful to encapsulate that logic in a more declarative utility API, such that applications could do the following:

    import warnings.
    warnings.hide_warnings()

Or:

    import warnings.
    warnings.hide_warnings(override_warnoptions=True)

Or:

    import warnings.
    warnings.hide_warnings(show=["app_pkg"])

Proposed API:

    def hide_warnings(*, show=(), override_warnoptions=False):
        if override_warnoptions or not sys.warnoptions:
            simplefilter("ignore")
            for pkg_name in show:
                pkg_filter =  _make_regex_for_pkg(pkg_name)
                filterwarnings("default", module=pkg_filter)
msg307734 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-12-06 12:43
I haven't been following that discussion, and isolated from that that discussion the title of this issue and this proposal make no sense to me.  Warnings are off by default, so you don't need to hide them.  In what context does this get used?  If this is going to be used to implement turning warnings on for the main application, why isn't it named "show_warnings"?
msg307736 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-12-06 13:21
Warnings aren't off by default in general - we just add implicit "ignore" filters for a few specific types.

So the primary functionality is to opt in to hiding *all* warnings, but to do it in a way that can be overridden by PYTHONWARNINGS, the interpreter's "-W" switch and the new "-X dev" mode.

For that, the usage looks like:

    import warnings
    warnings.hide_warnings()

Essentially, it flips the default behaviour over to "ignore everything", but reverts to the regular default if there are any config settings supplied.

The odd structure of my opening message arises from the fact that *given* such a modified default, it's then surprisingly tricky to say "hide warnings, except for those from modules I'm responsible for". That latter complication then becomes the rationale for the design of the proposed "show" parameter to carve out exceptions to the overall "hide everything" filter.
msg307737 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2017-12-06 13:23
Note: for consistency with the underlying action names, the API should probably be called "warnings.ignore_warnings". I'd still keep the proposed parameter name as "show" though (and we may want to consider introducing that as a more semantically meaningful alias for "default").
msg307740 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-12-06 14:32
Ah, OK, that makes more sense.  I don't run into warnings other than DeprecationWarnings in practice, so I tend to forget about them :)

I think specifying warnings filters is pretty inscrutable, in general.
History
Date User Action Args
2017-12-06 14:32:30r.david.murraysetmessages: + msg307740
2017-12-06 13:23:50ncoghlansetmessages: + msg307737
2017-12-06 13:21:06ncoghlansetmessages: + msg307736
2017-12-06 12:43:17r.david.murraysetnosy: + r.david.murray
messages: + msg307734
2017-12-06 04:33:06ncoghlancreate