From 6c52131fcbfc46f96886b0c8a88792a6ba41b682 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Wed, 9 Aug 2023 14:49:34 +0100 Subject: [PATCH] fix: support lists of strings in `ak.zip` with `optiontype_outside_record=True` (#2623) * fix: remove string special-casing * test: add test for fix * Also test IndexedOptionArray. --------- Co-authored-by: Jim Pivarski --- src/awkward/operations/ak_zip.py | 9 +-- ..._2623_optiontype_outside_record_strings.py | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 tests/test_2623_optiontype_outside_record_strings.py diff --git a/src/awkward/operations/ak_zip.py b/src/awkward/operations/ak_zip.py index c50bcf1819..7d1d8a2698 100644 --- a/src/awkward/operations/ak_zip.py +++ b/src/awkward/operations/ak_zip.py @@ -213,14 +213,7 @@ def _impl( parameters["__record__"] = with_name def action(inputs, depth, **ignore): - if depth_limit == depth or all( - x.purelist_depth == 1 - or ( - x.purelist_depth == 2 - and x.purelist_parameter("__array__") in ("string", "bytestring") - ) - for x in inputs - ): + if depth_limit == depth or all(x.purelist_depth == 1 for x in inputs): # If we want to zip after option types at this depth if optiontype_outside_record and any(x.is_option for x in inputs): return None diff --git a/tests/test_2623_optiontype_outside_record_strings.py b/tests/test_2623_optiontype_outside_record_strings.py new file mode 100644 index 0000000000..15fba96ed7 --- /dev/null +++ b/tests/test_2623_optiontype_outside_record_strings.py @@ -0,0 +1,60 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE + +import awkward as ak + + +def test_ByteMaskedArray(): + record = ak.zip( + { + "x": ak.mask(["foo", "bar", "world"], [True, True, False]), + "y": ak.mask(["do", "re", "mi"], [False, True, True]), + }, + optiontype_outside_record=True, + ) + assert record.to_list() == [None, {"x": "bar", "y": "re"}, None] + assert record.type == ak.types.ArrayType( + ak.types.OptionType( + ak.types.RecordType( + [ + ak.types.ListType( + ak.types.NumpyType("uint8", parameters={"__array__": "char"}), + parameters={"__array__": "string"}, + ), + ak.types.ListType( + ak.types.NumpyType("uint8", parameters={"__array__": "char"}), + parameters={"__array__": "string"}, + ), + ], + ["x", "y"], + ) + ), + 3, + None, + ) + + +def test_IndexedOptionArray(): + record = ak.zip( + {"x": ["foo", "bar", None], "y": [None, "re", "mi"]}, + optiontype_outside_record=True, + ) + assert record.to_list() == [None, {"x": "bar", "y": "re"}, None] + assert record.type == ak.types.ArrayType( + ak.types.OptionType( + ak.types.RecordType( + [ + ak.types.ListType( + ak.types.NumpyType("uint8", parameters={"__array__": "char"}), + parameters={"__array__": "string"}, + ), + ak.types.ListType( + ak.types.NumpyType("uint8", parameters={"__array__": "char"}), + parameters={"__array__": "string"}, + ), + ], + ["x", "y"], + ) + ), + 3, + None, + )