fsspec 2024.3.0__py3-none-any.whl → 2024.5.0__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.
Files changed (87) hide show
  1. fsspec/__init__.py +2 -3
  2. fsspec/_version.py +14 -19
  3. fsspec/caching.py +83 -14
  4. fsspec/compression.py +1 -0
  5. fsspec/core.py +31 -6
  6. fsspec/exceptions.py +1 -0
  7. fsspec/generic.py +1 -1
  8. fsspec/gui.py +1 -1
  9. fsspec/implementations/arrow.py +0 -2
  10. fsspec/implementations/cache_mapper.py +1 -2
  11. fsspec/implementations/cache_metadata.py +7 -7
  12. fsspec/implementations/dirfs.py +2 -2
  13. fsspec/implementations/http.py +9 -9
  14. fsspec/implementations/local.py +97 -48
  15. fsspec/implementations/memory.py +9 -0
  16. fsspec/implementations/smb.py +3 -1
  17. fsspec/implementations/tests/__init__.py +0 -0
  18. fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_file_listing.yaml +112 -0
  19. fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_mkdir.yaml +582 -0
  20. fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_pyarrow_non_partitioned.yaml +873 -0
  21. fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_range.yaml +458 -0
  22. fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_range_chunked.yaml +1355 -0
  23. fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_write_and_read.yaml +795 -0
  24. fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_write_pyarrow_non_partitioned.yaml +613 -0
  25. fsspec/implementations/tests/conftest.py +39 -0
  26. fsspec/implementations/tests/local/__init__.py +0 -0
  27. fsspec/implementations/tests/local/local_fixtures.py +18 -0
  28. fsspec/implementations/tests/local/local_test.py +14 -0
  29. fsspec/implementations/tests/memory/__init__.py +0 -0
  30. fsspec/implementations/tests/memory/memory_fixtures.py +27 -0
  31. fsspec/implementations/tests/memory/memory_test.py +14 -0
  32. fsspec/implementations/tests/out.zip +0 -0
  33. fsspec/implementations/tests/test_archive.py +382 -0
  34. fsspec/implementations/tests/test_arrow.py +259 -0
  35. fsspec/implementations/tests/test_cached.py +1306 -0
  36. fsspec/implementations/tests/test_common.py +35 -0
  37. fsspec/implementations/tests/test_dask.py +29 -0
  38. fsspec/implementations/tests/test_data.py +20 -0
  39. fsspec/implementations/tests/test_dbfs.py +268 -0
  40. fsspec/implementations/tests/test_dirfs.py +588 -0
  41. fsspec/implementations/tests/test_ftp.py +178 -0
  42. fsspec/implementations/tests/test_git.py +76 -0
  43. fsspec/implementations/tests/test_http.py +577 -0
  44. fsspec/implementations/tests/test_jupyter.py +57 -0
  45. fsspec/implementations/tests/test_libarchive.py +33 -0
  46. fsspec/implementations/tests/test_local.py +1285 -0
  47. fsspec/implementations/tests/test_memory.py +382 -0
  48. fsspec/implementations/tests/test_reference.py +720 -0
  49. fsspec/implementations/tests/test_sftp.py +233 -0
  50. fsspec/implementations/tests/test_smb.py +139 -0
  51. fsspec/implementations/tests/test_tar.py +243 -0
  52. fsspec/implementations/tests/test_webhdfs.py +197 -0
  53. fsspec/implementations/tests/test_zip.py +134 -0
  54. fsspec/implementations/webhdfs.py +1 -3
  55. fsspec/mapping.py +2 -2
  56. fsspec/parquet.py +0 -8
  57. fsspec/registry.py +4 -0
  58. fsspec/spec.py +21 -4
  59. fsspec/tests/__init__.py +0 -0
  60. fsspec/tests/abstract/mv.py +57 -0
  61. fsspec/tests/conftest.py +188 -0
  62. fsspec/tests/data/listing.html +1 -0
  63. fsspec/tests/test_api.py +498 -0
  64. fsspec/tests/test_async.py +230 -0
  65. fsspec/tests/test_caches.py +255 -0
  66. fsspec/tests/test_callbacks.py +89 -0
  67. fsspec/tests/test_compression.py +164 -0
  68. fsspec/tests/test_config.py +129 -0
  69. fsspec/tests/test_core.py +466 -0
  70. fsspec/tests/test_downstream.py +40 -0
  71. fsspec/tests/test_file.py +200 -0
  72. fsspec/tests/test_fuse.py +147 -0
  73. fsspec/tests/test_generic.py +90 -0
  74. fsspec/tests/test_gui.py +23 -0
  75. fsspec/tests/test_mapping.py +228 -0
  76. fsspec/tests/test_parquet.py +140 -0
  77. fsspec/tests/test_registry.py +134 -0
  78. fsspec/tests/test_spec.py +1167 -0
  79. fsspec/tests/test_utils.py +478 -0
  80. fsspec/utils.py +0 -2
  81. fsspec-2024.5.0.dist-info/METADATA +273 -0
  82. fsspec-2024.5.0.dist-info/RECORD +111 -0
  83. {fsspec-2024.3.0.dist-info → fsspec-2024.5.0.dist-info}/WHEEL +1 -2
  84. fsspec-2024.3.0.dist-info/METADATA +0 -167
  85. fsspec-2024.3.0.dist-info/RECORD +0 -54
  86. fsspec-2024.3.0.dist-info/top_level.txt +0 -1
  87. {fsspec-2024.3.0.dist-info → fsspec-2024.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,382 @@
1
+ import os
2
+ from pathlib import PurePosixPath, PureWindowsPath
3
+
4
+ import pytest
5
+
6
+ from fsspec.implementations.local import LocalFileSystem, make_path_posix
7
+
8
+
9
+ def test_1(m):
10
+ m.touch("/somefile") # NB: is found with or without initial /
11
+ m.touch("afiles/and/another")
12
+ files = m.find("")
13
+ assert files == ["/afiles/and/another", "/somefile"]
14
+
15
+ files = sorted(m.get_mapper())
16
+ assert files == ["afiles/and/another", "somefile"]
17
+
18
+
19
+ def test_strip(m):
20
+ assert m._strip_protocol("") == ""
21
+ assert m._strip_protocol("memory://") == ""
22
+ assert m._strip_protocol("afile") == "/afile"
23
+ assert m._strip_protocol("/b/c") == "/b/c"
24
+ assert m._strip_protocol("/b/c/") == "/b/c"
25
+
26
+
27
+ def test_ls(m):
28
+ m.mkdir("/dir")
29
+ m.mkdir("/dir/dir1")
30
+
31
+ m.touch("/dir/afile")
32
+ m.touch("/dir/dir1/bfile")
33
+ m.touch("/dir/dir1/cfile")
34
+
35
+ assert m.ls("/", False) == ["/dir"]
36
+ assert m.ls("/dir", False) == ["/dir/afile", "/dir/dir1"]
37
+ assert m.ls("/dir", True)[0]["type"] == "file"
38
+ assert m.ls("/dir", True)[1]["type"] == "directory"
39
+ assert m.ls("/dir/afile", False) == ["/dir/afile"]
40
+ assert m.ls("/dir/afile", True)[0]["type"] == "file"
41
+
42
+ assert len(m.ls("/dir/dir1")) == 2
43
+ assert len(m.ls("/dir/afile")) == 1
44
+
45
+
46
+ def test_directories(m):
47
+ m.mkdir("outer/inner")
48
+ assert m.info("outer/inner")["type"] == "directory"
49
+
50
+ assert m.ls("outer")
51
+ assert m.ls("outer/inner") == []
52
+
53
+ with pytest.raises(OSError):
54
+ m.rmdir("outer")
55
+
56
+ m.rmdir("outer/inner")
57
+ m.rmdir("outer")
58
+
59
+ assert not m.store
60
+
61
+
62
+ def test_exists_isdir_isfile(m):
63
+ m.mkdir("/root")
64
+ m.touch("/root/a")
65
+
66
+ assert m.exists("/root")
67
+ assert m.isdir("/root")
68
+ assert not m.isfile("/root")
69
+
70
+ assert m.exists("/root/a")
71
+ assert m.isfile("/root/a")
72
+ assert not m.isdir("/root/a")
73
+
74
+ assert not m.exists("/root/not-exists")
75
+ assert not m.isfile("/root/not-exists")
76
+ assert not m.isdir("/root/not-exists")
77
+
78
+ m.rm("/root/a")
79
+ m.rmdir("/root")
80
+
81
+ assert not m.exists("/root")
82
+
83
+ m.touch("/a/b")
84
+ assert m.isfile("/a/b")
85
+
86
+ assert m.exists("/a")
87
+ assert m.isdir("/a")
88
+ assert not m.isfile("/a")
89
+
90
+
91
+ def test_touch(m):
92
+ m.touch("/root/a")
93
+ with pytest.raises(FileExistsError):
94
+ m.touch("/root/a/b")
95
+ with pytest.raises(FileExistsError):
96
+ m.touch("/root/a/b/c")
97
+ assert not m.exists("/root/a/b/")
98
+
99
+
100
+ def test_mv_recursive(m):
101
+ m.mkdir("src")
102
+ m.touch("src/file.txt")
103
+ m.mv("src", "dest", recursive=True)
104
+ assert m.exists("dest/file.txt")
105
+ assert not m.exists("src")
106
+
107
+
108
+ def test_mv_same_paths(m):
109
+ m.mkdir("src")
110
+ m.touch("src/file.txt")
111
+ m.mv("src", "src", recursive=True)
112
+ assert m.exists("src/file.txt")
113
+
114
+
115
+ def test_rm_no_pseudo_dir(m):
116
+ m.touch("/dir1/dir2/file")
117
+ m.rm("/dir1", recursive=True)
118
+ assert not m.exists("/dir1/dir2/file")
119
+ assert not m.exists("/dir1/dir2")
120
+ assert not m.exists("/dir1")
121
+
122
+ with pytest.raises(FileNotFoundError):
123
+ m.rm("/dir1", recursive=True)
124
+
125
+
126
+ def test_rewind(m):
127
+ # https://github.com/fsspec/filesystem_spec/issues/349
128
+ with m.open("src/file.txt", "w") as f:
129
+ f.write("content")
130
+ with m.open("src/file.txt") as f:
131
+ assert f.tell() == 0
132
+
133
+
134
+ def test_empty_raises(m):
135
+ with pytest.raises(FileNotFoundError):
136
+ m.ls("nonexistent")
137
+
138
+ with pytest.raises(FileNotFoundError):
139
+ m.info("nonexistent")
140
+
141
+
142
+ def test_dir_errors(m):
143
+ m.mkdir("/first")
144
+
145
+ with pytest.raises(FileExistsError):
146
+ m.mkdir("/first")
147
+ with pytest.raises(FileExistsError):
148
+ m.makedirs("/first", exist_ok=False)
149
+ m.makedirs("/first", exist_ok=True)
150
+ m.makedirs("/first/second/third")
151
+ assert "/first/second" in m.pseudo_dirs
152
+
153
+ m.touch("/afile")
154
+ with pytest.raises(NotADirectoryError):
155
+ m.mkdir("/afile/nodir")
156
+
157
+
158
+ def test_no_rewind_append_mode(m):
159
+ # https://github.com/fsspec/filesystem_spec/issues/349
160
+ with m.open("src/file.txt", "w") as f:
161
+ f.write("content")
162
+ with m.open("src/file.txt", "a") as f:
163
+ assert f.tell() == 7
164
+
165
+
166
+ def test_moves(m):
167
+ m.touch("source.txt")
168
+ m.mv("source.txt", "target.txt")
169
+
170
+ m.touch("source2.txt")
171
+ m.mv("source2.txt", "target2.txt", recursive=True)
172
+ assert m.find("") == ["/target.txt", "/target2.txt"]
173
+
174
+
175
+ def test_rm_reursive_empty_subdir(m):
176
+ # https://github.com/fsspec/filesystem_spec/issues/500
177
+ m.mkdir("recdir")
178
+ m.mkdir("recdir/subdir2")
179
+ m.rm("recdir/", recursive=True)
180
+ assert not m.exists("dir")
181
+
182
+
183
+ def test_seekable(m):
184
+ fn0 = "foo.txt"
185
+ with m.open(fn0, "wb") as f:
186
+ f.write(b"data")
187
+
188
+ f = m.open(fn0, "rt")
189
+ assert f.seekable(), "file is not seekable"
190
+ f.seek(1)
191
+ assert f.read(1) == "a"
192
+ assert f.tell() == 2
193
+
194
+
195
+ # https://github.com/fsspec/filesystem_spec/issues/1425
196
+ @pytest.mark.parametrize("mode", ["r", "rb", "w", "wb", "ab", "r+b"])
197
+ def test_open_mode(m, mode):
198
+ filename = "mode.txt"
199
+ m.touch(filename)
200
+ with m.open(filename, mode=mode) as _:
201
+ pass
202
+
203
+
204
+ def test_remove_all(m):
205
+ m.touch("afile")
206
+ m.rm("/", recursive=True)
207
+ assert not m.ls("/")
208
+
209
+
210
+ def test_cp_directory_recursive(m):
211
+ # https://github.com/fsspec/filesystem_spec/issues/1062
212
+ # Recursive cp/get/put of source directory into non-existent target directory.
213
+ src = "/src"
214
+ src_file = src + "/file"
215
+ m.mkdir(src)
216
+ m.touch(src_file)
217
+
218
+ target = "/target"
219
+
220
+ # cp without slash
221
+ assert not m.exists(target)
222
+ for loop in range(2):
223
+ m.cp(src, target, recursive=True)
224
+ assert m.isdir(target)
225
+
226
+ if loop == 0:
227
+ correct = [target + "/file"]
228
+ assert m.find(target) == correct
229
+ else:
230
+ correct = [target + "/file", target + "/src/file"]
231
+ assert sorted(m.find(target)) == correct
232
+
233
+ m.rm(target, recursive=True)
234
+
235
+ # cp with slash
236
+ assert not m.exists(target)
237
+ for loop in range(2):
238
+ m.cp(src + "/", target, recursive=True)
239
+ assert m.isdir(target)
240
+ correct = [target + "/file"]
241
+ assert m.find(target) == correct
242
+
243
+
244
+ def test_get_directory_recursive(m, tmpdir):
245
+ # https://github.com/fsspec/filesystem_spec/issues/1062
246
+ # Recursive cp/get/put of source directory into non-existent target directory.
247
+ src = "/src"
248
+ src_file = src + "/file"
249
+ m.mkdir(src)
250
+ m.touch(src_file)
251
+
252
+ target = os.path.join(tmpdir, "target")
253
+ target_fs = LocalFileSystem()
254
+
255
+ # get without slash
256
+ assert not target_fs.exists(target)
257
+ for loop in range(2):
258
+ m.get(src, target, recursive=True)
259
+ assert target_fs.isdir(target)
260
+
261
+ if loop == 0:
262
+ correct = [make_path_posix(os.path.join(target, "file"))]
263
+ assert target_fs.find(target) == correct
264
+ else:
265
+ correct = [
266
+ make_path_posix(os.path.join(target, "file")),
267
+ make_path_posix(os.path.join(target, "src", "file")),
268
+ ]
269
+ assert sorted(target_fs.find(target)) == correct
270
+
271
+ target_fs.rm(target, recursive=True)
272
+
273
+ # get with slash
274
+ assert not target_fs.exists(target)
275
+ for loop in range(2):
276
+ m.get(src + "/", target, recursive=True)
277
+ assert target_fs.isdir(target)
278
+ correct = [make_path_posix(os.path.join(target, "file"))]
279
+ assert target_fs.find(target) == correct
280
+
281
+
282
+ def test_put_directory_recursive(m, tmpdir):
283
+ # https://github.com/fsspec/filesystem_spec/issues/1062
284
+ # Recursive cp/get/put of source directory into non-existent target directory.
285
+ src = os.path.join(tmpdir, "src")
286
+ src_file = os.path.join(src, "file")
287
+ source_fs = LocalFileSystem()
288
+ source_fs.mkdir(src)
289
+ source_fs.touch(src_file)
290
+
291
+ target = "/target"
292
+
293
+ # put without slash
294
+ assert not m.exists(target)
295
+ for loop in range(2):
296
+ m.put(src, target, recursive=True)
297
+ assert m.isdir(target)
298
+
299
+ if loop == 0:
300
+ correct = [target + "/file"]
301
+ assert m.find(target) == correct
302
+ else:
303
+ correct = [target + "/file", target + "/src/file"]
304
+ assert sorted(m.find(target)) == correct
305
+
306
+ m.rm(target, recursive=True)
307
+
308
+ # put with slash
309
+ assert not m.exists(target)
310
+ for loop in range(2):
311
+ m.put(src + "/", target, recursive=True)
312
+ assert m.isdir(target)
313
+ correct = [target + "/file"]
314
+ assert m.find(target) == correct
315
+
316
+
317
+ def test_cp_empty_directory(m):
318
+ # https://github.com/fsspec/filesystem_spec/issues/1198
319
+ # cp/get/put of empty directory.
320
+ empty = "/src/empty"
321
+ m.mkdir(empty)
322
+
323
+ target = "/target"
324
+ m.mkdir(target)
325
+
326
+ # cp without slash, target directory exists
327
+ assert m.isdir(target)
328
+ m.cp(empty, target)
329
+ assert m.find(target, withdirs=True) == [target]
330
+
331
+ # cp with slash, target directory exists
332
+ assert m.isdir(target)
333
+ m.cp(empty + "/", target)
334
+ assert m.find(target, withdirs=True) == [target]
335
+
336
+ m.rmdir(target)
337
+
338
+ # cp without slash, target directory doesn't exist
339
+ assert not m.isdir(target)
340
+ m.cp(empty, target)
341
+ assert not m.isdir(target)
342
+
343
+ # cp with slash, target directory doesn't exist
344
+ assert not m.isdir(target)
345
+ m.cp(empty + "/", target)
346
+ assert not m.isdir(target)
347
+
348
+
349
+ def test_cp_two_files(m):
350
+ src = "/src"
351
+ file0 = src + "/file0"
352
+ file1 = src + "/file1"
353
+ m.mkdir(src)
354
+ m.touch(file0)
355
+ m.touch(file1)
356
+
357
+ target = "/target"
358
+ assert not m.exists(target)
359
+
360
+ m.cp([file0, file1], target)
361
+
362
+ assert m.isdir(target)
363
+ assert sorted(m.find(target)) == [
364
+ "/target/file0",
365
+ "/target/file1",
366
+ ]
367
+
368
+
369
+ def test_open_path_posix(m):
370
+ path = PurePosixPath("/myfile/foo/bar")
371
+ with m.open(path, "wb") as f:
372
+ f.write(b"some\nlines\nof\ntext")
373
+
374
+ assert m.read_text(path) == "some\nlines\nof\ntext"
375
+
376
+
377
+ def test_open_path_windows(m):
378
+ path = PureWindowsPath("C:\\myfile\\foo\\bar")
379
+ with m.open(path, "wb") as f:
380
+ f.write(b"some\nlines\nof\ntext")
381
+
382
+ assert m.read_text(path) == "some\nlines\nof\ntext"