You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by gi...@apache.org on 2026/09/07 06:13:27 UTC

(iceberg-python) branch gh-readonly-queue/main/pr-3915-7a7a99b9711bfa2922962b207517fc43f9c525a7 created (now 75b74cfca)

This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-3915-7a7a99b9711bfa2922962b207517fc43f9c525a7
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git


      at 75b74cfca fix: treat a .pyiceberg.yaml without a mapping as no config (#3915)

This branch includes the following new commits:

     new 75b74cfca fix: treat a .pyiceberg.yaml without a mapping as no config (#3915)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(iceberg-python) 01/01: fix: treat a .pyiceberg.yaml without a mapping as no config (#3915)

Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-3915-7a7a99b9711bfa2922962b207517fc43f9c525a7
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git

commit 75b74cfca0d0491e94c12c9da978eeb0bc05698a
Author: jackylee <qc...@gmail.com>
AuthorDate: Mon Sep 7 06:13:04 2026 +0000

    fix: treat a .pyiceberg.yaml without a mapping as no config (#3915)
    
    `_load_yaml` passed `strictyaml.load(...).data` straight to
    `_lowercase_dictionary_keys`. For an empty or comment-only document that
    value is a `str`, not a mapping, so the call raised
    `AttributeError: 'str' object has no attribute 'items'`.
    
    `Config()` runs at import time, so commenting out the file made
    `import pyiceberg.catalog` fail with an error naming neither YAML nor the
    file. Return `None` instead, which the annotated return type already allows
    and which the caller already handles as "keep looking".
    
    Co-authored-by: Claude Code <no...@anthropic.com>
---
 pyiceberg/utils/config.py  |  3 +++
 tests/utils/test_config.py | 17 +++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/pyiceberg/utils/config.py b/pyiceberg/utils/config.py
index ab9b549d2..2b5baafa5 100644
--- a/pyiceberg/utils/config.py
+++ b/pyiceberg/utils/config.py
@@ -79,6 +79,9 @@ class Config:
                     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 5cd6a7203..309821023 100644
--- a/tests/utils/test_config.py
+++ b/tests/utils/test_config.py
@@ -183,3 +183,20 @@ def test_config_lookup_order(
     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