fsspec-data 0.2.2__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.2 → fsspec_data-0.2.3}/Cargo.lock +2 -2
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/Cargo.toml +2 -2
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/PKG-INFO +2 -2
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/__init__.py +1 -1
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/filesystem.py +30 -27
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/fsspec_data.abi3.so +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/interchange.py +52 -15
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/tests/test_all.py +62 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/tests/test_filesystem.py +40 -1
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/pyproject.toml +4 -4
- {fsspec_data-0.2.2 → 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.2 → fsspec_data-0.2.3}/rust/src/codec.rs +219 -7
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/rust/src/error.rs +2 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/rust/src/lib.rs +2 -2
- fsspec_data-0.2.2/rust/coverage +0 -1855
- fsspec_data-0.2.2/rust/python/lib.rs +0 -168
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/.gitignore +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/LICENSE +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/README.md +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/_version.py +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/backends/__init__.py +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/backends/base.py +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/backends/http.py +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/backends/sqlalchemy.py +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/tests/__init__.py +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/fsspec_data/tests/conftest.py +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/rust/.config/nextest.toml +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/rust/src/plan.rs +0 -0
- {fsspec_data-0.2.2 → fsspec_data-0.2.3}/rust/src/stream.rs +0 -0
|
@@ -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",
|
|
@@ -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)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import io
|
|
2
|
+
|
|
1
3
|
import fsspec
|
|
2
4
|
import pyarrow as pa
|
|
3
5
|
import pyarrow.parquet as pq
|
|
4
6
|
import pytest
|
|
5
7
|
|
|
6
|
-
from fsspec_data import DataFileSystem
|
|
8
|
+
from fsspec_data import Codec, DataFileSystem, DecodedBatchStream
|
|
7
9
|
|
|
8
10
|
SCHEMA = pa.schema([pa.field("id", pa.int64(), nullable=False), pa.field("name", pa.string())])
|
|
9
11
|
SCHEMA_OPTIONS = {
|
|
@@ -34,6 +36,43 @@ def test_chained_filesystem_converts_csv_to_seekable_parquet(memory_fs):
|
|
|
34
36
|
assert table.to_pylist() == [{"id": 1, "name": "ada"}, {"id": 2, "name": "grace"}]
|
|
35
37
|
|
|
36
38
|
|
|
39
|
+
def test_chained_filesystem_reads_source_without_cat_file(memory_fs, monkeypatch):
|
|
40
|
+
rows = [f"{index},name-{index}\n".encode() for index in range(50_000)]
|
|
41
|
+
encoded = b"id,name\n" + b"".join(rows)
|
|
42
|
+
bytes_read = 0
|
|
43
|
+
|
|
44
|
+
class CountingReader(io.BytesIO):
|
|
45
|
+
def read(self, size=-1):
|
|
46
|
+
nonlocal bytes_read
|
|
47
|
+
data = super().read(size)
|
|
48
|
+
bytes_read += len(data)
|
|
49
|
+
return data
|
|
50
|
+
|
|
51
|
+
monkeypatch.setattr(memory_fs, "open", lambda *args, **kwargs: CountingReader(encoded))
|
|
52
|
+
monkeypatch.setattr(memory_fs, "cat_file", lambda *args, **kwargs: pytest.fail("cat_file should not be called"))
|
|
53
|
+
fs = DataFileSystem(
|
|
54
|
+
fo="orders.csv",
|
|
55
|
+
fs=memory_fs,
|
|
56
|
+
provided_schema=SCHEMA_OPTIONS,
|
|
57
|
+
batch_size=1,
|
|
58
|
+
row_limit=1,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
assert pq.read_table(fs.open("orders.parquet")).to_pylist() == [{"id": 0, "name": "name-0"}]
|
|
62
|
+
assert bytes_read < len(encoded)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_chained_filesystem_streams_batches_into_spooled_output(memory_fs, monkeypatch):
|
|
66
|
+
monkeypatch.setattr(DecodedBatchStream, "collect", lambda self: pytest.fail("decoded batches should not be collected"))
|
|
67
|
+
monkeypatch.setattr(Codec, "encode_batches", lambda self, *args, **kwargs: pytest.fail("encoded bytes should not be collected"))
|
|
68
|
+
fs = DataFileSystem(fo="orders.csv", fs=memory_fs, provided_schema=SCHEMA_OPTIONS)
|
|
69
|
+
|
|
70
|
+
assert pq.read_table(fs.open("orders.parquet")).to_pylist() == [
|
|
71
|
+
{"id": 1, "name": "ada"},
|
|
72
|
+
{"id": 2, "name": "grace"},
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
|
|
37
76
|
def test_fsspec_url_builds_chained_filesystem(memory_fs):
|
|
38
77
|
fsspec.register_implementation("fsspec-data", DataFileSystem, clobber=True)
|
|
39
78
|
|
|
@@ -13,8 +13,8 @@ authors = [
|
|
|
13
13
|
description = "Arrow interchange planning for the fsspec data ecosystem"
|
|
14
14
|
readme = "README.md"
|
|
15
15
|
license = { text = "Apache-2.0" }
|
|
16
|
-
version = "0.2.
|
|
17
|
-
requires-python = ">=3.
|
|
16
|
+
version = "0.2.3"
|
|
17
|
+
requires-python = ">=3.10"
|
|
18
18
|
keywords = ["arrow", "data", "fsspec", "interchange"]
|
|
19
19
|
|
|
20
20
|
classifiers = [
|
|
@@ -65,7 +65,7 @@ Repository = "https://github.com/1kbgz/fsspec-data"
|
|
|
65
65
|
Homepage = "https://github.com/1kbgz/fsspec-data"
|
|
66
66
|
|
|
67
67
|
[tool.bumpversion]
|
|
68
|
-
current_version = "0.2.
|
|
68
|
+
current_version = "0.2.3"
|
|
69
69
|
commit = true
|
|
70
70
|
tag = false
|
|
71
71
|
commit_args = "-s"
|
|
@@ -91,7 +91,7 @@ search = 'version = "{current_version}"'
|
|
|
91
91
|
replace = 'version = "{new_version}"'
|
|
92
92
|
|
|
93
93
|
[tool.cibuildwheel]
|
|
94
|
-
build = "
|
|
94
|
+
build = "cp310-*"
|
|
95
95
|
test-command = "pytest -vvv {project}/fsspec_data/tests"
|
|
96
96
|
test-extras = "develop"
|
|
97
97
|
|