Skip to content

Commit fd6790b

Browse files
authored
Add ignored modules to Astroid module deny list (#9504)
1 parent d5ad55d commit fd6790b

File tree

10 files changed

+51
-15
lines changed

10 files changed

+51
-15
lines changed

.pyenchant_pylint_custom_dict.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ spammy
300300
sqlalchemy
301301
src
302302
starargs
303+
stateful
303304
staticmethod
304305
stderr
305306
stdin

doc/user_guide/configuration/all-options.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ Standard Checkers
120120

121121
--ignored-modules
122122
"""""""""""""""""
123-
*List of module names for which member attributes should not be checked (useful for modules/projects where namespaces are manipulated during runtime and thus existing member attributes cannot be deduced by static analysis). It supports qualified module names, as well as Unix pattern matching.*
123+
*List of module names for which member attributes should not be checked and will not be imported (useful for modules/projects where namespaces are manipulated during runtime and thus existing member attributes cannot be deduced by static analysis). It supports qualified module names, as well as Unix pattern matching.*
124124

125125
**Default:** ``()``
126126

doc/whatsnew/fragments/9442.other

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Ignored modules are now not checked at all, instead of being checked and then
2+
ignored. This should speed up the analysis of large codebases which have
3+
ignored modules.
4+
5+
Closes #9442 (`#9442 <https://github.com/pylint-dev/pylint/issues/9442>`_)

examples/pylintrc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ ignore-paths=
5959
# Emacs file locks
6060
ignore-patterns=^\.#
6161

62-
# List of module names for which member attributes should not be checked
63-
# (useful for modules/projects where namespaces are manipulated during runtime
64-
# and thus existing member attributes cannot be deduced by static analysis). It
65-
# supports qualified module names, as well as Unix pattern matching.
62+
# List of module names for which member attributes should not be checked and
63+
# will not be imported (useful for modules/projects where namespaces are
64+
# manipulated during runtime and thus existing member attributes cannot be
65+
# deduced by static analysis). It supports qualified module names, as well
66+
# as Unix pattern matching.
6667
ignored-modules=
6768

6869
# Python code to execute, usually for sys.path manipulation such as

examples/pyproject.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ ignore = ["CVS"]
4949
# file locks
5050
ignore-patterns = ["^\\.#"]
5151

52-
# List of module names for which member attributes should not be checked (useful
53-
# for modules/projects where namespaces are manipulated during runtime and thus
54-
# existing member attributes cannot be deduced by static analysis). It supports
55-
# qualified module names, as well as Unix pattern matching.
52+
# List of module names for which member attributes should not be checked and
53+
# will not be imported (useful for modules/projects where namespaces are
54+
# manipulated during runtime and thus existing member attributes cannot be
55+
# deduced by static analysis). It supports qualified module names, as well
56+
# as Unix pattern matching.
5657
# ignored-modules =
5758

5859
# Python code to execute, usually for sys.path manipulation such as

pylint/lint/base_options.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ def _make_linter_options(linter: PyLinter) -> Options:
384384
"type": "csv",
385385
"metavar": "<module names>",
386386
"help": "List of module names for which member attributes "
387-
"should not be checked (useful for modules/projects "
387+
"should not be checked and will not be imported "
388+
"(useful for modules/projects "
388389
"where namespaces are manipulated during runtime and "
389390
"thus existing member attributes cannot be "
390391
"deduced by static analysis). It supports qualified "

pylint/lint/pylinter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,7 @@ def open(self) -> None:
10731073
MANAGER.always_load_extensions = self.config.unsafe_load_any_extension
10741074
MANAGER.max_inferable_values = self.config.limit_inference_results
10751075
MANAGER.extension_package_whitelist.update(self.config.extension_pkg_allow_list)
1076+
MANAGER.module_denylist.update(self.config.ignored_modules)
10761077
if self.config.extension_pkg_whitelist:
10771078
MANAGER.extension_package_whitelist.update(
10781079
self.config.extension_pkg_whitelist

pylintrc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,11 @@ property-classes=abc.abstractproperty
342342
# members is set to 'yes'
343343
mixin-class-rgx=.*MixIn
344344

345-
# List of module names for which member attributes should not be checked
346-
# (useful for modules/projects where namespaces are manipulated during runtime
347-
# and thus existing member attributes cannot be deduced by static analysis). It
348-
# supports qualified module names, as well as Unix pattern matching.
345+
# List of module names for which member attributes should not be checked and
346+
# will not be imported (useful for modules/projects where namespaces are
347+
# manipulated during runtime and thus existing member attributes cannot be
348+
# deduced by static analysis). It supports qualified module names, as well
349+
# as Unix pattern matching.
349350
ignored-modules=
350351

351352
# List of class names for which member attributes should not be checked (useful

tests/lint/test_pylinter.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from pytest import CaptureFixture
1212

13-
from pylint.lint.pylinter import PyLinter
13+
from pylint.lint.pylinter import MANAGER, PyLinter
1414
from pylint.utils import FileState
1515

1616

@@ -48,3 +48,14 @@ def test_crash_during_linting(
4848
assert len(files) == 1
4949
assert "pylint-crash-20" in str(files[0])
5050
assert any(m.symbol == "astroid-error" for m in linter.reporter.messages)
51+
52+
53+
def test_open_pylinter_denied_modules(linter: PyLinter) -> None:
54+
"""Test PyLinter open() adds ignored modules to Astroid manager deny list."""
55+
MANAGER.module_denylist = {"mod1"}
56+
try:
57+
linter.config.ignored_modules = ["mod2", "mod3"]
58+
linter.open()
59+
assert MANAGER.module_denylist == {"mod1", "mod2", "mod3"}
60+
finally:
61+
MANAGER.module_denylist = set()

tests/test_functional.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
from __future__ import annotations
88

99
import sys
10+
from collections.abc import Iterator
1011
from pathlib import Path
12+
from typing import TYPE_CHECKING
1113

1214
import pytest
1315
from _pytest.config import Config
1416

1517
from pylint import testutils
1618
from pylint.constants import PY312_PLUS
19+
from pylint.lint.pylinter import MANAGER
1720
from pylint.testutils import UPDATE_FILE, UPDATE_OPTION
1821
from pylint.testutils.functional import (
1922
FunctionalTestFile,
@@ -22,6 +25,9 @@
2225
)
2326
from pylint.utils import HAS_ISORT_5
2427

28+
if TYPE_CHECKING:
29+
from pylint.lint import PyLinter
30+
2531
FUNCTIONAL_DIR = Path(__file__).parent.resolve() / "functional"
2632

2733

@@ -40,6 +46,14 @@
4046
]
4147

4248

49+
@pytest.fixture
50+
def revert_stateful_config_changes(linter: PyLinter) -> Iterator[PyLinter]:
51+
yield linter
52+
# Revert any stateful configuration changes.
53+
MANAGER.brain["module_denylist"] = set()
54+
55+
56+
@pytest.mark.usefixtures("revert_stateful_config_changes")
4357
@pytest.mark.parametrize("test_file", TESTS, ids=TESTS_NAMES)
4458
def test_functional(test_file: FunctionalTestFile, pytestconfig: Config) -> None:
4559
__tracebackhide__ = True # pylint: disable=unused-variable

0 commit comments

Comments
 (0)