Skip to content

Commit e6ff144

Browse files
authored
fix: make file ordering deterministic (#14)
1 parent d8303a6 commit e6ff144

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

package_python_function/packager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ def zip_all_dependencies(self, target_path: Path) -> None:
4646

4747
with ZipFile(target_path, "w", ZIP_DEFLATED) as zip_file:
4848
def zip_dir(path: Path) -> None:
49-
for item in path.iterdir():
49+
# use sorted to make sure files are always written in a deterministic order
50+
for item in sorted(path.iterdir(), key=lambda i: i.name):
5051
if item.is_dir():
5152
if item.name not in self.DIRS_TO_EXCLUDE:
5253
zip_dir(item)

tests/test_package_python_function.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,45 @@ def test_package_python_function(
7272
else:
7373
assert (verify_dir / file.path).exists()
7474

75+
def test_python_package_deterministic_file_ordering(
76+
test_data: Data,
77+
tmp_path: Path,
78+
monkeypatch: MonkeyPatch,
79+
):
80+
zip_contents: dict[str, list[str]] = {}
81+
82+
original_iterdir = Path.iterdir
83+
84+
# Simulate adding the files in a random order
85+
def shuffled_iterdir(path: Path):
86+
import random
87+
88+
results = list(original_iterdir(path))
89+
random.shuffle(results)
90+
return iter(results)
91+
92+
monkeypatch.setattr(Path, "iterdir", shuffled_iterdir)
93+
94+
for id in ["a", "b"]:
95+
output = tmp_path / f"output_{id}"
96+
output.mkdir()
97+
sys.argv = [
98+
"test_package_python_function",
99+
str(test_data.venv_dir),
100+
"--project",
101+
str(test_data.pyproject.path),
102+
"--output-dir",
103+
str(output),
104+
]
105+
main()
106+
zip_file = output / f"{test_data.pyproject.name.replace('-', '_')}.zip"
107+
with zipfile.ZipFile(zip_file, "r") as zip_file:
108+
zip_contents[id] = [zi.filename for zi in zip_file.infolist()]
109+
110+
assert zip_contents["a"] == zip_contents["b"], (
111+
"File ordering in the zip file is not deterministic when the input file order is shuffled."
112+
)
113+
75114
@pytest.mark.parametrize(
76115
"src_epoch, expected_exception, expected_date_time",
77116
[

0 commit comments

Comments
 (0)