Skip to content

Commit a6e02fb

Browse files
Prevent useless-suppression on disables for stdlib deprecation checker (#5876)
Co-authored-by: Marc Mueller <[email protected]>
1 parent 588ed30 commit a6e02fb

16 files changed

+84
-18
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ Release date: TBA
421421

422422
Closes #5862
423423

424+
* Disables for ``deprecated-module`` and similar warnings for stdlib features deprecated
425+
in newer versions of Python no longer raise ``useless-suppression`` when linting with
426+
older Python interpreters where those features are not yet deprecated.
427+
424428
* Importing the deprecated stdlib module ``distutils`` now emits ``deprecated_module`` on Python 3.10+.
425429

426430
* ``missing-raises-doc`` will now check the class hierarchy of the raised exceptions

doc/whatsnew/2.13.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,10 @@ Other Changes
402402
* The ``testutils`` for unittests now accept ``end_lineno`` and ``end_column``. Tests
403403
without these will trigger a ``DeprecationWarning``.
404404

405+
* Disables for ``deprecated-module`` and similar warnings for stdlib features deprecated
406+
in newer versions of Python no longer raise ``useless-suppression`` when linting with
407+
older Python interpreters where those features are not yet deprecated.
408+
405409
* Importing the deprecated stdlib module ``xml.etree.cElementTree`` now emits ``deprecated_module``.
406410

407411
Closes #5862

pylint/checkers/stdlib.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
import sys
4141
from collections.abc import Iterable
42-
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set
42+
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
4343

4444
import astroid
4545
from astroid import nodes
@@ -473,24 +473,26 @@ class StdlibChecker(DeprecatedMixin, BaseChecker):
473473

474474
def __init__(self, linter: Optional["PyLinter"] = None) -> None:
475475
BaseChecker.__init__(self, linter)
476-
self._deprecated_methods: Set[Any] = set()
477-
self._deprecated_methods.update(DEPRECATED_METHODS[0])
476+
self._deprecated_methods: Set[str] = set()
477+
self._deprecated_arguments: Dict[
478+
str, Tuple[Tuple[Optional[int], str], ...]
479+
] = {}
480+
self._deprecated_classes: Dict[str, Set[str]] = {}
481+
self._deprecated_modules: Set[str] = set()
482+
self._deprecated_decorators: Set[str] = set()
483+
478484
for since_vers, func_list in DEPRECATED_METHODS[sys.version_info[0]].items():
479485
if since_vers <= sys.version_info:
480486
self._deprecated_methods.update(func_list)
481-
self._deprecated_attributes = {}
482487
for since_vers, func_list in DEPRECATED_ARGUMENTS.items():
483488
if since_vers <= sys.version_info:
484-
self._deprecated_attributes.update(func_list)
485-
self._deprecated_classes = {}
489+
self._deprecated_arguments.update(func_list)
486490
for since_vers, class_list in DEPRECATED_CLASSES.items():
487491
if since_vers <= sys.version_info:
488492
self._deprecated_classes.update(class_list)
489-
self._deprecated_modules = set()
490493
for since_vers, mod_list in DEPRECATED_MODULES.items():
491494
if since_vers <= sys.version_info:
492495
self._deprecated_modules.update(mod_list)
493-
self._deprecated_decorators = set()
494496
for since_vers, decorator_list in DEPRECATED_DECORATORS.items():
495497
if since_vers <= sys.version_info:
496498
self._deprecated_decorators.update(decorator_list)
@@ -788,7 +790,7 @@ def deprecated_methods(self):
788790
return self._deprecated_methods
789791

790792
def deprecated_arguments(self, method: str):
791-
return self._deprecated_attributes.get(method, ())
793+
return self._deprecated_arguments.get(method, ())
792794

793795
def deprecated_classes(self, module: str):
794796
return self._deprecated_classes.get(module, ())

pylint/constants.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,20 @@ class DeletedMessage(NamedTuple):
173173
# https://github.com/PyCQA/pylint/pull/3571
174174
DeletedMessage("C0330", "bad-continuation"),
175175
]
176+
177+
178+
# ignore some messages when emitting useless-suppression:
179+
# - cyclic-import: can show false positives due to incomplete context
180+
# - deprecated-{module, argument, class, method, decorator}:
181+
# can cause false positives for multi-interpreter projects
182+
# when linting with an interpreter on a lower python version
183+
INCOMPATIBLE_WITH_USELESS_SUPPRESSION = frozenset(
184+
[
185+
"R0401", # cyclic-import
186+
"W0402", # deprecated-module
187+
"W1505", # deprecated-method
188+
"W1511", # deprecated-argument
189+
"W1512", # deprecated-class
190+
"W1513", # deprecated-decorator
191+
]
192+
)

