summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2021-12-23 23:02:34 +0100
committerGitHub <noreply@github.com>2021-12-23 23:02:34 +0100
commitb4bf5168621f0a4bf7cca795862e2b5c139fc8cb (patch)
tree9103f50e667e2cdac1cc140938a48b3d8b6c3c04
parent1a122dd7c4ace87574440bb78fc9b4ddcbd123d1 (diff)
downloadpylint-git-b4bf5168621f0a4bf7cca795862e2b5c139fc8cb.tar.gz
Create ``_config_initialization`` util and use in functional tests (#5591)
-rw-r--r--pylint/config/config_initialization.py75
-rw-r--r--pylint/lint/run.py42
-rw-r--r--pylint/testutils/lint_module_test.py15
-rw-r--r--tests/testutils/data/init_hook.py3
-rw-r--r--tests/testutils/data/init_hook.rc3
-rw-r--r--tests/testutils/test_functional_testutils.py21
6 files changed, 111 insertions, 48 deletions
diff --git a/pylint/config/config_initialization.py b/pylint/config/config_initialization.py
new file mode 100644
index 000000000..46031bae3
--- /dev/null
+++ b/pylint/config/config_initialization.py
@@ -0,0 +1,75 @@
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
+
+import sys
+from typing import TYPE_CHECKING, List, Optional, Union
+
+from pylint import reporters
+from pylint.utils import utils
+
+if TYPE_CHECKING:
+ from pylint.lint import PyLinter
+
+
+def _config_initialization(
+ linter: "PyLinter",
+ args_list: List[str],
+ reporter: Union[reporters.BaseReporter, reporters.MultiReporter, None] = None,
+ config_file: Optional[str] = None,
+ verbose_mode: Optional[bool] = None,
+) -> List[str]:
+ """Parse all available options, read config files and command line arguments and
+ set options accordingly.
+ """
+
+ # Read the config file. The parser is stored on linter.cfgfile_parser
+ try:
+ linter.read_config_file(config_file=config_file, verbose=verbose_mode)
+ except OSError as ex:
+ print(ex, file=sys.stderr)
+ sys.exit(32)
+ config_parser = linter.cfgfile_parser
+
+ # Run init hook, if present, before loading plugins
+ if config_parser.has_option("MASTER", "init-hook"):
+ exec( # pylint: disable=exec-used
+ utils._unquote(config_parser.get("MASTER", "init-hook"))
+ )
+
+ # Load plugins if specified in the config file
+ if config_parser.has_option("MASTER", "load-plugins"):
+ plugins = utils._splitstrip(config_parser.get("MASTER", "load-plugins"))
+ linter.load_plugin_modules(plugins)
+
+ # Now we can load file config, plugins (which can
+ # provide options) have been registered
+ linter.load_config_file()
+
+ if reporter:
+ # If a custom reporter is provided as argument, it may be overridden
+ # by file parameters, so re-set it here, but before command line
+ # parsing, so it's still overridable by command line option
+ linter.set_reporter(reporter)
+
+ # Load command line arguments
+ try:
+ args_list = linter.load_command_line_configuration(args_list)
+ except SystemExit as exc:
+ if exc.code == 2: # bad options
+ exc.code = 32
+ raise
+
+ # args_list should now only be a list of files/directories to lint. All options have
+ # been removed from the list
+ if not args_list:
+ print(linter.help())
+ sys.exit(32)
+
+ # We have loaded configuration from config file and command line. Now, we can
+ # load plugin specific configuration.
+ linter.load_plugin_configuration()
+
+ # Now that plugins are loaded, get list of all fail_on messages, and enable them
+ linter.enable_fail_on_messages()
+
+ return args_list
diff --git a/pylint/lint/run.py b/pylint/lint/run.py
index a349298c1..a7539cd6a 100644
--- a/pylint/lint/run.py
+++ b/pylint/lint/run.py
@@ -6,6 +6,7 @@ import sys
import warnings
from pylint import __pkginfo__, extensions, interfaces
+from pylint.config.config_initialization import _config_initialization
from pylint.constants import DEFAULT_PYLINT_HOME, OLD_DEFAULT_PYLINT_HOME, full_version
from pylint.lint.pylinter import PyLinter
from pylint.lint.utils import ArgumentPreprocessingError, preprocess_options
@@ -327,40 +328,8 @@ to search for configuration file.
# read configuration
linter.disable("I")
linter.enable("c-extension-no-member")
- try:
- linter.read_config_file(verbose=self.verbose)
- except OSError as ex:
- print(ex, file=sys.stderr)
- sys.exit(32)
- config_parser = linter.cfgfile_parser
- # run init hook, if present, before loading plugins
- if config_parser.has_option("MASTER", "init-hook"):
- cb_init_hook(
- "init-hook", utils._unquote(config_parser.get("MASTER", "init-hook"))
- )
- # is there some additional plugins in the file configuration, in
- if config_parser.has_option("MASTER", "load-plugins"):
- plugins = utils._splitstrip(config_parser.get("MASTER", "load-plugins"))
- linter.load_plugin_modules(plugins)
- # now we can load file config and command line, plugins (which can
- # provide options) have been registered
- linter.load_config_file()
-
- if reporter:
- # If a custom reporter is provided as argument, it may be overridden
- # by file parameters, so re-set it here, but before command line
- # parsing, so it's still overridable by command line option
- linter.set_reporter(reporter)
- try:
- args = linter.load_command_line_configuration(args)
- except SystemExit as exc:
- if exc.code == 2: # bad options
- exc.code = 32
- raise
- if not args:
- print(linter.help())
- sys.exit(32)
+ args = _config_initialization(linter, args, reporter, verbose_mode=self.verbose)
if linter.config.jobs < 0:
print(
@@ -378,13 +347,6 @@ to search for configuration file.
elif linter.config.jobs == 0:
linter.config.jobs = _cpu_count()
- # We have loaded configuration from config file and command line. Now, we can
- # load plugin specific configuration.
- linter.load_plugin_configuration()
-
- # Now that plugins are loaded, get list of all fail_on messages, and enable them
- linter.enable_fail_on_messages()
-
if self._output:
try:
with open(self._output, "w", encoding="utf-8") as output:
diff --git a/pylint/testutils/lint_module_test.py b/pylint/testutils/lint_module_test.py
index b7e1ffc67..e89f82ace 100644
--- a/pylint/testutils/lint_module_test.py
+++ b/pylint/testutils/lint_module_test.py
@@ -14,6 +14,7 @@ import pytest
from _pytest.config import Config
from pylint import checkers
+from pylint.config.config_initialization import _config_initialization
from pylint.lint import PyLinter
from pylint.message.message import Message
from pylint.testutils.constants import _EXPECTED_RE, _OPERATORS, UPDATE_OPTION
@@ -24,7 +25,6 @@ from pylint.testutils.functional.test_file import ( # need to import from funct
)
from pylint.testutils.output_line import OutputLine
from pylint.testutils.reporter_for_tests import FunctionalTestReporter
-from pylint.utils import utils
MessageCounter = CounterType[Tuple[int, str]]
@@ -44,15 +44,14 @@ class LintModuleTest:
self._linter.disable("locally-disabled")
self._linter.disable("useless-suppression")
try:
- self._linter.read_config_file(test_file.option_file)
- if self._linter.cfgfile_parser.has_option("MASTER", "load-plugins"):
- plugins = utils._splitstrip(
- self._linter.cfgfile_parser.get("MASTER", "load-plugins")
- )
- self._linter.load_plugin_modules(plugins)
- self._linter.load_config_file()
+ _config_initialization(
+ self._linter,
+ [test_file.source],
+ config_file=test_file.option_file,
+ )
except NoFileError:
pass
+
self._test_file = test_file
self._config = config
self._check_end_position = (
diff --git a/tests/testutils/data/init_hook.py b/tests/testutils/data/init_hook.py
new file mode 100644
index 000000000..f16492d3a
--- /dev/null
+++ b/tests/testutils/data/init_hook.py
@@ -0,0 +1,3 @@
+"""This file should never be tested as the init-hook in the configuration
+file prevents the test runner from getting here.
+"""
diff --git a/tests/testutils/data/init_hook.rc b/tests/testutils/data/init_hook.rc
new file mode 100644
index 000000000..b0efa254b
--- /dev/null
+++ b/tests/testutils/data/init_hook.rc
@@ -0,0 +1,3 @@
+[MASTER]
+
+init-hook=raise RuntimeError
diff --git a/tests/testutils/test_functional_testutils.py b/tests/testutils/test_functional_testutils.py
new file mode 100644
index 000000000..c1e852e15
--- /dev/null
+++ b/tests/testutils/test_functional_testutils.py
@@ -0,0 +1,21 @@
+# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
+
+"""Tests for the functional test framework."""
+
+from pathlib import Path
+
+import pytest
+
+from pylint import testutils
+from pylint.testutils.functional import FunctionalTestFile
+
+HERE = Path(__file__).parent
+DATA_DIRECTORY = HERE / "data"
+
+
+def test_parsing_of_pylintrc_init_hook() -> None:
+ """Test that we correctly parse an init-hook in a settings file."""
+ with pytest.raises(RuntimeError):
+ test_file = FunctionalTestFile(str(DATA_DIRECTORY), "init_hook.py")
+ testutils.LintModuleTest(test_file)