diff --git a/pyiceberg/utils/config.py b/pyiceberg/utils/config.py index ab9b549d25..2b5baafa59 100644 --- a/pyiceberg/utils/config.py +++ b/pyiceberg/utils/config.py @@ -79,6 +79,9 @@ def _load_yaml(directory: str | None) -> RecursiveDict | None: with open(path, encoding=UTF8) as f: yml_str = f.read() file_config = strictyaml.load(yml_str).data + if not isinstance(file_config, dict): + # An empty or comment-only document parses as a string + return None file_config_lowercase = _lowercase_dictionary_keys(file_config) return file_config_lowercase return None diff --git a/tests/utils/test_config.py b/tests/utils/test_config.py index 5cd6a7203a..309821023d 100644 --- a/tests/utils/test_config.py +++ b/tests/utils/test_config.py @@ -183,3 +183,20 @@ def create_config_file(path: str, uri: str | None) -> None: assert ( result["catalog"]["default"]["uri"] if result else None # type: ignore ) == expected_result, f"Unexpected configuration result. Expected: {expected_result}, Actual: {result}" + + +@pytest.mark.parametrize("content", ["", "\n", "# only a comment\n"]) +def test_from_configuration_files_without_a_mapping( + monkeypatch: pytest.MonkeyPatch, tmp_path_factory: pytest.TempPathFactory, content: str +) -> None: + """A file that holds no mapping should be treated as absent.""" + pyiceberg_home = str(tmp_path_factory.mktemp("pyiceberg_home")) + empty_dir = str(tmp_path_factory.mktemp("empty")) + with open(os.path.join(pyiceberg_home, ".pyiceberg.yaml"), "w", encoding=UTF8) as file: + file.write(content) + + monkeypatch.setenv("PYICEBERG_HOME", pyiceberg_home) + monkeypatch.setattr(os.path, "expanduser", lambda _: empty_dir) + monkeypatch.chdir(empty_dir) + + assert Config()._from_configuration_files() is None