Skip to content

Commit 231447c

Browse files
[config] Create a config parsing class indpendant from Pylinter (#8707)
This will permit to parse config file without having to instantiate a linter for tool working on pylint configuration like #5462
1 parent ff471cb commit 231447c

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

pylint/config/config_file_parser.py

+41-25
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import os
1111
import sys
1212
from pathlib import Path
13-
from typing import TYPE_CHECKING
13+
from typing import TYPE_CHECKING, Dict, List, Tuple
1414

1515
from pylint.config.utils import _parse_rich_type_value
1616

@@ -22,25 +22,26 @@
2222
if TYPE_CHECKING:
2323
from pylint.lint import PyLinter
2424

25+
PylintConfigFileData = Tuple[Dict[str, str], List[str]]
2526

26-
class _ConfigurationFileParser:
27+
28+
class _RawConfParser:
2729
"""Class to parse various formats of configuration files."""
2830

29-
def __init__(self, verbose: bool, linter: PyLinter) -> None:
30-
self.verbose_mode = verbose
31-
self.linter = linter
31+
@staticmethod
32+
def parse_ini_file(file_path: Path) -> PylintConfigFileData:
33+
"""Parse and handle errors of an ini configuration file.
3234
33-
def _parse_ini_file(self, file_path: Path) -> tuple[dict[str, str], list[str]]:
34-
"""Parse and handle errors of a ini configuration file."""
35+
Raises ``configparser.Error``.
36+
"""
3537
parser = configparser.ConfigParser(inline_comment_prefixes=("#", ";"))
36-
3738
# Use this encoding in order to strip the BOM marker, if any.
3839
with open(file_path, encoding="utf_8_sig") as fp:
3940
parser.read_file(fp)
4041

4142
config_content: dict[str, str] = {}
4243
options: list[str] = []
43-
ini_file_with_sections = self._ini_file_with_sections(file_path)
44+
ini_file_with_sections = _RawConfParser._ini_file_with_sections(file_path)
4445
for section in parser.sections():
4546
if ini_file_with_sections and not section.startswith("pylint"):
4647
continue
@@ -58,15 +59,14 @@ def _ini_file_with_sections(file_path: Path) -> bool:
5859
return True
5960
return False
6061

61-
def _parse_toml_file(self, file_path: Path) -> tuple[dict[str, str], list[str]]:
62-
"""Parse and handle errors of a toml configuration file."""
63-
try:
64-
with open(file_path, mode="rb") as fp:
65-
content = tomllib.load(fp)
66-
except tomllib.TOMLDecodeError as e:
67-
self.linter.add_message("config-parse-error", line=0, args=str(e))
68-
return {}, []
62+
@staticmethod
63+
def parse_toml_file(file_path: Path) -> PylintConfigFileData:
64+
"""Parse and handle errors of a toml configuration file.
6965
66+
Raises ``tomllib.TOMLDecodeError``.
67+
"""
68+
with open(file_path, mode="rb") as fp:
69+
content = tomllib.load(fp)
7070
try:
7171
sections_values = content["tool"]["pylint"]
7272
except KeyError:
@@ -86,12 +86,16 @@ def _parse_toml_file(self, file_path: Path) -> tuple[dict[str, str], list[str]]:
8686
options += [f"--{opt}", values]
8787
return config_content, options
8888

89+
@staticmethod
8990
def parse_config_file(
90-
self, file_path: Path | None
91-
) -> tuple[dict[str, str], list[str]]:
92-
"""Parse a config file and return str-str pairs."""
91+
file_path: Path | None, verbose: bool
92+
) -> PylintConfigFileData:
93+
"""Parse a config file and return str-str pairs.
94+
95+
Raises ``tomllib.TOMLDecodeError``, ``configparser.Error``.
96+
"""
9397
if file_path is None:
94-
if self.verbose_mode:
98+
if verbose:
9599
print(
96100
"No config file found, using default configuration", file=sys.stderr
97101
)
@@ -101,13 +105,25 @@ def parse_config_file(
101105
if not file_path.exists():
102106
raise OSError(f"The config file {file_path} doesn't exist!")
103107

104-
if self.verbose_mode:
108+
if verbose:
105109
print(f"Using config file {file_path}", file=sys.stderr)
106110

111+
if file_path.suffix == ".toml":
112+
return _RawConfParser.parse_toml_file(file_path)
113+
return _RawConfParser.parse_ini_file(file_path)
114+
115+
116+
class _ConfigurationFileParser:
117+
"""Class to parse various formats of configuration files."""
118+
119+
def __init__(self, verbose: bool, linter: PyLinter) -> None:
120+
self.verbose_mode = verbose
121+
self.linter = linter
122+
123+
def parse_config_file(self, file_path: Path | None) -> PylintConfigFileData:
124+
"""Parse a config file and return str-str pairs."""
107125
try:
108-
if file_path.suffix == ".toml":
109-
return self._parse_toml_file(file_path)
110-
return self._parse_ini_file(file_path)
126+
return _RawConfParser.parse_config_file(file_path, self.verbose_mode)
111127
except (configparser.Error, tomllib.TOMLDecodeError) as e:
112128
self.linter.add_message("config-parse-error", line=0, args=str(e))
113129
return {}, []

0 commit comments

Comments
 (0)