Both of DeprecationWarning and PendingDeprecationWarning are suppressed by default.
When using -Wd or -Xdev option, both are enabled.
Do we really need two warning classes?
How about use just DeprecationWarning, and deprecate PendingDeprecationWarning?
Or can we change default behavior to not suppress DeprecationWarning?
I’ve personally used PendingDeprecationWarning for things whose deprecation is longer than a single release and for the time up to the last release the feature will be in. Then in that final release I switch it to DeprecationWarning. IOW you should clear out DeprecationWarning issues before upgrading to the next version and PendingDeprecationWarning if you’re supporting more than two versions of Python.
I think if you’re running under -Xdev it makes sense to at least see DeprecationWarning.
AFAIU it was useful when DeprecatingWarning was visible by default. But at some point it was decided that DeprecatingWarning would be hidden by default (as PendingDeprecationWarning already was), and now it’s not clear anymore why we have two separate categories.
(also note some projects have started to use FutureWarning, since it’s shown by default, as they find the hidden-by-default status of DeprecationWarning is detrimental to their users)
My guess is that you can get dozens of deprecation warnings, you should first focus on DeprecationWarning, and ignore PendingDeprecationWarning. But Antoine’s explanation makes sense. Maybe PendingDeprecationWarning don’t make sense anymore.
In practice, it’s common that a PendingDeprecationWarning introduced in version N is not converted to a DeprecationWarning in version N+1, just because everybody forgot about it. It’s also common that scheduled feature removals don’t happen
I’m open to change the -X dev option if it was your question. FYI you can already ignore PendingDeprecationWarning even when using -X dev.
-X dev has a lower priority than PYTHONWARNINGS and -W options by default, so you can override warning filters set by -X dev.
-X dev show PendingDeprecationWarning, whereas -X dev -W ignore::PendingDeprecationWarning ignores PendingDeprecationWarning.
Another example, PYTHONMALLOC has a higher priority than -X dev. So “PYTHONMALLOC=debug python3 -X dev” uses the default memory allocator, it doesn’t force to use debug memory allocators.
This is my observation too. We have not been rigorous about deprecating things which have expressed DeprecationWarning for. PendingDeprecationWarning may be worser, as the developer will have to track to deprecate it after the N releases in future.
I think, it is a good idea to revisit both these types of Warnings and probably choose one (DeprecationWarning), enable these by default and also define some protocols for deprecation of apis which have been marked with Deprecation Warning.
Oh, I didn’t know that. I used export PYTHONWARNINGS=default in my .bashrc.
But it’s difficult to recommend use -X dev always, because it may enable some options making Python slower.
If PendingDeprecationWarning is really worth enough, I think we should have two level -W options: -W all (-Wa) shows all warnings, -W default (-Wd) hides PendingDeprecationWarning.
But I still don’t feel we need two warning levels and two deprecation warning categories.
Even experienced Python developers doesn’t use -Wd daily, and find deprecation when it’s actually removed.
It means only one warning level is difficult enough for most Python developers.
What -X dev change makes Python too much slower to be recommended? PYTHONMALLOC=debug? I didn’t run any benchmark. I wrote -X dev for my usage, to debug CPython Maybe it doesn’t fit well the most common usage, run pure Python code?
I don’t think so For -X dev, my rationale is that I enable it when I would like to make a project “future proof”. The fact that a feature will change/will be removed in Python N+1 or Python N+3 doesn’t matter for me. I would like to prepare the code for any future Python version at once.
I’m running sometimes pip install with PYTHONDEVMODE=1, but not too often because I’m depressed by the high number of DeprecationWarning I’m trying to focus on ResourceWarning (I frequently fix a bunch of them in code used by pip, sometimes not in pip directly).
I think part of that is because we have not been removing anything due to Python 2 compatibility. But yes, we have not been great at this.
I’ve contemplated adding something to warnings where you specify what version of Python something is scheduled to be removed in and then it would raise PendingDeprecationWarning in >N version, DeprecationWarning in N, and raise a RuntimeError or something for N+1 so it doesn’t get forgotten.
Can’t we just create bpo issues for each deprecation, and mark them as release blockers for the next (or appropriate) version? They’re not likely to be overlooked.
I don’t understand why it’s so important to remove deprecated functionality. If you intend to remove some functionality from 3.9 (say) and you forget, is that really a problem?
It’s important to specify a minimum time, like “this functionality won’t be removed in 3.8”. But whether it’s removed in 3.9 or 3.10 or 4.0, why does that matter? You could just keep the deprecated functionality until somebody bothers to remove it.
IMHO we are not good to keep track of bugs. There are too many bugs, and no board to get a specific view of specific issues. Only searches using some parameters.
But I agree with @jdemeyer that it’s ok if we forget to remove a feature.
+1. Having a clear deadline, and a definite intention to remove the feature in a given, documented release, is absolutely worthwhile. But if we forget to do the removal at the planned time, why would anyone mind? Remove it (for the next feature release) as soon as we notice, and move on.
Yes, if we even have a version that far into the future, e.g. Python 3.10/4.0.
There’s two reasons to me. One is that leaving deprecated code in raises the chance that people will start using the deprecated code beyond those who predate the deprecation, accidental or not. That just leaves to that much more user pain when we do finally remove the code. This also applies to anyone who submits a PR against deprecated code.
Two, if people don’t believe we will remove stuff on time then they won’t take the deprecation as seriously.
Just so people know what I have thought about, I’ve contemplated adding the following to warnings:
def _deprecate(message, *, remove, start=None, stacklevel=2):
"""Deprecate starting in the Python version 'start' and remove in 'remove'.
Both 'start' and 'remove' are two-item tuples representing a (major, minor)
version of Python. If 'start' is specified, then the >N-1 version of 'remove'
will raise PendingDeprecationWarning, otherwise DeprecationWarning is
raised for >N of 'remove'. When the Python version <= 'remove' then XXX.
"""
I don’t know if some other warning should be raised once remove is reached or raise an exception.
I’m also tempted to provide a way to have a template message for the warning since most are of the form f"{name} has been deprecated since {start} and is slated for removal in {remove}; use {alternative} instead" (with obvious tweaks based on what is provided in the function call).
I like it. Raising an exception is the right thing to do when the remove version is hit. It forces us to find and remove it by virtue of test failures. Major version specifics don’t even matter. Suppose for example that 3.13 wound up rebranded as 4.0, anything marked remove as (3, 14) would turn into an exception with version_info[:2] of (4, 0) and could be adjusted to (4, 1) where appropriate in the change altering our version number.