From b37952400a6b8be45664c01f7eafbdaae74d17ba Mon Sep 17 00:00:00 2001 From: Anurag Kumar Singh Date: Mon, 31 Aug 2026 14:04:41 +0530 Subject: [PATCH] Fix decompress_list IndexError on empty string input (#3017) --- metaflow/util.py | 2 + test/unit/test_compress_decompress_list.py | 45 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/unit/test_compress_decompress_list.py diff --git a/metaflow/util.py b/metaflow/util.py index 8f310a63236..95b8f724f08 100644 --- a/metaflow/util.py +++ b/metaflow/util.py @@ -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 diff --git a/test/unit/test_compress_decompress_list.py b/test/unit/test_compress_decompress_list.py new file mode 100644 index 00000000000..b14b609fea4 --- /dev/null +++ b/test/unit/test_compress_decompress_list.py @@ -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