Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions custom_dict.txt
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ lineset's
linesets
linkers
linter
linter's
linux
listcomp
Logilab
Expand Down Expand Up @@ -228,6 +229,7 @@ mymodule
mypy
namedtuple
namespace
natively
newsfile
newstyle
nl
Expand Down
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/8460.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix ``store_true`` boolean config options (like ``exit-zero``) in TOML files not respecting ``false`` values. Setting ``exit-zero = false`` in a TOML config previously behaved the same as ``exit-zero = true``.

Closes #8460
53 changes: 43 additions & 10 deletions pylint/config/config_file_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from __future__ import annotations

import argparse
import configparser
import os
import sys
Expand Down Expand Up @@ -60,7 +61,9 @@
return False

@staticmethod
def parse_toml_file(file_path: Path) -> PylintConfigFileData:
def parse_toml_file(
file_path: Path, store_true_options: set[str] | None = None
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this optional?

) -> PylintConfigFileData:
"""Parse and handle errors of a toml configuration file.

Raises ``tomllib.TOMLDecodeError``.
Expand All @@ -77,18 +80,38 @@
for opt, values in sections_values.items():
if isinstance(values, dict):
for config, value in values.items():
value = _parse_rich_type_value(value)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of duplication. Have you explored if we can do this in _parse_rich_type_value instead?

config_content[config] = value
options += [f"--{config}", value]
if (
isinstance(value, bool)
and store_true_options
and config in store_true_options
):
config_content[config] = str(value)
if value:
options.append(f"--{config}")
else:
value = _parse_rich_type_value(value)
config_content[config] = value
options += [f"--{config}", value]
else:
values = _parse_rich_type_value(values)
config_content[opt] = values
options += [f"--{opt}", values]
if (
isinstance(values, bool)
and store_true_options
and opt in store_true_options
):
config_content[opt] = str(values)
if values:
options.append(f"--{opt}")
else:
values = _parse_rich_type_value(values)
config_content[opt] = values
options += [f"--{opt}", values]

Check notice on line 107 in pylint/config/config_file_parser.py

View workflow job for this annotation

GitHub Actions / pylint

R5501

Consider using "elif" instead of "else" then "if" to remove one indentation level
return config_content, options

@staticmethod
def parse_config_file(
file_path: Path | None, verbose: bool
file_path: Path | None,
verbose: bool,
store_true_options: set[str] | None = None,
) -> PylintConfigFileData:
"""Parse a config file and return str-str pairs.

Expand All @@ -109,7 +132,7 @@
print(f"Using config file {file_path}", file=sys.stderr)

if file_path.suffix == ".toml":
return _RawConfParser.parse_toml_file(file_path)
return _RawConfParser.parse_toml_file(file_path, store_true_options)
return _RawConfParser.parse_ini_file(file_path)


Expand All @@ -122,8 +145,18 @@

def parse_config_file(self, file_path: Path | None) -> PylintConfigFileData:
"""Parse a config file and return str-str pairs."""
# Build a set of store_true option names (bare, without --)
# so parse_toml_file can handle boolean values correctly.
store_true_options: set[str] = set()
for action in self.linter._arg_parser._actions:
if isinstance(action, argparse._StoreTrueAction):
for opt_string in action.option_strings:
store_true_options.add(opt_string.lstrip("-"))

try:
return _RawConfParser.parse_config_file(file_path, self.verbose_mode)
return _RawConfParser.parse_config_file(
file_path, self.verbose_mode, store_true_options
)
except (configparser.Error, tomllib.TOMLDecodeError) as e:
self.linter.add_message("config-parse-error", line=0, args=str(e))
return {}, []
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exit_zero": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Test that boolean false values in TOML config are properly respected
# for store_true options. Setting exit-zero = false should NOT cause
# pylint to always exit with code 0.

[tool.pylint.main]
exit-zero = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"exit_zero": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Test that boolean true values in TOML config still work correctly
# for store_true options.

[tool.pylint.main]
exit-zero = true
Loading