… warning is matched against each filter specification in the list in turn until a match is found; the filter determines the disposition of the match
This reads to me as “first match wins”, so earlier filters have higher precedence.
However under “Describing Warning Filters” there is:
… 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).
which is the opposite: later filters have higher precedence
If I try the precedence out on a simple script, e.g. with python -Wdefault -Werror test.py , I indeed see that later filters have higher precedence.
Am I reading the first citation wrong, or is there room for documentation improvement there?
It says the list is an ordered list, but what that order is, is not stated in the initial summary. You seem to be assuming that the order is to add new filters to the end of the list. However, the documentation for warnings.filterwarnings is explicit in saying that new filters are prepended by default, with an optional flag to request adding at the end.
Maybe the initial summary docs could be a little clearer about how the list is ordered, but I think the information is there if you look for it.
Thank you for that pointer to the warnings.filterwarnings docs. But please note that that function was not in my reading scope as I wasn’t looking at a way to set filters from within my application, I was mainly looking at -W and PYTHONWARNINGS usage to set the filters from the outside. (And actually pytest.mark.filterwarnings as well, but this one also does not link documentation-wise to stdlib’s warnings.filterwarnings.)
Also, you mention “the order”, but I think there are several orders in play here:
the order the user specifies the filters, e.g.
with -Werror -Wignore::DeprecationWarning
with PYTHONWARNINGS=error,ignore::DeprecationWarning)
the order of warnings.filterwarnings() calls
the order that the filters are evaluated (“any specific warning is matched against each filter specification in the list in turn until a match is found”)
As a core developer you are probably familiar with the inner workings and implementation details, so this all “clicks” naturally. But as a simple mortal trying to build a mental model of this from the docs, this is quite confusing.
Yes, if not mentioned explicitly, I would assume that -Werror -Wignore::DeprecationWarning translates to a filter list ["error", "ignore::DeprecationWarning"], but apparently it’s the reverse. I know that the -W and PYTHONWARNINGS docs describe “filters later in the list take precedence”, but that only describes the filtering outcome, not how this filter list is organized, so that doesn’t help.
I guess the important trick is understanding that all methods to specify filters (-W, PYTHONWARNINGS, warnings.filterwarnings(), and derivatives) all use the “prepend” behavior. Unfortunately this “prepend” behavior is only mentioned in the docs of warnings.filterwarnings(), which is very far down the warnings docs.