fsspec-data 0.2.0__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/Cargo.lock +61 -50
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/Cargo.toml +2 -2
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/PKG-INFO +2 -2
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/__init__.py +1 -1
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/filesystem.py +30 -27
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/fsspec_data.abi3.so +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/interchange.py +52 -15
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/tests/test_all.py +62 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/tests/test_filesystem.py +40 -1
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/pyproject.toml +4 -4
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/rust/Cargo.toml +1 -1
- fsspec_data-0.2.3/rust/coverage +2229 -0
- fsspec_data-0.2.3/rust/python/lib.rs +327 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/rust/src/codec.rs +386 -51
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/rust/src/error.rs +2 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/rust/src/lib.rs +2 -2
- fsspec_data-0.2.0/rust/coverage +0 -1690
- fsspec_data-0.2.0/rust/python/lib.rs +0 -168
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/.gitignore +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/LICENSE +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/README.md +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/_version.py +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/backends/__init__.py +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/backends/base.py +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/backends/http.py +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/backends/sqlalchemy.py +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/tests/__init__.py +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/fsspec_data/tests/conftest.py +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/rust/.config/nextest.toml +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/rust/src/plan.rs +0 -0
- {fsspec_data-0.2.0 → fsspec_data-0.2.3}/rust/src/stream.rs +0 -0
|
@@ -233,7 +233,7 @@ version = "54.3.1"
|
|
|
233
233
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
234
234
|
checksum = "39cfaf5e440be44db5413b75b72c2a87c1f8f0627117d110264048f2969b99e9"
|
|
235
235
|
dependencies = [
|
|
236
|
-
"bitflags 2.13.
|
|
236
|
+
"bitflags 2.13.1",
|
|
237
237
|
]
|
|
238
238
|
|
|
239
239
|
[[package]]
|
|
@@ -296,9 +296,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|
|
296
296
|
|
|
297
297
|
[[package]]
|
|
298
298
|
name = "bitflags"
|
|
299
|
-
version = "2.13.
|
|
299
|
+
version = "2.13.1"
|
|
300
300
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
301
|
-
checksum = "
|
|
301
|
+
checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
|
|
302
302
|
|
|
303
303
|
[[package]]
|
|
304
304
|
name = "brotli"
|
|
@@ -341,9 +341,9 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
|
|
|
341
341
|
|
|
342
342
|
[[package]]
|
|
343
343
|
name = "cc"
|
|
344
|
-
version = "1.
|
|
344
|
+
version = "1.3.0"
|
|
345
345
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
346
|
-
checksum = "
|
|
346
|
+
checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8"
|
|
347
347
|
dependencies = [
|
|
348
348
|
"find-msvc-tools",
|
|
349
349
|
"jobserver",
|
|
@@ -464,7 +464,7 @@ dependencies = [
|
|
|
464
464
|
|
|
465
465
|
[[package]]
|
|
466
466
|
name = "fsspec_data"
|
|
467
|
-
version = "0.2.
|
|
467
|
+
version = "0.2.3"
|
|
468
468
|
dependencies = [
|
|
469
469
|
"arrow",
|
|
470
470
|
"bytes",
|
|
@@ -474,7 +474,7 @@ dependencies = [
|
|
|
474
474
|
|
|
475
475
|
[[package]]
|
|
476
476
|
name = "fsspec_data_py"
|
|
477
|
-
version = "0.2.
|
|
477
|
+
version = "0.2.3"
|
|
478
478
|
dependencies = [
|
|
479
479
|
"arrow",
|
|
480
480
|
"fsspec_data",
|
|
@@ -483,21 +483,21 @@ dependencies = [
|
|
|
483
483
|
|
|
484
484
|
[[package]]
|
|
485
485
|
name = "futures-core"
|
|
486
|
-
version = "0.3.
|
|
486
|
+
version = "0.3.33"
|
|
487
487
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
488
|
-
checksum = "
|
|
488
|
+
checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
|
|
489
489
|
|
|
490
490
|
[[package]]
|
|
491
491
|
name = "futures-task"
|
|
492
|
-
version = "0.3.
|
|
492
|
+
version = "0.3.33"
|
|
493
493
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
494
|
-
checksum = "
|
|
494
|
+
checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
|
|
495
495
|
|
|
496
496
|
[[package]]
|
|
497
497
|
name = "futures-util"
|
|
498
|
-
version = "0.3.
|
|
498
|
+
version = "0.3.33"
|
|
499
499
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
500
|
-
checksum = "
|
|
500
|
+
checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
|
|
501
501
|
dependencies = [
|
|
502
502
|
"futures-core",
|
|
503
503
|
"futures-task",
|
|
@@ -732,7 +732,7 @@ version = "0.11.6"
|
|
|
732
732
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
733
733
|
checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a"
|
|
734
734
|
dependencies = [
|
|
735
|
-
"twox-hash 2.1.
|
|
735
|
+
"twox-hash 2.1.3",
|
|
736
736
|
]
|
|
737
737
|
|
|
738
738
|
[[package]]
|
|
@@ -901,15 +901,15 @@ checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
|
|
|
901
901
|
|
|
902
902
|
[[package]]
|
|
903
903
|
name = "portable-atomic"
|
|
904
|
-
version = "1.
|
|
904
|
+
version = "1.14.0"
|
|
905
905
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
906
|
-
checksum = "
|
|
906
|
+
checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
|
|
907
907
|
|
|
908
908
|
[[package]]
|
|
909
909
|
name = "proc-macro2"
|
|
910
|
-
version = "1.0.
|
|
910
|
+
version = "1.0.107"
|
|
911
911
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
912
|
-
checksum = "
|
|
912
|
+
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
|
913
913
|
dependencies = [
|
|
914
914
|
"unicode-ident",
|
|
915
915
|
]
|
|
@@ -961,7 +961,7 @@ dependencies = [
|
|
|
961
961
|
"proc-macro2",
|
|
962
962
|
"pyo3-macros-backend",
|
|
963
963
|
"quote",
|
|
964
|
-
"syn",
|
|
964
|
+
"syn 2.0.119",
|
|
965
965
|
]
|
|
966
966
|
|
|
967
967
|
[[package]]
|
|
@@ -974,14 +974,14 @@ dependencies = [
|
|
|
974
974
|
"proc-macro2",
|
|
975
975
|
"pyo3-build-config",
|
|
976
976
|
"quote",
|
|
977
|
-
"syn",
|
|
977
|
+
"syn 2.0.119",
|
|
978
978
|
]
|
|
979
979
|
|
|
980
980
|
[[package]]
|
|
981
981
|
name = "quote"
|
|
982
|
-
version = "1.0.
|
|
982
|
+
version = "1.0.47"
|
|
983
983
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
984
|
-
checksum = "
|
|
984
|
+
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
|
985
985
|
dependencies = [
|
|
986
986
|
"proc-macro2",
|
|
987
987
|
]
|
|
@@ -1000,9 +1000,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
|
|
1000
1000
|
|
|
1001
1001
|
[[package]]
|
|
1002
1002
|
name = "regex"
|
|
1003
|
-
version = "1.13.
|
|
1003
|
+
version = "1.13.1"
|
|
1004
1004
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1005
|
-
checksum = "
|
|
1005
|
+
checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
|
|
1006
1006
|
dependencies = [
|
|
1007
1007
|
"aho-corasick",
|
|
1008
1008
|
"memchr",
|
|
@@ -1012,9 +1012,9 @@ dependencies = [
|
|
|
1012
1012
|
|
|
1013
1013
|
[[package]]
|
|
1014
1014
|
name = "regex-automata"
|
|
1015
|
-
version = "0.4.
|
|
1015
|
+
version = "0.4.16"
|
|
1016
1016
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1017
|
-
checksum = "
|
|
1017
|
+
checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
|
|
1018
1018
|
dependencies = [
|
|
1019
1019
|
"aho-corasick",
|
|
1020
1020
|
"memchr",
|
|
@@ -1062,38 +1062,38 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
|
|
1062
1062
|
|
|
1063
1063
|
[[package]]
|
|
1064
1064
|
name = "serde"
|
|
1065
|
-
version = "1.0.
|
|
1065
|
+
version = "1.0.229"
|
|
1066
1066
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1067
|
-
checksum = "
|
|
1067
|
+
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
|
|
1068
1068
|
dependencies = [
|
|
1069
1069
|
"serde_core",
|
|
1070
1070
|
]
|
|
1071
1071
|
|
|
1072
1072
|
[[package]]
|
|
1073
1073
|
name = "serde_core"
|
|
1074
|
-
version = "1.0.
|
|
1074
|
+
version = "1.0.229"
|
|
1075
1075
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1076
|
-
checksum = "
|
|
1076
|
+
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
|
|
1077
1077
|
dependencies = [
|
|
1078
1078
|
"serde_derive",
|
|
1079
1079
|
]
|
|
1080
1080
|
|
|
1081
1081
|
[[package]]
|
|
1082
1082
|
name = "serde_derive"
|
|
1083
|
-
version = "1.0.
|
|
1083
|
+
version = "1.0.229"
|
|
1084
1084
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1085
|
-
checksum = "
|
|
1085
|
+
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|
1086
1086
|
dependencies = [
|
|
1087
1087
|
"proc-macro2",
|
|
1088
1088
|
"quote",
|
|
1089
|
-
"syn",
|
|
1089
|
+
"syn 3.0.2",
|
|
1090
1090
|
]
|
|
1091
1091
|
|
|
1092
1092
|
[[package]]
|
|
1093
1093
|
name = "serde_json"
|
|
1094
|
-
version = "1.0.
|
|
1094
|
+
version = "1.0.151"
|
|
1095
1095
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1096
|
-
checksum = "
|
|
1096
|
+
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
|
1097
1097
|
dependencies = [
|
|
1098
1098
|
"itoa",
|
|
1099
1099
|
"memchr",
|
|
@@ -1128,9 +1128,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
|
|
1128
1128
|
|
|
1129
1129
|
[[package]]
|
|
1130
1130
|
name = "snap"
|
|
1131
|
-
version = "1.1.
|
|
1131
|
+
version = "1.1.2"
|
|
1132
1132
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1133
|
-
checksum = "
|
|
1133
|
+
checksum = "199905e6153d6405f9728fe44daace35f8f837bbf830bb6e85fbd5828709a886"
|
|
1134
1134
|
|
|
1135
1135
|
[[package]]
|
|
1136
1136
|
name = "static_assertions"
|
|
@@ -1140,9 +1140,20 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
|
|
1140
1140
|
|
|
1141
1141
|
[[package]]
|
|
1142
1142
|
name = "syn"
|
|
1143
|
-
version = "2.0.
|
|
1143
|
+
version = "2.0.119"
|
|
1144
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1145
|
+
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
|
1146
|
+
dependencies = [
|
|
1147
|
+
"proc-macro2",
|
|
1148
|
+
"quote",
|
|
1149
|
+
"unicode-ident",
|
|
1150
|
+
]
|
|
1151
|
+
|
|
1152
|
+
[[package]]
|
|
1153
|
+
name = "syn"
|
|
1154
|
+
version = "3.0.2"
|
|
1144
1155
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1145
|
-
checksum = "
|
|
1156
|
+
checksum = "a207d6d6a2b7fc470b80443726053f18a2481b7e1eee970597051596567987a3"
|
|
1146
1157
|
dependencies = [
|
|
1147
1158
|
"proc-macro2",
|
|
1148
1159
|
"quote",
|
|
@@ -1157,22 +1168,22 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
|
1157
1168
|
|
|
1158
1169
|
[[package]]
|
|
1159
1170
|
name = "thiserror"
|
|
1160
|
-
version = "2.0.
|
|
1171
|
+
version = "2.0.19"
|
|
1161
1172
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1162
|
-
checksum = "
|
|
1173
|
+
checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
|
|
1163
1174
|
dependencies = [
|
|
1164
1175
|
"thiserror-impl",
|
|
1165
1176
|
]
|
|
1166
1177
|
|
|
1167
1178
|
[[package]]
|
|
1168
1179
|
name = "thiserror-impl"
|
|
1169
|
-
version = "2.0.
|
|
1180
|
+
version = "2.0.19"
|
|
1170
1181
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1171
|
-
checksum = "
|
|
1182
|
+
checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
|
|
1172
1183
|
dependencies = [
|
|
1173
1184
|
"proc-macro2",
|
|
1174
1185
|
"quote",
|
|
1175
|
-
"syn",
|
|
1186
|
+
"syn 3.0.2",
|
|
1176
1187
|
]
|
|
1177
1188
|
|
|
1178
1189
|
[[package]]
|
|
@@ -1207,9 +1218,9 @@ dependencies = [
|
|
|
1207
1218
|
|
|
1208
1219
|
[[package]]
|
|
1209
1220
|
name = "twox-hash"
|
|
1210
|
-
version = "2.1.
|
|
1221
|
+
version = "2.1.3"
|
|
1211
1222
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1212
|
-
checksum = "
|
|
1223
|
+
checksum = "8464ec13c3691491391d9fce00f6416c9a48e46972f72d7865688be2080192c9"
|
|
1213
1224
|
|
|
1214
1225
|
[[package]]
|
|
1215
1226
|
name = "unicode-ident"
|
|
@@ -1276,7 +1287,7 @@ dependencies = [
|
|
|
1276
1287
|
"bumpalo",
|
|
1277
1288
|
"proc-macro2",
|
|
1278
1289
|
"quote",
|
|
1279
|
-
"syn",
|
|
1290
|
+
"syn 2.0.119",
|
|
1280
1291
|
"wasm-bindgen-shared",
|
|
1281
1292
|
]
|
|
1282
1293
|
|
|
@@ -1310,7 +1321,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
|
|
1310
1321
|
dependencies = [
|
|
1311
1322
|
"proc-macro2",
|
|
1312
1323
|
"quote",
|
|
1313
|
-
"syn",
|
|
1324
|
+
"syn 2.0.119",
|
|
1314
1325
|
]
|
|
1315
1326
|
|
|
1316
1327
|
[[package]]
|
|
@@ -1321,7 +1332,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
|
|
1321
1332
|
dependencies = [
|
|
1322
1333
|
"proc-macro2",
|
|
1323
1334
|
"quote",
|
|
1324
|
-
"syn",
|
|
1335
|
+
"syn 2.0.119",
|
|
1325
1336
|
]
|
|
1326
1337
|
|
|
1327
1338
|
[[package]]
|
|
@@ -1371,7 +1382,7 @@ checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5"
|
|
|
1371
1382
|
dependencies = [
|
|
1372
1383
|
"proc-macro2",
|
|
1373
1384
|
"quote",
|
|
1374
|
-
"syn",
|
|
1385
|
+
"syn 2.0.119",
|
|
1375
1386
|
]
|
|
1376
1387
|
|
|
1377
1388
|
[[package]]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "fsspec_data_py"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
publish = false
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ crate-type = ["cdylib"]
|
|
|
12
12
|
[dependencies]
|
|
13
13
|
fsspec_data = { path = "./rust", version = "*" }
|
|
14
14
|
arrow = { version = "54.3.1", features = ["pyarrow"] }
|
|
15
|
-
pyo3 = { version = "0.23", features = ["abi3-
|
|
15
|
+
pyo3 = { version = "0.23", features = ["abi3-py310", "extension-module"] }
|
|
16
16
|
|
|
17
17
|
[profile.release]
|
|
18
18
|
panic = "abort"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fsspec-data
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Arrow interchange planning for the fsspec data ecosystem
|
|
5
5
|
Project-URL: Repository, https://github.com/1kbgz/fsspec-data
|
|
6
6
|
Project-URL: Homepage, https://github.com/1kbgz/fsspec-data
|
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
18
18
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
19
19
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
20
20
|
Classifier: Programming Language :: Rust
|
|
21
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
22
|
Requires-Dist: fsspec
|
|
23
23
|
Requires-Dist: pyarrow
|
|
24
24
|
Provides-Extra: develop
|
|
@@ -70,11 +70,14 @@ class DataFileSystem(ChainedFileSystem):
|
|
|
70
70
|
raise ValueError("fsspec-data is a read-only filesystem")
|
|
71
71
|
|
|
72
72
|
path = self._strip_protocol(path)
|
|
73
|
-
output = self._convert(path)
|
|
74
73
|
file = tempfile.SpooledTemporaryFile(max_size=self.spool_max_size, mode="w+b")
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
try:
|
|
75
|
+
self._convert(path, file)
|
|
76
|
+
self._sizes[path] = file.tell()
|
|
77
|
+
file.seek(0)
|
|
78
|
+
except Exception:
|
|
79
|
+
file.close()
|
|
80
|
+
raise
|
|
78
81
|
return file
|
|
79
82
|
|
|
80
83
|
def info(self, path: str, **kwargs: Any) -> dict[str, Any]:
|
|
@@ -94,31 +97,31 @@ class DataFileSystem(ChainedFileSystem):
|
|
|
94
97
|
entry = self.info(path, **kwargs)
|
|
95
98
|
return [entry] if detail else [entry["name"]]
|
|
96
99
|
|
|
97
|
-
def _convert(self, path: str) ->
|
|
100
|
+
def _convert(self, path: str, output) -> None:
|
|
98
101
|
provided_format = self.provided_format or _format_from_path(self.fo)
|
|
99
102
|
requested_format = self.requested_format or _format_from_path(path)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
103
|
+
with self.fs.open(self.fo, "rb") as source:
|
|
104
|
+
decoded = DEFAULT_REGISTRY.get(provided_format).iter_batches(
|
|
105
|
+
source,
|
|
106
|
+
schema=self.provided_schema,
|
|
107
|
+
batch_size=self.batch_size,
|
|
108
|
+
row_limit=self.row_limit,
|
|
109
|
+
byte_limit=self.byte_limit,
|
|
110
|
+
)
|
|
111
|
+
if self.provided_schema is not None and not decoded.schema.equals(self.provided_schema, check_metadata=False):
|
|
112
|
+
raise ValueError("provided schema does not match the source schema")
|
|
113
|
+
|
|
114
|
+
provided_schema = self.provided_schema or decoded.schema
|
|
115
|
+
requested_schema = self.requested_schema or provided_schema
|
|
116
|
+
plan = InterchangeRequest(
|
|
117
|
+
provided_format,
|
|
118
|
+
requested_format,
|
|
119
|
+
provided_schema,
|
|
120
|
+
requested_schema,
|
|
121
|
+
self.schema_policy,
|
|
122
|
+
).plan()
|
|
123
|
+
batches = (plan.apply_batch(batch) for batch in decoded)
|
|
124
|
+
DEFAULT_REGISTRY.get(requested_format).encode_batches_to(batches, output, schema=requested_schema)
|
|
122
125
|
|
|
123
126
|
|
|
124
127
|
_SUFFIX_FORMATS = {
|
|
Binary file
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable
|
|
3
4
|
from dataclasses import dataclass, replace
|
|
4
5
|
from enum import Enum
|
|
5
6
|
from importlib import import_module
|
|
6
|
-
from
|
|
7
|
+
from itertools import chain
|
|
8
|
+
from typing import Any, BinaryIO
|
|
7
9
|
|
|
8
10
|
import pyarrow as pa
|
|
9
11
|
import pyarrow.compute as pc
|
|
@@ -94,9 +96,34 @@ class Codec:
|
|
|
94
96
|
raise TypeError("batches must contain pyarrow.RecordBatch objects")
|
|
95
97
|
return _rust.encode_batches(self.format.value, schema, batches)
|
|
96
98
|
|
|
99
|
+
def encode_batches_to(
|
|
100
|
+
self,
|
|
101
|
+
batches: Iterable[pa.RecordBatch],
|
|
102
|
+
output: BinaryIO,
|
|
103
|
+
*,
|
|
104
|
+
schema: pa.Schema | None = None,
|
|
105
|
+
) -> None:
|
|
106
|
+
batches = iter(batches)
|
|
107
|
+
if schema is None:
|
|
108
|
+
try:
|
|
109
|
+
first = next(batches)
|
|
110
|
+
except StopIteration as error:
|
|
111
|
+
raise ValueError("schema is required when encoding no record batches") from error
|
|
112
|
+
if not isinstance(first, pa.RecordBatch):
|
|
113
|
+
raise TypeError("batches must contain pyarrow.RecordBatch objects")
|
|
114
|
+
schema = first.schema
|
|
115
|
+
batches = chain((first,), batches)
|
|
116
|
+
schema = _ensure_pyarrow(schema)
|
|
117
|
+
writer = _rust.start_codec_writer(self.format.value, schema, output)
|
|
118
|
+
for batch in batches:
|
|
119
|
+
if not isinstance(batch, pa.RecordBatch):
|
|
120
|
+
raise TypeError("batches must contain pyarrow.RecordBatch objects")
|
|
121
|
+
writer.write_batch(batch)
|
|
122
|
+
writer.finish()
|
|
123
|
+
|
|
97
124
|
def decode_batches(
|
|
98
125
|
self,
|
|
99
|
-
data: bytes | bytearray | memoryview,
|
|
126
|
+
data: bytes | bytearray | memoryview | BinaryIO,
|
|
100
127
|
*,
|
|
101
128
|
schema: pa.Schema | None = None,
|
|
102
129
|
batch_size: int = 1024,
|
|
@@ -113,25 +140,35 @@ class Codec:
|
|
|
113
140
|
|
|
114
141
|
def iter_batches(
|
|
115
142
|
self,
|
|
116
|
-
data: bytes | bytearray | memoryview,
|
|
143
|
+
data: bytes | bytearray | memoryview | BinaryIO,
|
|
117
144
|
*,
|
|
118
145
|
schema: pa.Schema | None = None,
|
|
119
146
|
batch_size: int = 1024,
|
|
120
147
|
row_limit: int | None = None,
|
|
121
148
|
byte_limit: int | None = None,
|
|
122
149
|
) -> DecodedBatchStream:
|
|
123
|
-
if not isinstance(data, (bytes, bytearray, memoryview)):
|
|
124
|
-
raise TypeError("data must be bytes-like")
|
|
125
150
|
if schema is not None:
|
|
126
151
|
schema = _ensure_pyarrow(schema)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
152
|
+
if isinstance(data, (bytes, bytearray, memoryview)):
|
|
153
|
+
decoded_schema, native = _rust.decode_stream(
|
|
154
|
+
self.format.value,
|
|
155
|
+
bytes(data),
|
|
156
|
+
schema,
|
|
157
|
+
batch_size,
|
|
158
|
+
row_limit,
|
|
159
|
+
byte_limit,
|
|
160
|
+
)
|
|
161
|
+
elif hasattr(data, "read"):
|
|
162
|
+
decoded_schema, native = _rust.decode_reader(
|
|
163
|
+
self.format.value,
|
|
164
|
+
data,
|
|
165
|
+
schema,
|
|
166
|
+
batch_size,
|
|
167
|
+
row_limit,
|
|
168
|
+
byte_limit,
|
|
169
|
+
)
|
|
170
|
+
else:
|
|
171
|
+
raise TypeError("data must be bytes-like or a binary file-like object")
|
|
135
172
|
return DecodedBatchStream(decoded_schema, native)
|
|
136
173
|
|
|
137
174
|
|
|
@@ -204,7 +241,7 @@ class InterchangePlan:
|
|
|
204
241
|
|
|
205
242
|
def iter_batches(
|
|
206
243
|
self,
|
|
207
|
-
data: bytes | bytearray | memoryview,
|
|
244
|
+
data: bytes | bytearray | memoryview | BinaryIO,
|
|
208
245
|
*,
|
|
209
246
|
batch_size: int = 1024,
|
|
210
247
|
row_limit: int | None = None,
|
|
@@ -222,7 +259,7 @@ class InterchangePlan:
|
|
|
222
259
|
|
|
223
260
|
def convert(
|
|
224
261
|
self,
|
|
225
|
-
data: bytes | bytearray | memoryview,
|
|
262
|
+
data: bytes | bytearray | memoryview | BinaryIO,
|
|
226
263
|
*,
|
|
227
264
|
batch_size: int = 1024,
|
|
228
265
|
row_limit: int | None = None,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import io
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
1
4
|
import pyarrow as pa
|
|
2
5
|
import pyarrow.parquet as pq
|
|
3
6
|
import pytest
|
|
@@ -280,6 +283,43 @@ def test_text_codec_round_trip_preserves_schema_and_rows(format, prefix):
|
|
|
280
283
|
assert pa.Table.from_batches(decoded.batches).to_pylist() == pa.Table.from_batches(batches).to_pylist()
|
|
281
284
|
|
|
282
285
|
|
|
286
|
+
@pytest.mark.parametrize("format", list(DataFormat))
|
|
287
|
+
def test_codec_encodes_batches_to_binary_file(format):
|
|
288
|
+
provided, _ = schemas()
|
|
289
|
+
batches = (
|
|
290
|
+
pa.RecordBatch.from_arrays([pa.array([1, 2]), pa.array(["ada", None])], schema=provided),
|
|
291
|
+
pa.RecordBatch.from_arrays([pa.array([3]), pa.array(["margaret"])], schema=provided),
|
|
292
|
+
)
|
|
293
|
+
codec = DEFAULT_REGISTRY.get(format)
|
|
294
|
+
output = io.BytesIO()
|
|
295
|
+
|
|
296
|
+
codec.encode_batches_to(iter(batches), output)
|
|
297
|
+
|
|
298
|
+
decode_schema = provided if format in {DataFormat.CSV, DataFormat.JSONL} else None
|
|
299
|
+
decoded = codec.decode_batches(output.getvalue(), schema=decode_schema)
|
|
300
|
+
assert pa.Table.from_batches(decoded.batches).to_pylist() == pa.Table.from_batches(batches).to_pylist()
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def test_codec_file_writer_requires_schema_for_empty_stream():
|
|
304
|
+
codec = DEFAULT_REGISTRY.get(DataFormat.ARROW)
|
|
305
|
+
|
|
306
|
+
with pytest.raises(ValueError, match="schema is required"):
|
|
307
|
+
codec.encode_batches_to((), io.BytesIO())
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def test_codec_file_writer_rejects_non_batches():
|
|
311
|
+
provided, _ = schemas()
|
|
312
|
+
codec = DEFAULT_REGISTRY.get(DataFormat.ARROW)
|
|
313
|
+
invalid: Any = object()
|
|
314
|
+
|
|
315
|
+
with pytest.raises(TypeError, match="pyarrow.RecordBatch"):
|
|
316
|
+
codec.encode_batches_to(iter([invalid]), io.BytesIO())
|
|
317
|
+
|
|
318
|
+
batch = pa.record_batch([[1], ["ada"]], schema=provided)
|
|
319
|
+
with pytest.raises(TypeError, match="pyarrow.RecordBatch"):
|
|
320
|
+
codec.encode_batches_to(iter([batch, invalid]), io.BytesIO(), schema=provided)
|
|
321
|
+
|
|
322
|
+
|
|
283
323
|
@pytest.mark.parametrize("format", [DataFormat.CSV, DataFormat.JSONL])
|
|
284
324
|
def test_text_codec_decode_requires_schema(format):
|
|
285
325
|
codec = DEFAULT_REGISTRY.get(format)
|
|
@@ -302,6 +342,28 @@ def test_lazy_decode_applies_batch_and_row_limits():
|
|
|
302
342
|
assert pa.Table.from_batches(batches).column("id").to_pylist() == [1, 2, 3, 4]
|
|
303
343
|
|
|
304
344
|
|
|
345
|
+
def test_lazy_decode_reads_binary_file_without_eagerly_consuming_it():
|
|
346
|
+
class CountingReader(io.BytesIO):
|
|
347
|
+
def __init__(self, data):
|
|
348
|
+
super().__init__(data)
|
|
349
|
+
self.bytes_read = 0
|
|
350
|
+
|
|
351
|
+
def read(self, size=-1):
|
|
352
|
+
data = super().read(size)
|
|
353
|
+
self.bytes_read += len(data)
|
|
354
|
+
return data
|
|
355
|
+
|
|
356
|
+
schema = pa.schema([("id", pa.int64())])
|
|
357
|
+
batch = pa.record_batch([pa.array(range(1024))], schema=schema)
|
|
358
|
+
codec = DEFAULT_REGISTRY.get(DataFormat.ARROW)
|
|
359
|
+
encoded = codec.encode_batches((batch,) * 128)
|
|
360
|
+
source = CountingReader(encoded)
|
|
361
|
+
stream = codec.iter_batches(source)
|
|
362
|
+
|
|
363
|
+
assert next(stream).num_rows == 1024
|
|
364
|
+
assert source.bytes_read < len(encoded)
|
|
365
|
+
|
|
366
|
+
|
|
305
367
|
def test_lazy_decode_observes_cancellation():
|
|
306
368
|
schema = pa.schema([("id", pa.int64())])
|
|
307
369
|
codec = DEFAULT_REGISTRY.get(DataFormat.ARROW)
|