@@ -1041,5 +1041,89 @@ class R:
10411041 np .testing .assert_allclose (t ["val" ][:], np .arange (n_live , dtype = np .float64 ) * 7.0 )
10421042
10431043
1044+ # -------------------------------------------------------------------
1045+ # Column.array property
1046+ # -------------------------------------------------------------------
1047+
1048+
1049+ @dataclass
1050+ class ArrayRow :
1051+ value : float = blosc2 .field (blosc2 .float64 ())
1052+ label : str = blosc2 .field (blosc2 .dictionary ())
1053+ name : str = blosc2 .field (blosc2 .string (max_length = 32 ))
1054+ tags : list [str ] = blosc2 .field ( # noqa: RUF009
1055+ blosc2 .list (blosc2 .string (max_length = 16 ))
1056+ )
1057+
1058+
1059+ def test_column_array_ndarray ():
1060+ """array on a numeric column returns the underlying NDArray directly."""
1061+ t = CTable (Row , new_data = DATA20 )
1062+ raw = t .id .array
1063+ assert isinstance (raw , blosc2 .NDArray )
1064+ assert raw is t ._cols ["id" ]
1065+
1066+
1067+ def test_column_array_dictionary ():
1068+ """array on a dictionary column returns the underlying DictionaryColumn."""
1069+ from blosc2 .dictionary_column import DictionaryColumn
1070+
1071+ t = CTable (DictRow , new_data = [("acme" , 1.0 ), ("globex" , 2.0 ), ("acme" , 3.0 )])
1072+ raw = t .vendor .array
1073+ assert isinstance (raw , DictionaryColumn )
1074+ assert raw is t ._cols ["vendor" ]
1075+
1076+
1077+ def test_column_array_varlen_scalar ():
1078+ """array on a varlen-string column returns the underlying _ScalarVarLenArray."""
1079+ from blosc2 .scalar_array import _ScalarVarLenArray
1080+
1081+ @dataclass
1082+ class VLRow :
1083+ note : str = blosc2 .field (blosc2 .vlstring ())
1084+
1085+ t = CTable (VLRow , new_data = [("hello" ,), ("world" ,)])
1086+ raw = t .note .array
1087+ assert isinstance (raw , _ScalarVarLenArray )
1088+ assert raw is t ._cols ["note" ]
1089+
1090+
1091+ def test_column_array_list ():
1092+ """array on a list column returns the underlying ListArray."""
1093+ from blosc2 .list_array import ListArray
1094+
1095+ t = CTable (
1096+ ArrayRow ,
1097+ new_data = [
1098+ (1.0 , "a" , "foo" , ["x" , "y" ]),
1099+ (2.0 , "b" , "bar" , ["z" ]),
1100+ ],
1101+ )
1102+ raw = t .tags .array
1103+ assert isinstance (raw , ListArray )
1104+ assert raw is t ._cols ["tags" ]
1105+
1106+
1107+ def test_column_array_computed_raises ():
1108+ """array raises AttributeError for computed (virtual) columns."""
1109+ t = CTable (Row , new_data = DATA20 )
1110+ t .add_computed_column ("double_score" , lambda cols : cols ["score" ] * 2 )
1111+ with pytest .raises (AttributeError , match = "computed" ):
1112+ _ = t .double_score .array
1113+
1114+
1115+ def test_column_array_bypasses_null_scan ():
1116+ """array returns values that include the raw sentinel, not NaN-substituted values."""
1117+
1118+ @dataclass
1119+ class NullRow :
1120+ x : float = blosc2 .field (blosc2 .float64 (null_value = - 1.0 ))
1121+
1122+ t = CTable (NullRow , new_data = [(1.0 ,), (- 1.0 ,), (3.0 ,)])
1123+ raw = t .x .array [:]
1124+ # The raw array contains the sentinel as-is, not converted to NaN.
1125+ assert raw [1 ] == - 1.0
1126+
1127+
10441128if __name__ == "__main__" :
10451129 pytest .main (["-v" , __file__ ])
0 commit comments