From 04add3de60e42d4e8de4138824b89a885ebd667b Mon Sep 17 00:00:00 2001 From: Christian Schmidbauer Date: Fri, 10 Jul 2026 12:22:16 +0200 Subject: [PATCH] fix: report a clear error when config has no [requirements] section mirror() crashed with a bare KeyError when the (hand-written) config file was missing the [requirements] section. Raise a ValueError with a message pointing at the config file instead. Co-Authored-By: Claude Fable 5 --- morgan/__init__.py | 3 +++ tests/test_init.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/morgan/__init__.py b/morgan/__init__.py index b1a5144..5835c9b 100644 --- a/morgan/__init__.py +++ b/morgan/__init__.py @@ -813,6 +813,9 @@ def mirror(args: argparse.Namespace): """ m = Mirrorer(args) + if not m.config.has_section("requirements"): + msg = f"Config file {args.config} has no [requirements] section" + raise ValueError(msg) for package in m.config["requirements"]: reqs = m.config["requirements"][package].splitlines() if not reqs: diff --git a/tests/test_init.py b/tests/test_init.py index bcce0df..9c3234c 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -12,6 +12,7 @@ import packaging.version import pytest +import morgan from morgan import ( PYPI_ADDRESS, Mirrorer, @@ -761,3 +762,31 @@ def test_process_file_rejects_escaping_path(self, mirrorer, monkeypatch): with pytest.raises(ValueError, match="Unsafe file path"): # pylint: disable=W0212 mirrorer._process_file(requirement, fileinfo) # noqa: SLF001 + + +class TestMirrorConfigValidation: + def test_mirror_reports_missing_requirements_section(self, tmp_path): + config_path = os.path.join(tmp_path, "morgan.ini") + with open(config_path, "w", encoding="utf-8") as f: + f.write( + """ + [env.test_env] + python_version = 3.10 + sys_platform = linux + platform_machine = x86_64 + """, + ) + args = argparse.Namespace( + index_path=str(tmp_path), + index_url=PYPI_ADDRESS, + config=config_path, + mirror_all_versions=False, + package_type_regex=r"(whl|zip|tar\.gz)", + mirror_all_wheels=False, + target_url=None, + use_pypi_metadata=False, + skip_server_copy=True, + ) + + with pytest.raises(ValueError, match=r"no \[requirements\] section"): + morgan.mirror(args)