fsspec 2023.6.0__py3-none-any.whl → 2023.9.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 +3 -3
- fsspec/asyn.py +154 -92
- fsspec/caching.py +1 -1
- fsspec/compression.py +7 -2
- fsspec/core.py +16 -8
- fsspec/generic.py +111 -17
- fsspec/gui.py +4 -2
- fsspec/implementations/cache_mapper.py +80 -0
- fsspec/implementations/cache_metadata.py +232 -0
- fsspec/implementations/cached.py +74 -157
- fsspec/implementations/dirfs.py +3 -1
- fsspec/implementations/http.py +36 -19
- fsspec/implementations/local.py +4 -21
- fsspec/implementations/memory.py +8 -9
- fsspec/implementations/reference.py +8 -8
- fsspec/implementations/sftp.py +6 -2
- fsspec/implementations/smb.py +39 -23
- fsspec/mapping.py +8 -0
- fsspec/registry.py +22 -0
- fsspec/spec.py +164 -96
- fsspec/tests/abstract/__init__.py +147 -0
- fsspec/tests/abstract/common.py +175 -0
- fsspec/tests/abstract/copy.py +250 -56
- fsspec/tests/abstract/get.py +248 -38
- fsspec/tests/abstract/put.py +246 -66
- fsspec/utils.py +25 -8
- {fsspec-2023.6.0.dist-info → fsspec-2023.9.1.dist-info}/METADATA +1 -1
- fsspec-2023.9.1.dist-info/RECORD +54 -0
- fsspec-2023.6.0.dist-info/RECORD +0 -51
- {fsspec-2023.6.0.dist-info → fsspec-2023.9.1.dist-info}/LICENSE +0 -0
- {fsspec-2023.6.0.dist-info → fsspec-2023.9.1.dist-info}/WHEEL +0 -0
- {fsspec-2023.6.0.dist-info → fsspec-2023.9.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
GLOB_EDGE_CASES_TESTS = {
|
|
2
|
+
"argnames": ("path", "recursive", "maxdepth", "expected"),
|
|
3
|
+
"argvalues": [
|
|
4
|
+
("fil?1", False, None, ["file1"]),
|
|
5
|
+
("fil?1", True, None, ["file1"]),
|
|
6
|
+
("file[1-2]", False, None, ["file1", "file2"]),
|
|
7
|
+
("file[1-2]", True, None, ["file1", "file2"]),
|
|
8
|
+
("*", False, None, ["file1", "file2"]),
|
|
9
|
+
(
|
|
10
|
+
"*",
|
|
11
|
+
True,
|
|
12
|
+
None,
|
|
13
|
+
[
|
|
14
|
+
"file1",
|
|
15
|
+
"file2",
|
|
16
|
+
"subdir0/subfile1",
|
|
17
|
+
"subdir0/subfile2",
|
|
18
|
+
"subdir0/nesteddir/nestedfile",
|
|
19
|
+
"subdir1/subfile1",
|
|
20
|
+
"subdir1/subfile2",
|
|
21
|
+
"subdir1/nesteddir/nestedfile",
|
|
22
|
+
],
|
|
23
|
+
),
|
|
24
|
+
("*", True, 1, ["file1", "file2"]),
|
|
25
|
+
(
|
|
26
|
+
"*",
|
|
27
|
+
True,
|
|
28
|
+
2,
|
|
29
|
+
[
|
|
30
|
+
"file1",
|
|
31
|
+
"file2",
|
|
32
|
+
"subdir0/subfile1",
|
|
33
|
+
"subdir0/subfile2",
|
|
34
|
+
"subdir1/subfile1",
|
|
35
|
+
"subdir1/subfile2",
|
|
36
|
+
],
|
|
37
|
+
),
|
|
38
|
+
("*1", False, None, ["file1"]),
|
|
39
|
+
(
|
|
40
|
+
"*1",
|
|
41
|
+
True,
|
|
42
|
+
None,
|
|
43
|
+
[
|
|
44
|
+
"file1",
|
|
45
|
+
"subdir1/subfile1",
|
|
46
|
+
"subdir1/subfile2",
|
|
47
|
+
"subdir1/nesteddir/nestedfile",
|
|
48
|
+
],
|
|
49
|
+
),
|
|
50
|
+
("*1", True, 2, ["file1", "subdir1/subfile1", "subdir1/subfile2"]),
|
|
51
|
+
(
|
|
52
|
+
"**",
|
|
53
|
+
False,
|
|
54
|
+
None,
|
|
55
|
+
[
|
|
56
|
+
"file1",
|
|
57
|
+
"file2",
|
|
58
|
+
"subdir0/subfile1",
|
|
59
|
+
"subdir0/subfile2",
|
|
60
|
+
"subdir0/nesteddir/nestedfile",
|
|
61
|
+
"subdir1/subfile1",
|
|
62
|
+
"subdir1/subfile2",
|
|
63
|
+
"subdir1/nesteddir/nestedfile",
|
|
64
|
+
],
|
|
65
|
+
),
|
|
66
|
+
(
|
|
67
|
+
"**",
|
|
68
|
+
True,
|
|
69
|
+
None,
|
|
70
|
+
[
|
|
71
|
+
"file1",
|
|
72
|
+
"file2",
|
|
73
|
+
"subdir0/subfile1",
|
|
74
|
+
"subdir0/subfile2",
|
|
75
|
+
"subdir0/nesteddir/nestedfile",
|
|
76
|
+
"subdir1/subfile1",
|
|
77
|
+
"subdir1/subfile2",
|
|
78
|
+
"subdir1/nesteddir/nestedfile",
|
|
79
|
+
],
|
|
80
|
+
),
|
|
81
|
+
("**", True, 1, ["file1", "file2"]),
|
|
82
|
+
(
|
|
83
|
+
"**",
|
|
84
|
+
True,
|
|
85
|
+
2,
|
|
86
|
+
[
|
|
87
|
+
"file1",
|
|
88
|
+
"file2",
|
|
89
|
+
"subdir0/subfile1",
|
|
90
|
+
"subdir0/subfile2",
|
|
91
|
+
"subdir0/nesteddir/nestedfile",
|
|
92
|
+
"subdir1/subfile1",
|
|
93
|
+
"subdir1/subfile2",
|
|
94
|
+
"subdir1/nesteddir/nestedfile",
|
|
95
|
+
],
|
|
96
|
+
),
|
|
97
|
+
(
|
|
98
|
+
"**",
|
|
99
|
+
False,
|
|
100
|
+
2,
|
|
101
|
+
[
|
|
102
|
+
"file1",
|
|
103
|
+
"file2",
|
|
104
|
+
"subdir0/subfile1",
|
|
105
|
+
"subdir0/subfile2",
|
|
106
|
+
"subdir1/subfile1",
|
|
107
|
+
"subdir1/subfile2",
|
|
108
|
+
],
|
|
109
|
+
),
|
|
110
|
+
("**1", False, None, ["file1", "subdir0/subfile1", "subdir1/subfile1"]),
|
|
111
|
+
(
|
|
112
|
+
"**1",
|
|
113
|
+
True,
|
|
114
|
+
None,
|
|
115
|
+
[
|
|
116
|
+
"file1",
|
|
117
|
+
"subdir0/subfile1",
|
|
118
|
+
"subdir1/subfile1",
|
|
119
|
+
"subdir1/subfile2",
|
|
120
|
+
"subdir1/nesteddir/nestedfile",
|
|
121
|
+
],
|
|
122
|
+
),
|
|
123
|
+
("**1", True, 1, ["file1"]),
|
|
124
|
+
(
|
|
125
|
+
"**1",
|
|
126
|
+
True,
|
|
127
|
+
2,
|
|
128
|
+
["file1", "subdir0/subfile1", "subdir1/subfile1", "subdir1/subfile2"],
|
|
129
|
+
),
|
|
130
|
+
("**1", False, 2, ["file1", "subdir0/subfile1", "subdir1/subfile1"]),
|
|
131
|
+
("**/subdir0", False, None, []),
|
|
132
|
+
("**/subdir0", True, None, ["subfile1", "subfile2", "nesteddir/nestedfile"]),
|
|
133
|
+
("**/subdir0/nested*", False, 2, []),
|
|
134
|
+
("**/subdir0/nested*", True, 2, ["nestedfile"]),
|
|
135
|
+
("subdir[1-2]", False, None, []),
|
|
136
|
+
("subdir[1-2]", True, None, ["subfile1", "subfile2", "nesteddir/nestedfile"]),
|
|
137
|
+
("subdir[1-2]", True, 2, ["subfile1", "subfile2"]),
|
|
138
|
+
("subdir[0-1]", False, None, []),
|
|
139
|
+
(
|
|
140
|
+
"subdir[0-1]",
|
|
141
|
+
True,
|
|
142
|
+
None,
|
|
143
|
+
[
|
|
144
|
+
"subdir0/subfile1",
|
|
145
|
+
"subdir0/subfile2",
|
|
146
|
+
"subdir0/nesteddir/nestedfile",
|
|
147
|
+
"subdir1/subfile1",
|
|
148
|
+
"subdir1/subfile2",
|
|
149
|
+
"subdir1/nesteddir/nestedfile",
|
|
150
|
+
],
|
|
151
|
+
),
|
|
152
|
+
(
|
|
153
|
+
"subdir[0-1]/*fil[e]*",
|
|
154
|
+
False,
|
|
155
|
+
None,
|
|
156
|
+
[
|
|
157
|
+
"subdir0/subfile1",
|
|
158
|
+
"subdir0/subfile2",
|
|
159
|
+
"subdir1/subfile1",
|
|
160
|
+
"subdir1/subfile2",
|
|
161
|
+
],
|
|
162
|
+
),
|
|
163
|
+
(
|
|
164
|
+
"subdir[0-1]/*fil[e]*",
|
|
165
|
+
True,
|
|
166
|
+
None,
|
|
167
|
+
[
|
|
168
|
+
"subdir0/subfile1",
|
|
169
|
+
"subdir0/subfile2",
|
|
170
|
+
"subdir1/subfile1",
|
|
171
|
+
"subdir1/subfile2",
|
|
172
|
+
],
|
|
173
|
+
),
|
|
174
|
+
],
|
|
175
|
+
}
|
fsspec/tests/abstract/copy.py
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
|
+
from hashlib import md5
|
|
2
|
+
from itertools import product
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from fsspec.tests.abstract.common import GLOB_EDGE_CASES_TESTS
|
|
7
|
+
|
|
8
|
+
|
|
1
9
|
class AbstractCopyTests:
|
|
2
10
|
def test_copy_file_to_existing_directory(
|
|
3
|
-
self,
|
|
11
|
+
self,
|
|
12
|
+
fs,
|
|
13
|
+
fs_join,
|
|
14
|
+
fs_bulk_operations_scenario_0,
|
|
15
|
+
fs_target,
|
|
16
|
+
supports_empty_directories,
|
|
4
17
|
):
|
|
5
18
|
# Copy scenario 1a
|
|
6
19
|
source = fs_bulk_operations_scenario_0
|
|
7
20
|
|
|
8
21
|
target = fs_target
|
|
9
22
|
fs.mkdir(target)
|
|
10
|
-
if not
|
|
23
|
+
if not supports_empty_directories:
|
|
11
24
|
# Force target directory to exist by adding a dummy file
|
|
12
25
|
fs.touch(fs_join(target, "dummy"))
|
|
13
26
|
assert fs.isdir(target)
|
|
@@ -53,13 +66,22 @@ class AbstractCopyTests:
|
|
|
53
66
|
assert fs.isfile(fs_join(target, "newdir", "subfile1"))
|
|
54
67
|
|
|
55
68
|
def test_copy_file_to_file_in_existing_directory(
|
|
56
|
-
self,
|
|
69
|
+
self,
|
|
70
|
+
fs,
|
|
71
|
+
fs_join,
|
|
72
|
+
fs_bulk_operations_scenario_0,
|
|
73
|
+
fs_target,
|
|
74
|
+
supports_empty_directories,
|
|
57
75
|
):
|
|
58
76
|
# Copy scenario 1c
|
|
59
77
|
source = fs_bulk_operations_scenario_0
|
|
60
78
|
|
|
61
79
|
target = fs_target
|
|
62
80
|
fs.mkdir(target)
|
|
81
|
+
if not supports_empty_directories:
|
|
82
|
+
# Force target directory to exist by adding a dummy file
|
|
83
|
+
fs.touch(fs_join(target, "dummy"))
|
|
84
|
+
assert fs.isdir(target)
|
|
63
85
|
|
|
64
86
|
fs.cp(fs_join(source, "subdir", "subfile1"), fs_join(target, "newfile"))
|
|
65
87
|
assert fs.isfile(fs_join(target, "newfile"))
|
|
@@ -80,14 +102,19 @@ class AbstractCopyTests:
|
|
|
80
102
|
assert fs.isfile(fs_join(target, "newdir", "newfile"))
|
|
81
103
|
|
|
82
104
|
def test_copy_directory_to_existing_directory(
|
|
83
|
-
self,
|
|
105
|
+
self,
|
|
106
|
+
fs,
|
|
107
|
+
fs_join,
|
|
108
|
+
fs_bulk_operations_scenario_0,
|
|
109
|
+
fs_target,
|
|
110
|
+
supports_empty_directories,
|
|
84
111
|
):
|
|
85
112
|
# Copy scenario 1e
|
|
86
113
|
source = fs_bulk_operations_scenario_0
|
|
87
114
|
|
|
88
115
|
target = fs_target
|
|
89
116
|
fs.mkdir(target)
|
|
90
|
-
if not
|
|
117
|
+
if not supports_empty_directories:
|
|
91
118
|
# Force target directory to exist by adding a dummy file
|
|
92
119
|
dummy = fs_join(target, "dummy")
|
|
93
120
|
fs.touch(dummy)
|
|
@@ -101,7 +128,7 @@ class AbstractCopyTests:
|
|
|
101
128
|
|
|
102
129
|
# Without recursive does nothing
|
|
103
130
|
fs.cp(s, t)
|
|
104
|
-
assert fs.ls(target) == [] if
|
|
131
|
+
assert fs.ls(target) == ([] if supports_empty_directories else [dummy])
|
|
105
132
|
|
|
106
133
|
# With recursive
|
|
107
134
|
fs.cp(s, t, recursive=True)
|
|
@@ -112,7 +139,14 @@ class AbstractCopyTests:
|
|
|
112
139
|
assert fs.isfile(fs_join(target, "nesteddir", "nestedfile"))
|
|
113
140
|
assert not fs.exists(fs_join(target, "subdir"))
|
|
114
141
|
|
|
115
|
-
fs.rm(
|
|
142
|
+
fs.rm(
|
|
143
|
+
[
|
|
144
|
+
fs_join(target, "subfile1"),
|
|
145
|
+
fs_join(target, "subfile2"),
|
|
146
|
+
fs_join(target, "nesteddir"),
|
|
147
|
+
],
|
|
148
|
+
recursive=True,
|
|
149
|
+
)
|
|
116
150
|
else:
|
|
117
151
|
assert fs.isdir(fs_join(target, "subdir"))
|
|
118
152
|
assert fs.isfile(fs_join(target, "subdir", "subfile1"))
|
|
@@ -121,7 +155,7 @@ class AbstractCopyTests:
|
|
|
121
155
|
assert fs.isfile(fs_join(target, "subdir", "nesteddir", "nestedfile"))
|
|
122
156
|
|
|
123
157
|
fs.rm(fs_join(target, "subdir"), recursive=True)
|
|
124
|
-
assert fs.ls(target) == [] if
|
|
158
|
+
assert fs.ls(target) == ([] if supports_empty_directories else [dummy])
|
|
125
159
|
|
|
126
160
|
# Limit recursive by maxdepth
|
|
127
161
|
fs.cp(s, t, recursive=True, maxdepth=1)
|
|
@@ -131,7 +165,13 @@ class AbstractCopyTests:
|
|
|
131
165
|
assert not fs.exists(fs_join(target, "nesteddir"))
|
|
132
166
|
assert not fs.exists(fs_join(target, "subdir"))
|
|
133
167
|
|
|
134
|
-
fs.rm(
|
|
168
|
+
fs.rm(
|
|
169
|
+
[
|
|
170
|
+
fs_join(target, "subfile1"),
|
|
171
|
+
fs_join(target, "subfile2"),
|
|
172
|
+
],
|
|
173
|
+
recursive=True,
|
|
174
|
+
)
|
|
135
175
|
else:
|
|
136
176
|
assert fs.isdir(fs_join(target, "subdir"))
|
|
137
177
|
assert fs.isfile(fs_join(target, "subdir", "subfile1"))
|
|
@@ -139,10 +179,15 @@ class AbstractCopyTests:
|
|
|
139
179
|
assert not fs.exists(fs_join(target, "subdir", "nesteddir"))
|
|
140
180
|
|
|
141
181
|
fs.rm(fs_join(target, "subdir"), recursive=True)
|
|
142
|
-
assert fs.ls(target) == [] if
|
|
182
|
+
assert fs.ls(target) == ([] if supports_empty_directories else [dummy])
|
|
143
183
|
|
|
144
184
|
def test_copy_directory_to_new_directory(
|
|
145
|
-
self,
|
|
185
|
+
self,
|
|
186
|
+
fs,
|
|
187
|
+
fs_join,
|
|
188
|
+
fs_bulk_operations_scenario_0,
|
|
189
|
+
fs_target,
|
|
190
|
+
supports_empty_directories,
|
|
146
191
|
):
|
|
147
192
|
# Copy scenario 1f
|
|
148
193
|
source = fs_bulk_operations_scenario_0
|
|
@@ -160,7 +205,11 @@ class AbstractCopyTests:
|
|
|
160
205
|
|
|
161
206
|
# Without recursive does nothing
|
|
162
207
|
fs.cp(s, t)
|
|
163
|
-
|
|
208
|
+
if supports_empty_directories:
|
|
209
|
+
assert fs.ls(target) == []
|
|
210
|
+
else:
|
|
211
|
+
with pytest.raises(FileNotFoundError):
|
|
212
|
+
fs.ls(target)
|
|
164
213
|
|
|
165
214
|
# With recursive
|
|
166
215
|
fs.cp(s, t, recursive=True)
|
|
@@ -186,13 +235,23 @@ class AbstractCopyTests:
|
|
|
186
235
|
assert not fs.exists(fs_join(target, "newdir"))
|
|
187
236
|
|
|
188
237
|
def test_copy_glob_to_existing_directory(
|
|
189
|
-
self,
|
|
238
|
+
self,
|
|
239
|
+
fs,
|
|
240
|
+
fs_join,
|
|
241
|
+
fs_bulk_operations_scenario_0,
|
|
242
|
+
fs_target,
|
|
243
|
+
supports_empty_directories,
|
|
190
244
|
):
|
|
191
245
|
# Copy scenario 1g
|
|
192
246
|
source = fs_bulk_operations_scenario_0
|
|
193
247
|
|
|
194
248
|
target = fs_target
|
|
195
249
|
fs.mkdir(target)
|
|
250
|
+
if not supports_empty_directories:
|
|
251
|
+
# Force target directory to exist by adding a dummy file
|
|
252
|
+
dummy = fs_join(target, "dummy")
|
|
253
|
+
fs.touch(dummy)
|
|
254
|
+
assert fs.isdir(target)
|
|
196
255
|
|
|
197
256
|
for target_slash in [False, True]:
|
|
198
257
|
t = target + "/" if target_slash else target
|
|
@@ -205,29 +264,51 @@ class AbstractCopyTests:
|
|
|
205
264
|
assert not fs.exists(fs_join(target, "nesteddir", "nestedfile"))
|
|
206
265
|
assert not fs.exists(fs_join(target, "subdir"))
|
|
207
266
|
|
|
208
|
-
fs.rm(
|
|
209
|
-
|
|
267
|
+
fs.rm(
|
|
268
|
+
[
|
|
269
|
+
fs_join(target, "subfile1"),
|
|
270
|
+
fs_join(target, "subfile2"),
|
|
271
|
+
],
|
|
272
|
+
recursive=True,
|
|
273
|
+
)
|
|
274
|
+
assert fs.ls(target) == ([] if supports_empty_directories else [dummy])
|
|
210
275
|
|
|
211
276
|
# With recursive
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
fs.rm(fs.ls(target, detail=False), recursive=True)
|
|
220
|
-
assert fs.ls(target) == []
|
|
277
|
+
for glob, recursive in zip(["*", "**"], [True, False]):
|
|
278
|
+
fs.cp(fs_join(source, "subdir", glob), t, recursive=recursive)
|
|
279
|
+
assert fs.isfile(fs_join(target, "subfile1"))
|
|
280
|
+
assert fs.isfile(fs_join(target, "subfile2"))
|
|
281
|
+
assert fs.isdir(fs_join(target, "nesteddir"))
|
|
282
|
+
assert fs.isfile(fs_join(target, "nesteddir", "nestedfile"))
|
|
283
|
+
assert not fs.exists(fs_join(target, "subdir"))
|
|
221
284
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
285
|
+
fs.rm(
|
|
286
|
+
[
|
|
287
|
+
fs_join(target, "subfile1"),
|
|
288
|
+
fs_join(target, "subfile2"),
|
|
289
|
+
fs_join(target, "nesteddir"),
|
|
290
|
+
],
|
|
291
|
+
recursive=True,
|
|
292
|
+
)
|
|
293
|
+
assert fs.ls(target) == ([] if supports_empty_directories else [dummy])
|
|
294
|
+
|
|
295
|
+
# Limit recursive by maxdepth
|
|
296
|
+
fs.cp(
|
|
297
|
+
fs_join(source, "subdir", glob), t, recursive=recursive, maxdepth=1
|
|
298
|
+
)
|
|
299
|
+
assert fs.isfile(fs_join(target, "subfile1"))
|
|
300
|
+
assert fs.isfile(fs_join(target, "subfile2"))
|
|
301
|
+
assert not fs.exists(fs_join(target, "nesteddir"))
|
|
302
|
+
assert not fs.exists(fs_join(target, "subdir"))
|
|
228
303
|
|
|
229
|
-
|
|
230
|
-
|
|
304
|
+
fs.rm(
|
|
305
|
+
[
|
|
306
|
+
fs_join(target, "subfile1"),
|
|
307
|
+
fs_join(target, "subfile2"),
|
|
308
|
+
],
|
|
309
|
+
recursive=True,
|
|
310
|
+
)
|
|
311
|
+
assert fs.ls(target) == ([] if supports_empty_directories else [dummy])
|
|
231
312
|
|
|
232
313
|
def test_copy_glob_to_new_directory(
|
|
233
314
|
self, fs, fs_join, fs_bulk_operations_scenario_0, fs_target
|
|
@@ -257,39 +338,92 @@ class AbstractCopyTests:
|
|
|
257
338
|
assert not fs.exists(fs_join(target, "newdir"))
|
|
258
339
|
|
|
259
340
|
# With recursive
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
341
|
+
for glob, recursive in zip(["*", "**"], [True, False]):
|
|
342
|
+
fs.cp(fs_join(source, "subdir", glob), t, recursive=recursive)
|
|
343
|
+
assert fs.isdir(fs_join(target, "newdir"))
|
|
344
|
+
assert fs.isfile(fs_join(target, "newdir", "subfile1"))
|
|
345
|
+
assert fs.isfile(fs_join(target, "newdir", "subfile2"))
|
|
346
|
+
assert fs.isdir(fs_join(target, "newdir", "nesteddir"))
|
|
347
|
+
assert fs.isfile(fs_join(target, "newdir", "nesteddir", "nestedfile"))
|
|
348
|
+
assert not fs.exists(fs_join(target, "subdir"))
|
|
349
|
+
assert not fs.exists(fs_join(target, "newdir", "subdir"))
|
|
350
|
+
|
|
351
|
+
fs.rm(fs_join(target, "newdir"), recursive=True)
|
|
352
|
+
assert not fs.exists(fs_join(target, "newdir"))
|
|
353
|
+
|
|
354
|
+
# Limit recursive by maxdepth
|
|
355
|
+
fs.cp(
|
|
356
|
+
fs_join(source, "subdir", glob), t, recursive=recursive, maxdepth=1
|
|
357
|
+
)
|
|
358
|
+
assert fs.isdir(fs_join(target, "newdir"))
|
|
359
|
+
assert fs.isfile(fs_join(target, "newdir", "subfile1"))
|
|
360
|
+
assert fs.isfile(fs_join(target, "newdir", "subfile2"))
|
|
361
|
+
assert not fs.exists(fs_join(target, "newdir", "nesteddir"))
|
|
362
|
+
assert not fs.exists(fs_join(target, "subdir"))
|
|
363
|
+
assert not fs.exists(fs_join(target, "newdir", "subdir"))
|
|
364
|
+
|
|
365
|
+
fs.rm(fs_join(target, "newdir"), recursive=True)
|
|
366
|
+
assert not fs.exists(fs_join(target, "newdir"))
|
|
367
|
+
|
|
368
|
+
@pytest.mark.parametrize(
|
|
369
|
+
GLOB_EDGE_CASES_TESTS["argnames"],
|
|
370
|
+
GLOB_EDGE_CASES_TESTS["argvalues"],
|
|
371
|
+
)
|
|
372
|
+
def test_copy_glob_edge_cases(
|
|
373
|
+
self,
|
|
374
|
+
path,
|
|
375
|
+
recursive,
|
|
376
|
+
maxdepth,
|
|
377
|
+
expected,
|
|
378
|
+
fs,
|
|
379
|
+
fs_join,
|
|
380
|
+
fs_glob_edge_cases_files,
|
|
381
|
+
fs_target,
|
|
382
|
+
fs_sanitize_path,
|
|
383
|
+
):
|
|
384
|
+
# Copy scenario 1g
|
|
385
|
+
source = fs_glob_edge_cases_files
|
|
268
386
|
|
|
269
|
-
|
|
270
|
-
assert not fs.exists(fs_join(target, "newdir"))
|
|
387
|
+
target = fs_target
|
|
271
388
|
|
|
272
|
-
|
|
273
|
-
fs.
|
|
274
|
-
assert fs.isdir(fs_join(target, "newdir"))
|
|
275
|
-
assert fs.isfile(fs_join(target, "newdir", "subfile1"))
|
|
276
|
-
assert fs.isfile(fs_join(target, "newdir", "subfile2"))
|
|
277
|
-
assert not fs.exists(fs_join(target, "newdir", "nesteddir"))
|
|
278
|
-
assert not fs.exists(fs_join(target, "subdir"))
|
|
279
|
-
assert not fs.exists(fs_join(target, "newdir", "subdir"))
|
|
389
|
+
for new_dir, target_slash in product([True, False], [True, False]):
|
|
390
|
+
fs.mkdir(target)
|
|
280
391
|
|
|
281
|
-
|
|
282
|
-
|
|
392
|
+
t = fs_join(target, "newdir") if new_dir else target
|
|
393
|
+
t = t + "/" if target_slash else t
|
|
394
|
+
|
|
395
|
+
fs.copy(fs_join(source, path), t, recursive=recursive, maxdepth=maxdepth)
|
|
396
|
+
|
|
397
|
+
output = fs.find(target)
|
|
398
|
+
if new_dir:
|
|
399
|
+
prefixed_expected = [
|
|
400
|
+
fs_sanitize_path(fs_join(target, "newdir", p)) for p in expected
|
|
401
|
+
]
|
|
402
|
+
else:
|
|
403
|
+
prefixed_expected = [
|
|
404
|
+
fs_sanitize_path(fs_join(target, p)) for p in expected
|
|
405
|
+
]
|
|
406
|
+
assert sorted(output) == sorted(prefixed_expected)
|
|
407
|
+
|
|
408
|
+
try:
|
|
409
|
+
fs.rm(target, recursive=True)
|
|
410
|
+
except FileNotFoundError:
|
|
411
|
+
pass
|
|
283
412
|
|
|
284
413
|
def test_copy_list_of_files_to_existing_directory(
|
|
285
|
-
self,
|
|
414
|
+
self,
|
|
415
|
+
fs,
|
|
416
|
+
fs_join,
|
|
417
|
+
fs_bulk_operations_scenario_0,
|
|
418
|
+
fs_target,
|
|
419
|
+
supports_empty_directories,
|
|
286
420
|
):
|
|
287
421
|
# Copy scenario 2a
|
|
288
422
|
source = fs_bulk_operations_scenario_0
|
|
289
423
|
|
|
290
424
|
target = fs_target
|
|
291
425
|
fs.mkdir(target)
|
|
292
|
-
if not
|
|
426
|
+
if not supports_empty_directories:
|
|
293
427
|
# Force target directory to exist by adding a dummy file
|
|
294
428
|
dummy = fs_join(target, "dummy")
|
|
295
429
|
fs.touch(dummy)
|
|
@@ -309,8 +443,15 @@ class AbstractCopyTests:
|
|
|
309
443
|
assert fs.isfile(fs_join(target, "file2"))
|
|
310
444
|
assert fs.isfile(fs_join(target, "subfile1"))
|
|
311
445
|
|
|
312
|
-
fs.rm(
|
|
313
|
-
|
|
446
|
+
fs.rm(
|
|
447
|
+
[
|
|
448
|
+
fs_join(target, "file1"),
|
|
449
|
+
fs_join(target, "file2"),
|
|
450
|
+
fs_join(target, "subfile1"),
|
|
451
|
+
],
|
|
452
|
+
recursive=True,
|
|
453
|
+
)
|
|
454
|
+
assert fs.ls(target) == ([] if supports_empty_directories else [dummy])
|
|
314
455
|
|
|
315
456
|
def test_copy_list_of_files_to_new_directory(
|
|
316
457
|
self, fs, fs_join, fs_bulk_operations_scenario_0, fs_target
|
|
@@ -347,3 +488,56 @@ class AbstractCopyTests:
|
|
|
347
488
|
assert fs.isdir(target)
|
|
348
489
|
assert fs.isfile(fs_join(target, "file1"))
|
|
349
490
|
assert fs.isfile(fs_join(target, "file2"))
|
|
491
|
+
|
|
492
|
+
def test_copy_directory_without_files_with_same_name_prefix(
|
|
493
|
+
self,
|
|
494
|
+
fs,
|
|
495
|
+
fs_join,
|
|
496
|
+
fs_target,
|
|
497
|
+
fs_dir_and_file_with_same_name_prefix,
|
|
498
|
+
supports_empty_directories,
|
|
499
|
+
):
|
|
500
|
+
# Create the test dirs
|
|
501
|
+
source = fs_dir_and_file_with_same_name_prefix
|
|
502
|
+
target = fs_target
|
|
503
|
+
|
|
504
|
+
# Test without glob
|
|
505
|
+
fs.cp(fs_join(source, "subdir"), target, recursive=True)
|
|
506
|
+
|
|
507
|
+
assert fs.isfile(fs_join(target, "subfile.txt"))
|
|
508
|
+
assert not fs.isfile(fs_join(target, "subdir.txt"))
|
|
509
|
+
|
|
510
|
+
fs.rm([fs_join(target, "subfile.txt")])
|
|
511
|
+
if supports_empty_directories:
|
|
512
|
+
assert fs.ls(target) == []
|
|
513
|
+
else:
|
|
514
|
+
assert not fs.exists(target)
|
|
515
|
+
|
|
516
|
+
# Test with glob
|
|
517
|
+
fs.cp(fs_join(source, "subdir*"), target, recursive=True)
|
|
518
|
+
|
|
519
|
+
assert fs.isdir(fs_join(target, "subdir"))
|
|
520
|
+
assert fs.isfile(fs_join(target, "subdir", "subfile.txt"))
|
|
521
|
+
assert fs.isfile(fs_join(target, "subdir.txt"))
|
|
522
|
+
|
|
523
|
+
def test_copy_with_source_and_destination_as_list(
|
|
524
|
+
self, fs, fs_target, fs_join, fs_10_files_with_hashed_names
|
|
525
|
+
):
|
|
526
|
+
# Create the test dir
|
|
527
|
+
source = fs_10_files_with_hashed_names
|
|
528
|
+
target = fs_target
|
|
529
|
+
|
|
530
|
+
# Create list of files for source and destination
|
|
531
|
+
source_files = []
|
|
532
|
+
destination_files = []
|
|
533
|
+
for i in range(10):
|
|
534
|
+
hashed_i = md5(str(i).encode("utf-8")).hexdigest()
|
|
535
|
+
source_files.append(fs_join(source, f"{hashed_i}.txt"))
|
|
536
|
+
destination_files.append(fs_join(target, f"{hashed_i}.txt"))
|
|
537
|
+
|
|
538
|
+
# Copy and assert order was kept
|
|
539
|
+
fs.copy(path1=source_files, path2=destination_files)
|
|
540
|
+
|
|
541
|
+
for i in range(10):
|
|
542
|
+
file_content = fs.cat(destination_files[i]).decode("utf-8")
|
|
543
|
+
assert file_content == str(i)
|