@@ -54,6 +54,61 @@ def make_table(values=None, **kwargs):
5454 return CTable (Row , new_data = {"name" : list (values ), "x" : list (range (len (values )))}, ** kwargs )
5555
5656
57+ @pytest .mark .parametrize ("large" , [False , True ])
58+ @pytest .mark .parametrize ("null_storage" , ["mask" , "sentinel" ])
59+ def test_utf8_extend_arrow_buffers_and_pending_order (large , null_storage ):
60+ pa = pytest .importorskip ("pyarrow" )
61+ from blosc2 ._utf8_array import UTF8Array
62+
63+ options = {"null_value" : "<NULL>" } if null_storage == "sentinel" else {}
64+ backend = UTF8Array (blosc2 .utf8 (nullable = True , null_storage = null_storage , ** options ))
65+ backend .extend (["pending" ])
66+ values = ["ignored" , "café" , "" , None , "日本語" , "a\0 b" , "ignored" ]
67+ array = pa .array (values , type = pa .large_string () if large else pa .string ()).slice (1 , 5 )
68+ backend .extend_arrow (array )
69+ backend .extend_arrow (pa .chunked_array ([array .slice (0 , 2 ), array .slice (2 )]))
70+ backend .append ("last" )
71+ backend .flush ()
72+ expected = ["pending" ] + [backend ._coerce (value ) for value in values [1 :6 ]] * 2 + ["last" ]
73+ assert backend [:].tolist () == expected
74+ assert len (backend ) == len (expected )
75+ empty = pa .array ([], type = array .type )
76+ backend .extend_arrow (empty )
77+ assert backend [:].tolist () == expected
78+
79+
80+ @pytest .mark .parametrize ("values" , [[], ["" , "" ], [None , None ]])
81+ @pytest .mark .parametrize ("large" , [False , True ])
82+ def test_utf8_extend_arrow_empty_byte_spans (values , large ):
83+ pa = pytest .importorskip ("pyarrow" )
84+ from blosc2 ._utf8_array import UTF8Array
85+
86+ backend = UTF8Array (blosc2 .utf8 (nullable = True , null_storage = "mask" ))
87+ arrow_type = pa .large_string () if large else pa .string ()
88+ array = pa .array (["prefix" , * values , "suffix" ], type = arrow_type ).slice (1 , len (values ))
89+ backend .extend_arrow (array )
90+ backend .extend_arrow (pa .array (["tail" ], type = arrow_type ))
91+ assert backend [:].tolist () == ["" ] * len (values ) + ["tail" ]
92+
93+
94+ def test_utf8_extend_arrow_rejects_wrong_types_and_invalid_utf8 ():
95+ pa = pytest .importorskip ("pyarrow" )
96+ from blosc2 ._utf8_array import UTF8Array
97+
98+ backend = UTF8Array (blosc2 .utf8 ())
99+ for wrong in (["hello" ], pa .array ([1 ]), pa .chunked_array ([], type = pa .int64 ())):
100+ with pytest .raises (TypeError , match = "Arrow string array" ):
101+ backend .extend_arrow (wrong )
102+ with pytest .raises (TypeError , match = "not nullable" ):
103+ backend .extend_arrow (pa .array ([None ], type = pa .string ()))
104+ invalid = pa .Array .from_buffers (
105+ pa .string (), 1 , [None , pa .py_buffer (np .array ([0 , 1 ], dtype = "<i4" )), pa .py_buffer (b"\xff " )]
106+ )
107+ with pytest .raises (pa .ArrowInvalid ):
108+ backend .extend_arrow (invalid )
109+ assert len (backend ) == 0
110+
111+
57112# ---------------------------------------------------------------------------
58113# Schema spec
59114# ---------------------------------------------------------------------------
0 commit comments