From ebee3c8f18a002bf169935143b8882c2186d0bcc Mon Sep 17 00:00:00 2001 From: Eljees <57435526+Eljees@users.noreply.github.com> Date: Sat, 15 Aug 2026 23:31:02 +0300 Subject: [PATCH] fix: read rest-section-adorns from the configuration file Every command line option is read back from pyproject.toml / setup.cfg / tox.ini under its own hyphenated name -- in-place, wrap-summaries, pre-summary-space and so on. --rest-section-adorns is the one exception: it is read under rest_section_adorns, with underscores. docs/source/configuration.rst tells the user to set the ``rest-section-adorns`` option in the configuration file, so the spelling the documentation asks for is the spelling that gets dropped. The file is parsed correctly and the key does land in flargs; it is lost on the way to the argument default, which makes it silent -- no error, no warning, just the default adornment regex. Read the documented hyphenated key first and keep the underscored one as a fallback, so anyone who found the undocumented spelling by reading the source keeps working. --- src/docformatter/configuration.py | 6 +- tests/test_configuration_functions.py | 82 +++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/docformatter/configuration.py b/src/docformatter/configuration.py index 3fe45ee..3899e8f 100644 --- a/src/docformatter/configuration.py +++ b/src/docformatter/configuration.py @@ -178,7 +178,11 @@ def do_parse_arguments(self) -> None: type=str, dest="rest_section_adorns", default=self.flargs.get( - "rest_section_adorns", r"[!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]{4,}" + "rest-section-adorns", + self.flargs.get( + "rest_section_adorns", + r"[!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]{4,}", + ), ), help="regex for identifying reST section header adornments", ) diff --git a/tests/test_configuration_functions.py b/tests/test_configuration_functions.py index 0c63c39..a037276 100644 --- a/tests/test_configuration_functions.py +++ b/tests/test_configuration_functions.py @@ -699,3 +699,85 @@ def test_non_cap_from_setup_cfg( "diff": "true", "non-cap": '["qBittorrent", "iPad", "iOS", "eBay"]', } +DEFAULT_ADORNS = r"[!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]{4,}" + + +def _write_pyproject(directory, body): + """Write a pyproject.toml holding a [tool.docformatter] section.""" + config_file = directory / "pyproject.toml" + config_file.write_text("[tool.docformatter]\n" + body, encoding="utf-8") + return str(config_file) + + +class TestRestSectionAdornsConfigKey: + """Class for testing the rest-section-adorns configuration file key. + + The command line option is --rest-section-adorns and every other option + is read from the configuration file under its hyphenated command line + name. docs/source/configuration.rst tells the user to set the + ``rest-section-adorns`` option in the configuration file, so that + spelling has to be the one that is honored. + """ + + @pytest.mark.unit + def test_hyphenated_key_is_honored(self, tmp_path): + """Read the documented, hyphenated key from pyproject.toml.""" + config_file = _write_pyproject(tmp_path, 'rest-section-adorns = "[!]{4,}"\n') + + uut = Configurater(["/path/to/docformatter", "--config", config_file, ""]) + uut.do_parse_arguments() + + assert uut.flargs["rest-section-adorns"] == "[!]{4,}" + assert uut.args.rest_section_adorns == "[!]{4,}" + + @pytest.mark.unit + def test_underscored_key_is_still_honored(self, tmp_path): + """Keep reading the undocumented, underscored key.""" + config_file = _write_pyproject(tmp_path, 'rest_section_adorns = "[@]{4,}"\n') + + uut = Configurater(["/path/to/docformatter", "--config", config_file, ""]) + uut.do_parse_arguments() + + assert uut.args.rest_section_adorns == "[@]{4,}" + + @pytest.mark.unit + def test_hyphenated_key_wins_over_underscored_key(self, tmp_path): + """Prefer the documented spelling when a file carries both.""" + config_file = _write_pyproject( + tmp_path, + 'rest-section-adorns = "[!]{4,}"\nrest_section_adorns = "[@]{4,}"\n', + ) + + uut = Configurater(["/path/to/docformatter", "--config", config_file, ""]) + uut.do_parse_arguments() + + assert uut.args.rest_section_adorns == "[!]{4,}" + + @pytest.mark.unit + def test_default_is_used_when_key_is_absent(self, tmp_path): + """Fall back to the default adornment regex.""" + config_file = _write_pyproject(tmp_path, 'wrap-summaries = "79"\n') + + uut = Configurater(["/path/to/docformatter", "--config", config_file, ""]) + uut.do_parse_arguments() + + assert uut.args.rest_section_adorns == DEFAULT_ADORNS + + @pytest.mark.unit + def test_command_line_overrides_the_configuration_file(self, tmp_path): + """Let --rest-section-adorns beat the configuration file.""" + config_file = _write_pyproject(tmp_path, 'rest-section-adorns = "[!]{4,}"\n') + + uut = Configurater( + [ + "/path/to/docformatter", + "--config", + config_file, + "--rest-section-adorns", + "[~]{4,}", + "", + ] + ) + uut.do_parse_arguments() + + assert uut.args.rest_section_adorns == "[~]{4,}"