@@ -401,12 +401,14 @@ def dictionary_ordered(self) -> Union[bool, None]:
401
401
return self ._c_schema_view .dictionary_ordered
402
402
403
403
@property
404
- def value_type (self ):
405
- """Dictionary or list value type
404
+ def value_type (self ) -> Union [ "Schema" , None ] :
405
+ """Dictionary, map, or list value type
406
406
407
407
>>> import nanoarrow as na
408
408
>>> na.list_(na.int32()).value_type
409
409
<Schema> 'item': int32
410
+ >>> na.map_(na.int32(), na.string()).value_type
411
+ <Schema> 'value': string
410
412
>>> na.dictionary(na.int32(), na.string()).value_type
411
413
<Schema> string
412
414
"""
@@ -416,11 +418,33 @@ def value_type(self):
416
418
_types .FIXED_SIZE_LIST ,
417
419
):
418
420
return self .field (0 )
421
+ elif self ._c_schema_view .type_id == _types .MAP :
422
+ return Schema (self ._c_schema .child (0 ).child (1 ))
419
423
elif self ._c_schema_view .type_id == _types .DICTIONARY :
420
424
return Schema (self ._c_schema .dictionary )
421
425
else :
422
426
return None
423
427
428
+ @property
429
+ def key_type (self ) -> Union ["Schema" , None ]:
430
+ """Map key type
431
+
432
+ >>> import nanoarrow as na
433
+ >>> na.map_(na.int32(), na.string()).key_type
434
+ <Schema> 'key': non-nullable int32
435
+ """
436
+ if self ._c_schema_view .type_id == _types .MAP :
437
+ return Schema (self ._c_schema .child (0 ).child (0 ))
438
+ else :
439
+ return None
440
+
441
+ @property
442
+ def keys_sorted (self ) -> Union [bool , None ]:
443
+ if self ._c_schema_view .type_id == _types .MAP :
444
+ return self ._c_schema_view .map_keys_sorted
445
+ else :
446
+ return None
447
+
424
448
@property
425
449
def list_size (self ) -> Union [int , None ]:
426
450
"""Fixed-size list element size
@@ -979,7 +1003,7 @@ def timestamp(
979
1003
return Schema (Type .TIMESTAMP , timezone = timezone , unit = unit , nullable = nullable )
980
1004
981
1005
982
- def duration (unit , nullable : bool = True ):
1006
+ def duration (unit , nullable : bool = True ) -> Schema :
983
1007
"""Create an instance of a duration type.
984
1008
985
1009
Parameters
@@ -999,7 +1023,7 @@ def duration(unit, nullable: bool = True):
999
1023
return Schema (Type .DURATION , unit = unit , nullable = nullable )
1000
1024
1001
1025
1002
- def interval_months (nullable : bool = True ):
1026
+ def interval_months (nullable : bool = True ) -> Schema :
1003
1027
"""Create an instance of an interval type measured in months.
1004
1028
1005
1029
Parameters
@@ -1017,7 +1041,7 @@ def interval_months(nullable: bool = True):
1017
1041
return Schema (Type .INTERVAL_MONTHS , nullable = nullable )
1018
1042
1019
1043
1020
- def interval_day_time (nullable : bool = True ):
1044
+ def interval_day_time (nullable : bool = True ) -> Schema :
1021
1045
"""Create an instance of an interval type measured as a day/time pair.
1022
1046
1023
1047
Parameters
@@ -1035,7 +1059,7 @@ def interval_day_time(nullable: bool = True):
1035
1059
return Schema (Type .INTERVAL_DAY_TIME , nullable = nullable )
1036
1060
1037
1061
1038
- def interval_month_day_nano (nullable : bool = True ):
1062
+ def interval_month_day_nano (nullable : bool = True ) -> Schema :
1039
1063
"""Create an instance of an interval type measured as a month/day/nanosecond
1040
1064
tuple.
1041
1065
@@ -1100,7 +1124,7 @@ def decimal256(precision: int, scale: int, nullable: bool = True) -> Schema:
1100
1124
return Schema (Type .DECIMAL256 , precision = precision , scale = scale , nullable = nullable )
1101
1125
1102
1126
1103
- def struct (fields , nullable = True ) -> Schema :
1127
+ def struct (fields , nullable : bool = True ) -> Schema :
1104
1128
"""Create a type representing a named sequence of fields.
1105
1129
1106
1130
Parameters
@@ -1124,7 +1148,7 @@ def struct(fields, nullable=True) -> Schema:
1124
1148
return Schema (Type .STRUCT , fields = fields , nullable = nullable )
1125
1149
1126
1150
1127
- def list_ (value_type , nullable = True ) -> Schema :
1151
+ def list_ (value_type , nullable : bool = True ) -> Schema :
1128
1152
"""Create a type representing a variable-size list of some other type.
1129
1153
1130
1154
Parameters
@@ -1144,7 +1168,7 @@ def list_(value_type, nullable=True) -> Schema:
1144
1168
return Schema (Type .LIST , value_type = value_type , nullable = nullable )
1145
1169
1146
1170
1147
- def large_list (value_type , nullable = True ) -> Schema :
1171
+ def large_list (value_type , nullable : bool = True ) -> Schema :
1148
1172
"""Create a type representing a variable-size list of some other type.
1149
1173
1150
1174
Unlike :func:`list_`, the func:`large_list` can accomodate arrays
@@ -1167,7 +1191,7 @@ def large_list(value_type, nullable=True) -> Schema:
1167
1191
return Schema (Type .LARGE_LIST , value_type = value_type , nullable = nullable )
1168
1192
1169
1193
1170
- def fixed_size_list (value_type , list_size , nullable = True ) -> Schema :
1194
+ def fixed_size_list (value_type , list_size : int , nullable : bool = True ) -> Schema :
1171
1195
"""Create a type representing a fixed-size list of some other type.
1172
1196
1173
1197
Parameters
@@ -1194,7 +1218,40 @@ def fixed_size_list(value_type, list_size, nullable=True) -> Schema:
1194
1218
)
1195
1219
1196
1220
1197
- def dictionary (index_type , value_type , dictionary_ordered = False ):
1221
+ def map_ (key_type , value_type , keys_sorted : bool = False , nullable : bool = True ):
1222
+ """Create a type representing a list of key/value mappings
1223
+
1224
+ Note that each element in the list contains potentially many
1225
+ key/value pairs (and that a map array contains potentially
1226
+ many individual mappings).
1227
+
1228
+ Parameters
1229
+ ----------
1230
+ value_type : schema-like
1231
+ The type of keys in each map element.
1232
+ value_type : schema-like
1233
+ The type of values in each map element
1234
+ keys_sorted : bool, optional
1235
+ True if keys within each map element are sorted.
1236
+ nullable : bool, optional
1237
+ Use ``False`` to mark this field as non-nullable.
1238
+
1239
+ Examples
1240
+ --------
1241
+ >>> import nanoarrow as na
1242
+ >>> na.map_(na.int32(), na.string())
1243
+ <Schema> map<entries: struct<key: int32, value: string>>
1244
+ """
1245
+ return Schema (
1246
+ Type .MAP ,
1247
+ key_type = key_type ,
1248
+ value_type = value_type ,
1249
+ keys_sorted = keys_sorted ,
1250
+ nullable = nullable ,
1251
+ )
1252
+
1253
+
1254
+ def dictionary (index_type , value_type , dictionary_ordered : bool = False ) -> Schema :
1198
1255
"""Create a type representing dictionary-encoded values
1199
1256
1200
1257
Parameters
@@ -1290,6 +1347,25 @@ def _c_schema_from_type_and_params(type: Type, params: dict):
1290
1347
factory .allocate_children (1 )
1291
1348
factory .set_child (0 , "item" , c_schema (params .pop ("value_type" )))
1292
1349
1350
+ elif type == Type .MAP :
1351
+ key_schema = c_schema (params .pop ("key_type" ))
1352
+ value_schema = c_schema (params .pop ("value_type" ))
1353
+
1354
+ entries = CSchemaBuilder .allocate ()
1355
+ entries .set_format ("+s" )
1356
+ entries .set_nullable (False )
1357
+ entries .allocate_children (2 )
1358
+ entries .set_child (0 , "key" , key_schema .modify (nullable = False ))
1359
+ entries .set_child (1 , "value" , value_schema )
1360
+
1361
+ factory .set_format ("+m" )
1362
+ factory .allocate_children (1 )
1363
+ factory .set_child (0 , "entries" , entries .finish ())
1364
+ factory .set_nullable (False )
1365
+
1366
+ if "keys_sorted" in params :
1367
+ factory .set_map_keys_sorted (params .pop ("keys_sorted" ))
1368
+
1293
1369
elif type == Type .DICTIONARY :
1294
1370
index_type = c_schema (params .pop ("index_type" ))
1295
1371
factory .set_format (index_type .format )
0 commit comments