Skip to content
Merged
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
11 changes: 6 additions & 5 deletions pyiceberg/table/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import itertools
import logging
import os
import random
import time
import uuid
Expand Down Expand Up @@ -1963,19 +1962,21 @@ def refresh(self) -> Table:

@classmethod
def _metadata_location_from_version_hint(cls, metadata_location: str, properties: Properties = EMPTY_DICT) -> str:
version_hint_location = os.path.join(metadata_location, "metadata", "version-hint.text")
# Using os.path.join here would produce "\" separators on Windows, breaking URI locations
metadata_dir = f"{metadata_location.rstrip('/')}/metadata"
version_hint_location = f"{metadata_dir}/version-hint.text"
io = load_file_io(properties=properties, location=version_hint_location)
file = io.new_input(version_hint_location)

with file.open() as stream:
content = stream.read().decode("utf-8")

if content.endswith(".metadata.json"):
return os.path.join(metadata_location, "metadata", content)
return f"{metadata_dir}/{content}"
elif content.isnumeric():
return os.path.join(metadata_location, "metadata", f"v{content}.metadata.json")
return f"{metadata_dir}/v{content}.metadata.json"
else:
return os.path.join(metadata_location, "metadata", f"{content}.metadata.json")
return f"{metadata_dir}/{content}.metadata.json"

@classmethod
def from_metadata(cls, metadata_location: str, properties: Properties = EMPTY_DICT) -> StaticTable:
Expand Down
22 changes: 22 additions & 0 deletions tests/table/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import json
import uuid
from copy import copy
from pathlib import Path
from typing import Any

import pytest
Expand All @@ -37,6 +38,7 @@
from pyiceberg.io import PY_IO_IMPL, FileIO, load_file_io
from pyiceberg.partitioning import PartitionField, PartitionSpec
from pyiceberg.schema import Schema
from pyiceberg.serializers import ToOutputFile
from pyiceberg.table import (
CommitTableRequest,
StagedTable,
Expand Down Expand Up @@ -590,6 +592,26 @@ def test_static_table_version_hint_same_as_table(
assert static_table.metadata == table_v2.metadata


def test_static_table_version_hint_uri_location(table_v2: Table, tmp_path: Path) -> None:
# Fails on Windows if the locations are built with os.path.join
table_root = f"file://{tmp_path}"
file_io = load_file_io(location=table_root)

for version_hint_content, metadata_file in [
("v3.metadata.json", "v3.metadata.json"),
("3", "v3.metadata.json"),
("some-uuid", "some-uuid.metadata.json"),
]:
metadata_location = f"{table_root}/metadata/{metadata_file}"
ToOutputFile.table_metadata(table_v2.metadata, file_io.new_output(metadata_location), overwrite=True)
with file_io.new_output(f"{table_root}/metadata/version-hint.text").create(overwrite=True) as f:
f.write(version_hint_content.encode("utf-8"))

static_table = StaticTable.from_metadata(table_root)
assert static_table.metadata_location == metadata_location
assert static_table.metadata == table_v2.metadata


def test_static_table_io_does_not_exist(metadata_location: str) -> None:
with pytest.raises(ValueError):
StaticTable.from_metadata(metadata_location, {PY_IO_IMPL: "pyiceberg.does.not.exist.FileIO"})
Expand Down
Loading