> 2. Looking it up is hard. If I Google "python ignore warnings" the top
result is a Stack Overflow question where neither the accepted answer nor
the most upvoted answer mention specifying a module. The second Google
result is the Python docs which are not easy to read through.

Hmm, I think we may benefit from focusing the efforts on this point (at
least at first), particularly with regards to making the official
documentation for the warnings module [1] easier to understand with some
more examples, or perhaps writing a warnings HOWTO guide [2], which could
include the correct way to add filters for specific warning types by module
for a significant number of different filters.

>From my perspective, this seems to be more of an issue with a lack of
understanding and clear guides for using the existing tools, rather than a
direct indication that additional tools need to be added.

> 3. There's lots of similarly named methods and it's hard to find the
right one. Is it catch_warnings, simplefilter, or filterwarnings?

While I agree that the names might be a bit similar, I personally find that
the names accurately describe what each of them do, particularly
`filterwarnings()` and `catch_warnings()`. The purpose of `simplefilter()`
in relation to `filterwarnings()` might not be as obvious without reading
the documentation, but I don't think there's much that can reasonably be
done to address it. I also don't find it to be an especially significant
concern.

> 4. When warnings are displayed, they show the filename, but filters
require a module name, and converting between the two is tedious.

I could see it being useful to have a utility for filtering warnings by
filename rather than just module, if it's reasonably possible to implement.

> 5. The more warnings there are, and thus the more serious the need to
filter them properly, the more work it is to write all the filters.

This could be potentially addressed by adding an example in the warning
docs or a new warnings HOWTO that includes something along the lines of the
following:

```
modules_to_filter = {"foo": ResourceWarning, "bar": DeprecationWarning}
for mod, cat in modules_to_filter.items():
    warnings.filterwarnings("ignore", category=cat, module=mod)
```

(I suspect the actual documented example would be much more fleshed out and
explained, the above was very quickly thrown together as a rough example)

Alternatively, we could consider adding a helper function to the warnings
module for adding a filter with the same action and warning category across
multiple modules at once; by accepting a collection of a strings instead of
a single string (like `filterwarnings()` does for it's *module* parameter).
I'm not certain if the implementation would be too trivial to justify a new
helper function for it, but the use case may be common enough for something
like that to be reasonable.

> I propose we add a built in mechanism that is easy to use and remember
which displays Python code that can be copy pasted.

I really don't like the idea of a builtin that specifically revolves around
the expectation of its output being copied and pasted as code elsewhere,
particularly from an API design perspective. Also, *if* we were to consider
something like this, it seems more appropriate to be included in the
warnings module rather than as a builtin.

> Does this seem like a good general idea?

-1 on the addition of the proposed builtin, but +1 on the general idea of
making the process of correctly adding a decent volume of warning filters
more clear.

---

[1] - https://docs.python.org/3/library/warnings.html
[2] - https://docs.python.org/3/howto/index.html

On Tue, Feb 25, 2020 at 4:04 PM Alex Hall <alex.moj...@gmail.com> wrote:

> This is inspired by the [discussion on iterable strings](
> https://mail.python.org/archives/list/python-ideas@python.org/thread/WKEFHT4JYCL2PMZ5LB6HJRLVP3OGZI56/),
> although I think it has applications elsewhere.
>
> Sometimes programs emit warnings that need to be filtered out. Maybe
> they're coming from dependencies that we don't control, or maybe it's our
> own code but it's a problem that can't be fixed or isn't worth the trouble.
>
> But filtering warnings correctly isn't very easy. You generally shouldn't
> ignore all warnings, as this would hide important ones. Similarly, you
> probably shouldn't even filter an entire category, which is what many end
> up doing. A good compromise is to specify both the category and the module.
> In particular this lets you ignore warnings from libraries while still
> being able to see warnings from your own code. But there are obstacles on
> the way:
>
> 1. Remembering the syntax is hard. I've never been able to.
> 2. Looking it up is hard. If I Google "python ignore warnings" the top
> result is a Stack Overflow question where neither the accepted answer nor
> the most upvoted answer mention specifying a module. The second Google
> result is the Python docs which are not easy to read through.
> 3. There's lots of similarly named methods and it's hard to find the right
> one. Is it catch_warnings, simplefilter, or filterwarnings?
> 4. When warnings are displayed, they show the filename, but filters
> require a module name, and converting between the two is tedious.
> 5. The more warnings there are, and thus the more serious the need to
> filter them properly, the more work it is to write all the filters.
>
> I propose we add a built in mechanism that is easy to use and remember
> which displays Python code that can be copy pasted. For example, this could
> be a configuration option which causes the line of code to be shown in
> stderr immediately after the actual warning. Alternatively, here's a
> context manager / decorator which prints the code after it exits:
>
>     import inspect
>     import warnings
>     from contextlib import contextmanager
>     import __main__
>
>
>     @contextmanager
>     def showfilters():
>         with warnings.catch_warnings(record=True) as warnings_list:
>             yield
>
>         for warning in warnings_list:
>             if warning.filename == getattr(__main__, "__file__", object()):
>                 module = "__main__"
>             else:
>                 module = inspect.getmodulename(warning.filename)
>             module = bool(module) * f", module={module!r}"
>             print(
>                 f"warnings.filterwarnings('ignore', "
>                 f"category={warning.category.__name__}"
>                 f"{module})"
>             )
>
>
>     # Sample usage
>     # Prints the below, uncomment to confirm that output disappears
>     # warnings.filterwarnings('ignore', category=UserWarning,
> module='__main__')
>     # warnings.filterwarnings('ignore', category=SyntaxWarning)
>
>     @showfilters()  # comment out to see original warnings
>     def main():
>         warnings.warn("DOOM")
>         exec("assert (1, 2)")
>
>
>     main()
>
> This is of course a rough implementation, there are probably things it
> does wrong and there's all sorts of details about the desired behaviour we
> could debate about. The aim is that the code it prints is good enough for
> most cases and can easily be edited, particularly by deleting lines. Does
> this seem like a good general idea?
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/YGI6EJ6Q7HQ37YBIOMJEQ7SGW4WU4F22/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/XVEGFA5Y4Z7EL57KXRITNDU3QCZZISL4/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to