pylint/utils/file_state.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616

1717
from astroid import nodes
1818

19-
from pylint.constants import MSG_STATE_SCOPE_MODULE, WarningScope
19+
from pylint.constants import (
20+
INCOMPATIBLE_WITH_USELESS_SUPPRESSION,
21+
MSG_STATE_SCOPE_MODULE,
22+
WarningScope,
23+
)
2024

2125
if sys.version_info >= (3, 8):
2226
from typing import Literal
@@ -159,13 +163,14 @@ def iter_spurious_suppression_messages(
159163
]:
160164
for warning, lines in self._raw_module_msgs_state.items():
161165
for line, enable in lines.items():
162-
if not enable and (warning, line) not in self._ignored_msgs:
163-
# ignore cyclic-import check which can show false positives
164-
# here due to incomplete context
165-
if warning != "R0401":
166-
yield "useless-suppression", line, (
167-
msgs_store.get_msg_display_string(warning),
168-
)
166+
if (
167+
not enable
168+
and (warning, line) not in self._ignored_msgs
169+
and warning not in INCOMPATIBLE_WITH_USELESS_SUPPRESSION
170+
):
171+
yield "useless-suppression", line, (
172+
msgs_store.get_msg_display_string(warning),
173+
)
169174
# don't use iteritems here, _ignored_msgs may be modified by add_message
170175
for (warning, from_), ignored_lines in list(self._ignored_msgs.items()):
171176
for line in ignored_lines:
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""Test that versions below Py3.10 will not emit useless-suppression for
2+
disabling deprecated-method (on a method deprecated in Py3.10.
3+
4+
This test can be run on all Python versions, but it will lack value when
5+
Pylint drops support for 3.9."""
6+
# pylint: disable=import-error, unused-import
7+
8+
import threading.current_thread # pylint: disable=deprecated-method
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""Test deprecated methods from Python 3.9."""
2+
3+
import binascii
4+
binascii.b2a_hqx() # [deprecated-method]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[testoptions]
2+
min_pyver=3.9
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
deprecated-method:4:0:4:18::Using deprecated method b2a_hqx():UNDEFINED
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
deprecated-module:4:::Uses of a deprecated module 'optparse'
1+
deprecated-module:4:0:4:15::Uses of a deprecated module 'optparse':UNDEFINED
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""Test deprecated modules from Python 3.9."""
2+
# pylint: disable=unused-import
3+
4+
import binhex # [deprecated-module]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[testoptions]
2+
min_pyver=3.9
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
deprecated-module:4:0:4:13::Uses of a deprecated module 'binhex':UNDEFINED
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""Test deprecated modules from Python 3.9,
2+
but use an earlier --py-version and ensure a warning is still emitted.
3+
"""
4+
# pylint: disable=unused-import
5+
6+
import binhex # [deprecated-module]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[master]
2+
py-version=3.8
3+
4+
[testoptions]
5+
min_pyver=3.9
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
deprecated-module:6:0:6:13::Uses of a deprecated module 'binhex':UNDEFINED

0 commit comments

Comments
 (0)