Skip to content
Open
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
2 changes: 2 additions & 0 deletions metaflow/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ def compress_list(lst, separator=",", rangedelim=":", zlibmarker="!", zlibmin=50


def decompress_list(lststr, separator=",", rangedelim=":", zlibmarker="!"):
if lststr == "":
return []
# Three input modes:
if lststr[0] == zlibmarker:
# 3. zlib-compressed, base64-encoded
Expand Down
45 changes: 45 additions & 0 deletions test/unit/test_compress_decompress_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""Tests for compress_list / decompress_list round-trip correctness.

Regression test for https://github.com/Netflix/metaflow/issues/3017:
decompress_list("") must return [] instead of raising IndexError.
"""

import pytest

from metaflow.util import compress_list, decompress_list


def test_compress_empty_list():
assert compress_list([]) == ""


def test_decompress_empty_string():
"""The bug: lststr[0] crashes on empty string."""
assert decompress_list("") == []


def test_roundtrip_empty():
assert decompress_list(compress_list([])) == []


@pytest.mark.parametrize(
"items",
[
pytest.param(["x"], id="single"),
pytest.param(["a", "b", "c"], id="simple"),
pytest.param(
["run/step/task/1", "run/step/task/2", "run/step/task/3"],
id="common-prefix",
),
],
)
def test_roundtrip(items):
assert decompress_list(compress_list(items)) == items


def test_roundtrip_zlib():
"""Force the zlib-compressed path by setting zlibmin=0."""
items = ["a", "b"]
compressed = compress_list(items, zlibmin=0)
assert compressed.startswith("!")
assert decompress_list(compressed) == items