fsspec 2024.5.0__py3-none-any.whl → 2024.6.1__py3-none-any.whl
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/_version.py +2 -2
- fsspec/caching.py +3 -2
- fsspec/compression.py +1 -1
- fsspec/generic.py +3 -0
- fsspec/implementations/cached.py +6 -16
- fsspec/implementations/dirfs.py +2 -0
- fsspec/implementations/github.py +12 -0
- fsspec/implementations/http.py +2 -1
- fsspec/implementations/reference.py +9 -0
- fsspec/implementations/smb.py +10 -0
- fsspec/json.py +121 -0
- fsspec/registry.py +24 -18
- fsspec/spec.py +119 -33
- fsspec/utils.py +1 -1
- {fsspec-2024.5.0.dist-info → fsspec-2024.6.1.dist-info}/METADATA +10 -5
- fsspec-2024.6.1.dist-info/RECORD +55 -0
- {fsspec-2024.5.0.dist-info → fsspec-2024.6.1.dist-info}/WHEEL +1 -1
- fsspec/implementations/tests/__init__.py +0 -0
- fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_file_listing.yaml +0 -112
- fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_mkdir.yaml +0 -582
- fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_pyarrow_non_partitioned.yaml +0 -873
- fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_range.yaml +0 -458
- fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_range_chunked.yaml +0 -1355
- fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_write_and_read.yaml +0 -795
- fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_write_pyarrow_non_partitioned.yaml +0 -613
- fsspec/implementations/tests/conftest.py +0 -39
- fsspec/implementations/tests/local/__init__.py +0 -0
- fsspec/implementations/tests/local/local_fixtures.py +0 -18
- fsspec/implementations/tests/local/local_test.py +0 -14
- fsspec/implementations/tests/memory/__init__.py +0 -0
- fsspec/implementations/tests/memory/memory_fixtures.py +0 -27
- fsspec/implementations/tests/memory/memory_test.py +0 -14
- fsspec/implementations/tests/out.zip +0 -0
- fsspec/implementations/tests/test_archive.py +0 -382
- fsspec/implementations/tests/test_arrow.py +0 -259
- fsspec/implementations/tests/test_cached.py +0 -1306
- fsspec/implementations/tests/test_common.py +0 -35
- fsspec/implementations/tests/test_dask.py +0 -29
- fsspec/implementations/tests/test_data.py +0 -20
- fsspec/implementations/tests/test_dbfs.py +0 -268
- fsspec/implementations/tests/test_dirfs.py +0 -588
- fsspec/implementations/tests/test_ftp.py +0 -178
- fsspec/implementations/tests/test_git.py +0 -76
- fsspec/implementations/tests/test_http.py +0 -577
- fsspec/implementations/tests/test_jupyter.py +0 -57
- fsspec/implementations/tests/test_libarchive.py +0 -33
- fsspec/implementations/tests/test_local.py +0 -1285
- fsspec/implementations/tests/test_memory.py +0 -382
- fsspec/implementations/tests/test_reference.py +0 -720
- fsspec/implementations/tests/test_sftp.py +0 -233
- fsspec/implementations/tests/test_smb.py +0 -139
- fsspec/implementations/tests/test_tar.py +0 -243
- fsspec/implementations/tests/test_webhdfs.py +0 -197
- fsspec/implementations/tests/test_zip.py +0 -134
- fsspec/tests/__init__.py +0 -0
- fsspec/tests/conftest.py +0 -188
- fsspec/tests/data/listing.html +0 -1
- fsspec/tests/test_api.py +0 -498
- fsspec/tests/test_async.py +0 -230
- fsspec/tests/test_caches.py +0 -255
- fsspec/tests/test_callbacks.py +0 -89
- fsspec/tests/test_compression.py +0 -164
- fsspec/tests/test_config.py +0 -129
- fsspec/tests/test_core.py +0 -466
- fsspec/tests/test_downstream.py +0 -40
- fsspec/tests/test_file.py +0 -200
- fsspec/tests/test_fuse.py +0 -147
- fsspec/tests/test_generic.py +0 -90
- fsspec/tests/test_gui.py +0 -23
- fsspec/tests/test_mapping.py +0 -228
- fsspec/tests/test_parquet.py +0 -140
- fsspec/tests/test_registry.py +0 -134
- fsspec/tests/test_spec.py +0 -1167
- fsspec/tests/test_utils.py +0 -478
- fsspec-2024.5.0.dist-info/RECORD +0 -111
- {fsspec-2024.5.0.dist-info → fsspec-2024.6.1.dist-info}/licenses/LICENSE +0 -0
fsspec/tests/test_core.py
DELETED
|
@@ -1,466 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import pickle
|
|
3
|
-
import tempfile
|
|
4
|
-
import zipfile
|
|
5
|
-
from contextlib import contextmanager
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
|
|
8
|
-
import pytest
|
|
9
|
-
|
|
10
|
-
import fsspec
|
|
11
|
-
from fsspec.core import (
|
|
12
|
-
OpenFile,
|
|
13
|
-
OpenFiles,
|
|
14
|
-
_expand_paths,
|
|
15
|
-
expand_paths_if_needed,
|
|
16
|
-
get_compression,
|
|
17
|
-
get_fs_token_paths,
|
|
18
|
-
open_files,
|
|
19
|
-
open_local,
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@contextmanager
|
|
24
|
-
def tempzip(data={}):
|
|
25
|
-
f = tempfile.mkstemp(suffix="zip")[1]
|
|
26
|
-
with zipfile.ZipFile(f, mode="w") as z:
|
|
27
|
-
for k, v in data.items():
|
|
28
|
-
z.writestr(k, v)
|
|
29
|
-
try:
|
|
30
|
-
yield f
|
|
31
|
-
finally:
|
|
32
|
-
try:
|
|
33
|
-
os.remove(f)
|
|
34
|
-
except OSError:
|
|
35
|
-
pass
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@pytest.mark.parametrize(
|
|
39
|
-
"path, name_function, num, out",
|
|
40
|
-
[
|
|
41
|
-
[["apath"], None, 1, ["apath"]],
|
|
42
|
-
["apath.*.csv", None, 1, ["apath.0.csv"]],
|
|
43
|
-
["apath.*.csv", None, 2, ["apath.0.csv", "apath.1.csv"]],
|
|
44
|
-
["a*", lambda x: "abc"[x], 2, ["aa", "ab"]],
|
|
45
|
-
],
|
|
46
|
-
)
|
|
47
|
-
def test_expand_paths(path, name_function, num, out):
|
|
48
|
-
assert _expand_paths(path, name_function, num) == out
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@pytest.mark.parametrize(
|
|
52
|
-
"create_files, path, out",
|
|
53
|
-
[
|
|
54
|
-
[["apath"], "apath", ["apath"]],
|
|
55
|
-
[["apath1"], "apath*", ["apath1"]],
|
|
56
|
-
[["apath1", "apath2"], "apath*", ["apath1", "apath2"]],
|
|
57
|
-
[["apath1", "apath2"], "apath[1]", ["apath1"]],
|
|
58
|
-
[["apath1", "apath11"], "apath?", ["apath1"]],
|
|
59
|
-
],
|
|
60
|
-
)
|
|
61
|
-
def test_expand_paths_if_needed_in_read_mode(create_files, path, out):
|
|
62
|
-
d = str(tempfile.mkdtemp())
|
|
63
|
-
for f in create_files:
|
|
64
|
-
f = os.path.join(d, f)
|
|
65
|
-
open(f, "w").write("test")
|
|
66
|
-
|
|
67
|
-
path = os.path.join(d, path)
|
|
68
|
-
|
|
69
|
-
fs = fsspec.filesystem("file")
|
|
70
|
-
res = expand_paths_if_needed([path], "r", 0, fs, None)
|
|
71
|
-
assert [os.path.basename(p) for p in res] == out
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def test_expand_error():
|
|
75
|
-
with pytest.raises(ValueError):
|
|
76
|
-
_expand_paths("*.*", None, 1)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@pytest.mark.parametrize("mode", ["w", "w+", "x", "x+"])
|
|
80
|
-
def test_expand_fs_token_paths(mode):
|
|
81
|
-
assert len(get_fs_token_paths("path", mode, num=2, expand=True)[-1]) == 2
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def test_openfile_api(m):
|
|
85
|
-
m.open("somepath", "wb").write(b"data")
|
|
86
|
-
of = OpenFile(m, "somepath")
|
|
87
|
-
assert str(of) == "<OpenFile 'somepath'>"
|
|
88
|
-
f = of.open()
|
|
89
|
-
assert f.read() == b"data"
|
|
90
|
-
f.close()
|
|
91
|
-
with OpenFile(m, "somepath", mode="rt") as f:
|
|
92
|
-
assert f.read() == "data"
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def test_openfile_open(m):
|
|
96
|
-
of = OpenFile(m, "somepath", mode="wt")
|
|
97
|
-
f = of.open()
|
|
98
|
-
f.write("hello")
|
|
99
|
-
assert m.size("somepath") == 0 # no flush yet
|
|
100
|
-
of.close()
|
|
101
|
-
assert m.size("somepath") == 5
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def test_open_local_w_cache():
|
|
105
|
-
d1 = str(tempfile.mkdtemp())
|
|
106
|
-
f1 = os.path.join(d1, "f1")
|
|
107
|
-
open(f1, "w").write("test1")
|
|
108
|
-
d2 = str(tempfile.mkdtemp())
|
|
109
|
-
fn = open_local(f"simplecache://{f1}", cache_storage=d2, target_protocol="file")
|
|
110
|
-
assert isinstance(fn, str)
|
|
111
|
-
assert open(fn).read() == "test1"
|
|
112
|
-
assert d2 in fn
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def test_open_local_w_magic():
|
|
116
|
-
d1 = str(tempfile.mkdtemp())
|
|
117
|
-
f1 = os.path.join(d1, "f1")
|
|
118
|
-
open(f1, "w").write("test1")
|
|
119
|
-
fn = open_local(os.path.join(d1, "f*"))
|
|
120
|
-
assert len(fn) == 1
|
|
121
|
-
assert isinstance(fn, list)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def test_open_local_w_list_of_str():
|
|
125
|
-
d1 = str(tempfile.mkdtemp())
|
|
126
|
-
f1 = os.path.join(d1, "f1")
|
|
127
|
-
open(f1, "w").write("test1")
|
|
128
|
-
fn = open_local([f1, f1])
|
|
129
|
-
assert len(fn) == 2
|
|
130
|
-
assert isinstance(fn, list)
|
|
131
|
-
assert all(isinstance(elem, str) for elem in fn)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
def test_open_local_w_path():
|
|
135
|
-
d1 = str(tempfile.mkdtemp())
|
|
136
|
-
f1 = os.path.join(d1, "f1")
|
|
137
|
-
open(f1, "w").write("test1")
|
|
138
|
-
p = Path(f1)
|
|
139
|
-
fn = open_local(p)
|
|
140
|
-
assert isinstance(fn, str)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def test_open_local_w_list_of_path():
|
|
144
|
-
d1 = str(tempfile.mkdtemp())
|
|
145
|
-
f1 = os.path.join(d1, "f1")
|
|
146
|
-
open(f1, "w").write("test1")
|
|
147
|
-
p = Path(f1)
|
|
148
|
-
fn = open_local([p, p])
|
|
149
|
-
assert len(fn) == 2
|
|
150
|
-
assert isinstance(fn, list)
|
|
151
|
-
assert all(isinstance(elem, str) for elem in fn)
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def test_xz_lzma_compressions():
|
|
155
|
-
pytest.importorskip("lzma")
|
|
156
|
-
# Ensure that both 'xz' and 'lzma' compression names can be parsed
|
|
157
|
-
assert get_compression("some_file.xz", "infer") == "xz"
|
|
158
|
-
assert get_compression("some_file.xz", "xz") == "xz"
|
|
159
|
-
assert get_compression("some_file.xz", "lzma") == "lzma"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def test_list():
|
|
163
|
-
here = os.path.abspath(os.path.dirname(__file__))
|
|
164
|
-
flist = os.listdir(here)
|
|
165
|
-
plist = [os.path.join(here, p).replace("\\", "/") for p in flist]
|
|
166
|
-
of = open_files(plist)
|
|
167
|
-
assert len(of) == len(flist)
|
|
168
|
-
assert [f.path for f in of] == plist
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
def test_open_expand(m, monkeypatch):
|
|
172
|
-
m.pipe("/myfile", b"hello")
|
|
173
|
-
with pytest.raises(FileNotFoundError, match="expand=True"):
|
|
174
|
-
with fsspec.open("memory://my*", expand=False):
|
|
175
|
-
pass
|
|
176
|
-
with fsspec.open("memory://my*", expand=True) as f:
|
|
177
|
-
assert f.path == "/myfile"
|
|
178
|
-
monkeypatch.setattr(fsspec.core, "DEFAULT_EXPAND", True)
|
|
179
|
-
with fsspec.open("memory://my*") as f:
|
|
180
|
-
assert f.path == "/myfile"
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def test_pathobject(tmpdir):
|
|
184
|
-
import pathlib
|
|
185
|
-
|
|
186
|
-
tmpdir = str(tmpdir)
|
|
187
|
-
plist_str = [os.path.join(str(tmpdir), f).replace("\\", "/") for f in ["a", "b"]]
|
|
188
|
-
open(plist_str[0], "w").write("first file")
|
|
189
|
-
open(plist_str[1], "w").write("second file")
|
|
190
|
-
plist = [pathlib.Path(p) for p in plist_str]
|
|
191
|
-
of = open_files(plist)
|
|
192
|
-
assert len(of) == 2
|
|
193
|
-
assert [f.path for f in of] == plist_str
|
|
194
|
-
|
|
195
|
-
of = open_files(plist[0])
|
|
196
|
-
assert len(of) == 1
|
|
197
|
-
assert of[0].path == plist_str[0]
|
|
198
|
-
with of[0] as f:
|
|
199
|
-
assert f.read() == open(plist_str[0], "rb").read()
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
def test_automkdir(tmpdir):
|
|
203
|
-
dir = os.path.join(str(tmpdir), "a")
|
|
204
|
-
of = fsspec.open(os.path.join(dir, "afile"), "w", auto_mkdir=False)
|
|
205
|
-
with pytest.raises(IOError):
|
|
206
|
-
with of:
|
|
207
|
-
pass
|
|
208
|
-
|
|
209
|
-
dir = os.path.join(str(tmpdir), "b")
|
|
210
|
-
of = fsspec.open(os.path.join(dir, "bfile"), "w", auto_mkdir=True)
|
|
211
|
-
with of:
|
|
212
|
-
pass
|
|
213
|
-
|
|
214
|
-
assert "bfile" in os.listdir(dir)
|
|
215
|
-
|
|
216
|
-
dir = os.path.join(str(tmpdir), "c")
|
|
217
|
-
with pytest.raises(FileNotFoundError):
|
|
218
|
-
of = fsspec.open(os.path.join(dir, "bfile"), "w", auto_mkdir=False)
|
|
219
|
-
with of:
|
|
220
|
-
pass
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def test_automkdir_readonly(tmpdir):
|
|
224
|
-
dir = os.path.join(str(tmpdir), "d")
|
|
225
|
-
with pytest.raises(FileNotFoundError):
|
|
226
|
-
of = fsspec.open(os.path.join(dir, "dfile"), "r")
|
|
227
|
-
with of:
|
|
228
|
-
pass
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
def test_openfile_pickle_newline():
|
|
232
|
-
# GH#318
|
|
233
|
-
test = fsspec.open(__file__, newline=b"")
|
|
234
|
-
|
|
235
|
-
pickled = pickle.dumps(test)
|
|
236
|
-
restored = pickle.loads(pickled)
|
|
237
|
-
|
|
238
|
-
assert test.newline == restored.newline
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
def test_pickle_after_open_open():
|
|
242
|
-
of = fsspec.open(__file__, mode="rt")
|
|
243
|
-
test = of.open()
|
|
244
|
-
of2 = pickle.loads(pickle.dumps(of))
|
|
245
|
-
test2 = of2.open()
|
|
246
|
-
test.close()
|
|
247
|
-
|
|
248
|
-
assert not test2.closed
|
|
249
|
-
of.close()
|
|
250
|
-
of2.close()
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
# Define a list of special glob characters.
|
|
254
|
-
# Note that we need to escape some characters and also consider file system limitations.
|
|
255
|
-
# '*' and '?' are excluded because they are not valid for many file systems.
|
|
256
|
-
# Similarly, we're careful with '{', '}', and '@' as their special meaning is
|
|
257
|
-
# context-specific and might not be considered special for filenames.
|
|
258
|
-
# Add tests for more file systems and for more glob magic later
|
|
259
|
-
glob_magic_characters = ["[", "]", "!"]
|
|
260
|
-
if os.name != "nt":
|
|
261
|
-
glob_magic_characters.extend(("*", "?")) # not valid on Windows
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
@pytest.mark.parametrize("char", glob_magic_characters)
|
|
265
|
-
def test_open_file_read_with_special_characters(tmp_path, char):
|
|
266
|
-
# Create a filename incorporating the special character
|
|
267
|
-
file_name = f"test{char}.txt"
|
|
268
|
-
file_path = tmp_path / file_name
|
|
269
|
-
expected_content = "Hello, world!"
|
|
270
|
-
|
|
271
|
-
with open(file_path, "w") as f:
|
|
272
|
-
f.write(expected_content)
|
|
273
|
-
|
|
274
|
-
with fsspec.open(file_path, "r") as f:
|
|
275
|
-
actual_content = f.read()
|
|
276
|
-
|
|
277
|
-
assert actual_content == expected_content
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
@pytest.mark.parametrize("char", glob_magic_characters)
|
|
281
|
-
def test_open_files_read_with_special_characters(tmp_path, char):
|
|
282
|
-
# Create a filename incorporating the special character
|
|
283
|
-
file_name = f"test{char}.txt"
|
|
284
|
-
file_path = tmp_path / file_name
|
|
285
|
-
expected_content = "Hello, world!"
|
|
286
|
-
|
|
287
|
-
with open(file_path, "w") as f:
|
|
288
|
-
f.write(expected_content)
|
|
289
|
-
|
|
290
|
-
with fsspec.open_files(file_path, "r")[0] as f:
|
|
291
|
-
actual_content = f.read()
|
|
292
|
-
|
|
293
|
-
assert actual_content == expected_content
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
@pytest.mark.parametrize("char", glob_magic_characters)
|
|
297
|
-
def test_open_file_write_with_special_characters(tmp_path, char, monkeypatch):
|
|
298
|
-
# Create a filename incorporating the special character
|
|
299
|
-
file_name = f"test{char}.txt"
|
|
300
|
-
file_path = tmp_path / file_name
|
|
301
|
-
expected_content = "Hello, world!"
|
|
302
|
-
|
|
303
|
-
with fsspec.open(file_path, "w", expand=False) as f:
|
|
304
|
-
f.write(expected_content)
|
|
305
|
-
|
|
306
|
-
with open(file_path, "r") as f:
|
|
307
|
-
actual_content = f.read()
|
|
308
|
-
|
|
309
|
-
monkeypatch.setattr(fsspec.core, "DEFAULT_EXPAND", False)
|
|
310
|
-
with fsspec.open(file_path, "w") as f:
|
|
311
|
-
f.write(expected_content * 2)
|
|
312
|
-
|
|
313
|
-
with open(file_path, "r") as f:
|
|
314
|
-
f.read() == actual_content * 2
|
|
315
|
-
|
|
316
|
-
assert actual_content == expected_content
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
@pytest.mark.parametrize("char", glob_magic_characters)
|
|
320
|
-
def test_open_files_read_with_special_characters(tmp_path, char):
|
|
321
|
-
# Create a filename incorporating the special character
|
|
322
|
-
file_name = f"test{char}.txt"
|
|
323
|
-
file_path = tmp_path / file_name
|
|
324
|
-
expected_content = "Hello, world!"
|
|
325
|
-
|
|
326
|
-
with open(file_path, "w") as f:
|
|
327
|
-
f.write(expected_content)
|
|
328
|
-
|
|
329
|
-
with fsspec.open_files(
|
|
330
|
-
urlpath=[os.fspath(file_path)], mode="r", auto_mkdir=False, expand=False
|
|
331
|
-
)[0] as f:
|
|
332
|
-
actual_content = f.read()
|
|
333
|
-
|
|
334
|
-
assert actual_content == expected_content
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
@pytest.mark.parametrize("char", glob_magic_characters)
|
|
338
|
-
def test_open_files_write_with_special_characters(tmp_path, char):
|
|
339
|
-
# Create a filename incorporating the special character
|
|
340
|
-
file_name = f"test{char}.txt"
|
|
341
|
-
file_path = tmp_path / file_name
|
|
342
|
-
expected_content = "Hello, world!"
|
|
343
|
-
|
|
344
|
-
with fsspec.open_files(
|
|
345
|
-
urlpath=[os.fspath(file_path)], mode="w", auto_mkdir=False, expand=False
|
|
346
|
-
)[0] as f:
|
|
347
|
-
f.write(expected_content)
|
|
348
|
-
|
|
349
|
-
with open(file_path, "r") as f:
|
|
350
|
-
actual_content = f.read()
|
|
351
|
-
|
|
352
|
-
assert actual_content == expected_content
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
def test_mismatch():
|
|
356
|
-
pytest.importorskip("s3fs")
|
|
357
|
-
with pytest.raises(ValueError):
|
|
358
|
-
open_files(["s3://test/path.csv", "/other/path.csv"])
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
def test_url_kwargs_chain(ftp_writable):
|
|
362
|
-
host, port, username, password = ftp_writable
|
|
363
|
-
data = b"hello"
|
|
364
|
-
with fsspec.open(
|
|
365
|
-
"ftp:///afile", "wb", host=host, port=port, username=username, password=password
|
|
366
|
-
) as f:
|
|
367
|
-
f.write(data)
|
|
368
|
-
|
|
369
|
-
with fsspec.open(
|
|
370
|
-
f"simplecache::ftp://{username}:{password}@{host}:{port}//afile", "rb"
|
|
371
|
-
) as f:
|
|
372
|
-
assert f.read() == data
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
def test_multi_context(tmpdir):
|
|
376
|
-
fns = [os.path.join(tmpdir, fn) for fn in ["a", "b"]]
|
|
377
|
-
files = open_files(fns, "wb")
|
|
378
|
-
assert isinstance(files, OpenFiles)
|
|
379
|
-
assert isinstance(files[0], OpenFile)
|
|
380
|
-
assert len(files) == 2
|
|
381
|
-
assert isinstance(files[:1], OpenFiles)
|
|
382
|
-
assert len(files[:1]) == 1
|
|
383
|
-
with files as of:
|
|
384
|
-
assert len(of) == 2
|
|
385
|
-
assert not of[0].closed
|
|
386
|
-
assert of[0].name.endswith("a")
|
|
387
|
-
assert of[0].closed
|
|
388
|
-
assert repr(files) == "<List of 2 OpenFile instances>"
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
def test_not_local():
|
|
392
|
-
with pytest.raises(ValueError, match="attribute local_file=True"):
|
|
393
|
-
open_local("memory://afile")
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
def test_url_to_fs(ftp_writable):
|
|
397
|
-
host, port, username, password = ftp_writable
|
|
398
|
-
data = b"hello"
|
|
399
|
-
with fsspec.open(f"ftp://{username}:{password}@{host}:{port}/afile", "wb") as f:
|
|
400
|
-
f.write(data)
|
|
401
|
-
fs, url = fsspec.core.url_to_fs(
|
|
402
|
-
f"simplecache::ftp://{username}:{password}@{host}:{port}/afile"
|
|
403
|
-
)
|
|
404
|
-
assert url == "/afile"
|
|
405
|
-
fs, url = fsspec.core.url_to_fs(f"ftp://{username}:{password}@{host}:{port}/afile")
|
|
406
|
-
assert url == "/afile"
|
|
407
|
-
|
|
408
|
-
with fsspec.open(f"ftp://{username}:{password}@{host}:{port}/afile.zip", "wb") as f:
|
|
409
|
-
import zipfile
|
|
410
|
-
|
|
411
|
-
with zipfile.ZipFile(f, "w") as z:
|
|
412
|
-
with z.open("inner", "w") as f2:
|
|
413
|
-
f2.write(b"hello")
|
|
414
|
-
f.write(data)
|
|
415
|
-
|
|
416
|
-
fs, url = fsspec.core.url_to_fs(
|
|
417
|
-
f"zip://inner::ftp://{username}:{password}@{host}:{port}/afile.zip"
|
|
418
|
-
)
|
|
419
|
-
assert url == "inner"
|
|
420
|
-
fs, url = fsspec.core.url_to_fs(
|
|
421
|
-
f"simplecache::zip::ftp://{username}:{password}@{host}:{port}/afile.zip"
|
|
422
|
-
)
|
|
423
|
-
assert url == ""
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
def test_target_protocol_options(ftp_writable):
|
|
427
|
-
host, port, username, password = ftp_writable
|
|
428
|
-
data = {"afile": b"hello"}
|
|
429
|
-
options = {"host": host, "port": port, "username": username, "password": password}
|
|
430
|
-
with tempzip(data) as lfile, fsspec.open(
|
|
431
|
-
"ftp:///archive.zip", "wb", **options
|
|
432
|
-
) as f:
|
|
433
|
-
f.write(open(lfile, "rb").read())
|
|
434
|
-
with fsspec.open(
|
|
435
|
-
"zip://afile",
|
|
436
|
-
"rb",
|
|
437
|
-
target_protocol="ftp",
|
|
438
|
-
target_options=options,
|
|
439
|
-
fo="archive.zip",
|
|
440
|
-
) as f:
|
|
441
|
-
assert f.read() == data["afile"]
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
def test_chained_url(ftp_writable):
|
|
445
|
-
host, port, username, password = ftp_writable
|
|
446
|
-
data = {"afile": b"hello"}
|
|
447
|
-
cls = fsspec.get_filesystem_class("ftp")
|
|
448
|
-
fs = cls(host=host, port=port, username=username, password=password)
|
|
449
|
-
with tempzip(data) as lfile:
|
|
450
|
-
fs.put_file(lfile, "archive.zip")
|
|
451
|
-
|
|
452
|
-
urls = [
|
|
453
|
-
"zip://afile",
|
|
454
|
-
"zip://afile::simplecache",
|
|
455
|
-
"simplecache::zip://afile",
|
|
456
|
-
"simplecache::zip://afile::simplecache",
|
|
457
|
-
]
|
|
458
|
-
for url in urls:
|
|
459
|
-
url += f"::ftp://{username}:{password}@{host}:{port}/archive.zip"
|
|
460
|
-
with fsspec.open(url, "rb") as f:
|
|
461
|
-
assert f.read() == data["afile"]
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
def test_automkdir_local():
|
|
465
|
-
fs, _ = fsspec.core.url_to_fs("file://", auto_mkdir=True)
|
|
466
|
-
assert fs.auto_mkdir is True
|
fsspec/tests/test_downstream.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
pytest.importorskip("s3fs")
|
|
4
|
-
pytest.importorskip("moto")
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
from s3fs.tests.test_s3fs import ( # noqa: E402,F401
|
|
8
|
-
endpoint_uri,
|
|
9
|
-
s3,
|
|
10
|
-
s3_base,
|
|
11
|
-
test_bucket_name,
|
|
12
|
-
)
|
|
13
|
-
except ImportError:
|
|
14
|
-
pytest.skip("s3 tests not available.")
|
|
15
|
-
|
|
16
|
-
so = {"anon": False, "client_kwargs": {"endpoint_url": endpoint_uri}}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def test_pandas(s3):
|
|
20
|
-
pd = pytest.importorskip("pandas")
|
|
21
|
-
df = pd.DataFrame({"a": [1, 2], "b": [3, 4]})
|
|
22
|
-
df.to_csv(f"s3://{test_bucket_name}/a.csv", storage_options=so)
|
|
23
|
-
df2 = pd.read_csv(f"s3://{test_bucket_name}/a.csv", storage_options=so)
|
|
24
|
-
|
|
25
|
-
assert df.a.equals(df2.a)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def test_xarray_zarr(s3):
|
|
29
|
-
xr = pytest.importorskip("xarray")
|
|
30
|
-
pytest.importorskip("zarr")
|
|
31
|
-
import numpy as np
|
|
32
|
-
|
|
33
|
-
x = np.arange(5)
|
|
34
|
-
xarr = xr.DataArray(x)
|
|
35
|
-
ds = xr.Dataset({"x": xarr})
|
|
36
|
-
ds.to_zarr(f"s3://{test_bucket_name}/a.zarr", storage_options=so)
|
|
37
|
-
|
|
38
|
-
ds2 = xr.open_zarr(f"s3://{test_bucket_name}/a.zarr", storage_options=so)
|
|
39
|
-
|
|
40
|
-
assert (ds.x == ds2.x).all()
|
fsspec/tests/test_file.py
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
"""Tests abstract buffered file API, using FTP implementation"""
|
|
2
|
-
|
|
3
|
-
import pickle
|
|
4
|
-
|
|
5
|
-
import pytest
|
|
6
|
-
|
|
7
|
-
from fsspec.implementations.tests.test_ftp import FTPFileSystem
|
|
8
|
-
|
|
9
|
-
data = b"hello" * 10000
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def test_pickle(ftp_writable):
|
|
13
|
-
host, port, user, pw = ftp_writable
|
|
14
|
-
ftp = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
15
|
-
|
|
16
|
-
f = ftp.open("/out", "rb")
|
|
17
|
-
|
|
18
|
-
f2 = pickle.loads(pickle.dumps(f))
|
|
19
|
-
assert f == f2
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_file_read_attributes(ftp_writable):
|
|
23
|
-
host, port, user, pw = ftp_writable
|
|
24
|
-
ftp = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
25
|
-
|
|
26
|
-
f = ftp.open("/out", "rb")
|
|
27
|
-
assert f.info()["size"] == len(data)
|
|
28
|
-
assert f.tell() == 0
|
|
29
|
-
assert f.seekable()
|
|
30
|
-
assert f.readable()
|
|
31
|
-
assert not f.writable()
|
|
32
|
-
out = bytearray(len(data))
|
|
33
|
-
|
|
34
|
-
assert f.read() == data
|
|
35
|
-
assert f.read() == b""
|
|
36
|
-
f.seek(0)
|
|
37
|
-
assert f.readuntil(b"l") == b"hel"
|
|
38
|
-
assert f.tell() == 3
|
|
39
|
-
|
|
40
|
-
f.readinto1(out)
|
|
41
|
-
assert out[:-3] == data[3:]
|
|
42
|
-
with pytest.raises(ValueError):
|
|
43
|
-
f.write(b"")
|
|
44
|
-
f.close()
|
|
45
|
-
with pytest.raises(ValueError):
|
|
46
|
-
f.read()(b"")
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def test_seek(ftp_writable):
|
|
50
|
-
host, port, user, pw = ftp_writable
|
|
51
|
-
ftp = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
52
|
-
|
|
53
|
-
f = ftp.open("/out", "rb")
|
|
54
|
-
|
|
55
|
-
assert f.seek(-10, 2) == len(data) - 10
|
|
56
|
-
assert f.tell() == len(data) - 10
|
|
57
|
-
assert f.seek(-1, 1) == len(data) - 11
|
|
58
|
-
with pytest.raises(ValueError):
|
|
59
|
-
f.seek(-1)
|
|
60
|
-
with pytest.raises(ValueError):
|
|
61
|
-
f.seek(0, 7)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def test_file_idempotent(ftp_writable):
|
|
65
|
-
host, port, user, pw = ftp_writable
|
|
66
|
-
ftp = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
67
|
-
|
|
68
|
-
f = ftp.open("/out", "rb")
|
|
69
|
-
f2 = ftp.open("/out", "rb")
|
|
70
|
-
assert hash(f) == hash(f2)
|
|
71
|
-
assert f == f2
|
|
72
|
-
ftp.touch("/out2")
|
|
73
|
-
f2 = ftp.open("/out2", "rb")
|
|
74
|
-
assert hash(f2) != hash(f)
|
|
75
|
-
assert f != f2
|
|
76
|
-
f2 = ftp.open("/out", "wb")
|
|
77
|
-
assert hash(f2) != hash(f)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def test_file_text_attributes(ftp_writable):
|
|
81
|
-
host, port, user, pw = ftp_writable
|
|
82
|
-
ftp = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
83
|
-
|
|
84
|
-
data = b"hello\n" * 1000
|
|
85
|
-
with ftp.open("/out2", "wb") as f:
|
|
86
|
-
f.write(data)
|
|
87
|
-
|
|
88
|
-
f = ftp.open("/out2", "rb")
|
|
89
|
-
assert f.readline() == b"hello\n"
|
|
90
|
-
f.seek(0)
|
|
91
|
-
assert list(f) == [d + b"\n" for d in data.split()]
|
|
92
|
-
f.seek(0)
|
|
93
|
-
assert f.readlines() == [d + b"\n" for d in data.split()]
|
|
94
|
-
|
|
95
|
-
f = ftp.open("/out2", "rt")
|
|
96
|
-
assert f.readline() == "hello\n"
|
|
97
|
-
assert f.encoding
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def test_file_write_attributes(ftp_writable):
|
|
101
|
-
host, port, user, pw = ftp_writable
|
|
102
|
-
ftp = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
103
|
-
f = ftp.open("/out2", "wb")
|
|
104
|
-
with pytest.raises(ValueError):
|
|
105
|
-
f.info()
|
|
106
|
-
with pytest.raises(OSError):
|
|
107
|
-
f.seek(0)
|
|
108
|
-
with pytest.raises(ValueError):
|
|
109
|
-
f.read(0)
|
|
110
|
-
assert not f.readable()
|
|
111
|
-
assert f.writable()
|
|
112
|
-
|
|
113
|
-
f.flush() # no-op
|
|
114
|
-
|
|
115
|
-
assert f.write(b"hello") == 5
|
|
116
|
-
assert f.write(b"hello") == 5
|
|
117
|
-
assert not f.closed
|
|
118
|
-
f.close()
|
|
119
|
-
assert f.closed
|
|
120
|
-
with pytest.raises(ValueError):
|
|
121
|
-
f.write(b"")
|
|
122
|
-
with pytest.raises(ValueError):
|
|
123
|
-
f.flush()
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def test_midread_cache(ftp_writable):
|
|
127
|
-
host, port, user, pw = ftp_writable
|
|
128
|
-
fs = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
129
|
-
fn = "/myfile"
|
|
130
|
-
with fs.open(fn, "wb") as f:
|
|
131
|
-
f.write(b"a" * 175627146)
|
|
132
|
-
with fs.open(fn, "rb") as f:
|
|
133
|
-
f.seek(175561610)
|
|
134
|
-
d1 = f.read(65536)
|
|
135
|
-
assert len(d1) == 65536
|
|
136
|
-
|
|
137
|
-
f.seek(4)
|
|
138
|
-
size = 17562198
|
|
139
|
-
d2 = f.read(size)
|
|
140
|
-
assert len(d2) == size
|
|
141
|
-
|
|
142
|
-
f.seek(17562288)
|
|
143
|
-
size = 17562187
|
|
144
|
-
d3 = f.read(size)
|
|
145
|
-
assert len(d3) == size
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def test_read_block(ftp_writable):
|
|
149
|
-
# not the same as test_read_block in test_utils, this depends on the
|
|
150
|
-
# behaviour of the bytest caching
|
|
151
|
-
from fsspec.utils import read_block
|
|
152
|
-
|
|
153
|
-
host, port, user, pw = ftp_writable
|
|
154
|
-
fs = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
155
|
-
fn = "/myfile"
|
|
156
|
-
with fs.open(fn, "wb") as f:
|
|
157
|
-
f.write(b"a,b\n1,2")
|
|
158
|
-
f = fs.open(fn, "rb", cache_type="bytes")
|
|
159
|
-
assert read_block(f, 0, 6400, b"\n") == b"a,b\n1,2"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def test_with_gzip(ftp_writable):
|
|
163
|
-
import gzip
|
|
164
|
-
|
|
165
|
-
data = b"some compressible stuff"
|
|
166
|
-
host, port, user, pw = ftp_writable
|
|
167
|
-
fs = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
168
|
-
fn = "/myfile"
|
|
169
|
-
with fs.open(fn, "wb") as f:
|
|
170
|
-
gf = gzip.GzipFile(fileobj=f, mode="w")
|
|
171
|
-
gf.write(data)
|
|
172
|
-
gf.close()
|
|
173
|
-
with fs.open(fn, "rb") as f:
|
|
174
|
-
gf = gzip.GzipFile(fileobj=f, mode="r")
|
|
175
|
-
assert gf.read() == data
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def test_auto_compression(m):
|
|
179
|
-
fs = m
|
|
180
|
-
with fs.open("myfile.gz", mode="wt", compression="infer") as f:
|
|
181
|
-
f.write("text")
|
|
182
|
-
with fs.open("myfile.gz", mode="rt", compression="infer") as f:
|
|
183
|
-
assert f.read() == "text"
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def test_with_zip(ftp_writable):
|
|
187
|
-
import zipfile
|
|
188
|
-
|
|
189
|
-
data = b"hello zip"
|
|
190
|
-
host, port, user, pw = ftp_writable
|
|
191
|
-
fs = FTPFileSystem(host=host, port=port, username=user, password=pw)
|
|
192
|
-
fn = "/myfile.zip"
|
|
193
|
-
inner_file = "test.txt"
|
|
194
|
-
with fs.open(fn, "wb") as f:
|
|
195
|
-
zf = zipfile.ZipFile(f, mode="w")
|
|
196
|
-
zf.writestr(inner_file, data)
|
|
197
|
-
zf.close()
|
|
198
|
-
with fs.open(fn, "rb") as f:
|
|
199
|
-
zf = zipfile.ZipFile(f, mode="r")
|
|
200
|
-
assert zf.read(inner_file) == data
|