The logging.Logger.warn() method was deprecated in Python 3.3 by issue #57444 and commit 04d5bc0. This method is not documented and emits a DeprecationWarning since Python 3.3.
That's deliberate. The original code (before incorporation into Python) had warn(), which was kept for backward compatibility. The docs refer to warning() because that's what everyone is supposed to use. The method names map to the lower case of the appropriate logging level name.
I propose to remove this logging.Logger.warn() method in Python 3.13.
I would like to speak up for reversing this change. A lot of people, especially non-professional programmers, have written a lot of code with logging.warn(), and it is going to break in a way that will be very confusing to them. It's going to be especially thorny, since the thing that will fail will be their logging utility itself, which is usually where they would go to begin troubleshooting.
If this really is going to be removed, I would recommend at least one Python release where using logging.warn() emits a SyntaxWarning instead of a DeprecationWarning before removing it entirely, so that people have at least some visibility of the problem before their code breaks. This was done for invalid escape sequences in string literals in Python3.12, and I think it's a good model. Release notes link.
EDIT: I didn't notice until after I posted that the SyntaxWarning for invalid escape sequences was also done by @vstinner !
Whereas invalid escape sequences might reasonably be considered syntax warnings, I'm not sure that applies to methods that were deprecated long ago. In any case, it's easy enough for users to fix their broken code, in the (presumably) very rare instances where they didn't see the deprecation warning because they upgraded to the very latest Python version from a pre- 3.3 version.
Can you explain why you think a SyntaxWarning is better than the DeprecationWarning which was already in place?
@vsajip My preferred solution is to keep the warn() method in Logger with no changes.
If that isn't possible, I recommended the SyntaxWarning approach because I thought that it is visible by default, whereas DeprecationWarning is invisible by default. But based on some quick testing, that seems like it's not actually the case, at least universally.
I was trying to replicate this kind of behavior, where the warning about the deprecated behavior became more visible in 3.12:
In this case, the methods just echo the names of the levels they log at - they are just conveniences for the verb "log at ".
The novelty of warning is that unlike the other log levels, it does have a directly corresponding verb (warn). Sure, it's a shorthand for a shorthand, but it's a pretty harmless one.
If we dropped the warning (which was the part of my message you clipped out), it would be an alias of warning rather than a wrapper, and this would've been a non-issue. (Personally I'd redesign the whole thing to avoid stacklevel-type shenanigans anyway, but I'm not that motivated on it.)
Activity
pythongh-105376: Remove logging.Logger.warn() method
vstinner commented on Jun 6, 2023
cc @vsajip
The alternative is to remove the deprecation and keep this alias: see issue #105373.
pythongh-105376: Remove logging.Logger.warn() method
gh-105376: Remove logging.Logger.warn() method (#105377)
pythongh-105376: Remove logging.warn() and LoggerAdapter.warn()
gh-105376: Remove logging.warn() and LoggerAdapter.warn() (#106553)
refactor(main.py): remove deprecated logger.warn call
refactor(main.py): remove deprecated logger.warn call (#14)
Don't fail when logging.Logger.warn is not available
davidmayo commented on Aug 6, 2024
I would like to speak up for reversing this change. A lot of people, especially non-professional programmers, have written a lot of code with logging.warn(), and it is going to break in a way that will be very confusing to them. It's going to be especially thorny, since the thing that will fail will be their logging utility itself, which is usually where they would go to begin troubleshooting.
If this really is going to be removed, I would recommend at least one Python release where using logging.warn() emits a SyntaxWarning instead of a DeprecationWarning before removing it entirely, so that people have at least some visibility of the problem before their code breaks. This was done for invalid escape sequences in string literals in Python3.12, and I think it's a good model. Release notes link.
EDIT: I didn't notice until after I posted that the SyntaxWarning for invalid escape sequences was also done by @vstinner !
vsajip commented on Aug 6, 2024
Whereas invalid escape sequences might reasonably be considered syntax warnings, I'm not sure that applies to methods that were deprecated long ago. In any case, it's easy enough for users to fix their broken code, in the (presumably) very rare instances where they didn't see the deprecation warning because they upgraded to the very latest Python version from a pre- 3.3 version.
Can you explain why you think a SyntaxWarning is better than the DeprecationWarning which was already in place?
hugovk commented on Aug 6, 2024
These can be found with the Ruff linter: https://docs.astral.sh/ruff/rules/#flake8-logging-format-g
For example:
ruff check --isolated --select G010 .And auto-fixed:
ruff check --isolated --select G010 . --fixAnd found with pylint: https://pylint.readthedocs.io/en/stable/user_guide/messages/warning/deprecated-method.html
pylint --disable=all --enable=W4902 .And a Flake8 plugin: https://pypi.org/project/flake8-logging-format/
davidmayo commented on Aug 6, 2024
@vsajip My preferred solution is to keep the warn() method in Logger with no changes.
If that isn't possible, I recommended the SyntaxWarning approach because I thought that it is visible by default, whereas DeprecationWarning is invisible by default. But based on some quick testing, that seems like it's not actually the case, at least universally.
I was trying to replicate this kind of behavior, where the warning about the deprecated behavior became more visible in 3.12:
❯ python3.11 -c "print('\d')" \d ❯ python3.12 -c "print('\d')" <string>:1: SyntaxWarning: invalid escape sequence '\d' \d13 remaining items
zooba commented on Aug 7, 2024
I vote to keep it. This is hardly a maintenance burden - if we were to drop the deprecation warning then it's no maintenance burden at all.
"warn()", a verb, is a better method name anyway. I would normally assume "logging.warning" is a constant or type.
vsajip commented on Aug 7, 2024
In this case, the methods just echo the names of the levels they log at - they are just conveniences for the verb "log at ".
ncoghlan commented on Aug 8, 2024
The novelty of warning is that unlike the other log levels, it does have a directly corresponding verb (warn). Sure, it's a shorthand for a shorthand, but it's a pretty harmless one.
joukewitteveen commented on Aug 8, 2024
This is not true. The wrapper was an additional concern in #28287. In fact, it absorbed a substantial part of the total effort.
Remember the Zen of Python:
I'm in favor of removing the long-deprecated method.
zooba commented on Aug 8, 2024
If we dropped the warning (which was the part of my message you clipped out), it would be an alias of warning rather than a wrapper, and this would've been a non-issue. (Personally I'd redesign the whole thing to avoid stacklevel-type shenanigans anyway, but I'm not that motivated on it.)
gh-105376: Restore deprecated logging warn() method (#122775)
pythongh-105376: Restore deprecated logging warn() method (pythonGH-1…
[3.13] gh-105376: Restore deprecated logging warn() method (GH-122775) (
vstinner commented on Aug 9, 2024
I added again the warn() method.
pythongh-105376: Restore deprecated logging warn() method (python#122775
fix deprecation warning for logger.warn()
[fc] Repository: plone.behavior
[fc] Repository: plone.behavior
[fc] Repository: plone.behavior