megfile 4.2.5__py3-none-any.whl → 5.0.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.
@@ -0,0 +1,51 @@
1
+ megfile/__init__.py,sha256=2QtWAC9XFlKDhY0NTHsCJd2wQ-8LKz0q1ng4-8cXo38,2836
2
+ megfile/cli.py,sha256=yRrnXLYejCz1928JCjjiqOe50YH8lD1xuwaiej_67Ng,29352
3
+ megfile/config.py,sha256=r_QmInU_gFiSTV1nLJ5SyBVCX5bsANqOoNM82bRESnQ,4414
4
+ megfile/errors.py,sha256=eC7z-2-QqE12pYgTGAOIlEBsemqcMyeBFVUEDz3gBS0,15585
5
+ megfile/fs_path.py,sha256=tt2__W6E4vep0lmVreTLIW63njl-EzyQEEkEGziyAb4,41015
6
+ megfile/hdfs_path.py,sha256=OmUe3vA3Qoxnqtcq0Rs3ygBvzAtqUz3fGo8iP5sWneE,26058
7
+ megfile/http_path.py,sha256=08OmzmRMyLSyq1Yr1K2HbzexesURJrIoA6AibwYzUiA,13844
8
+ megfile/interfaces.py,sha256=XU46U5pl4k1Gse63i4z5SvxcjWeKLj0xyB0Y6fYiWWo,9887
9
+ megfile/pathlike.py,sha256=kacTG55j3dq3b7YP7MT7jxeJGbDwvK3XuZIvF-UUE0o,31244
10
+ megfile/s3_path.py,sha256=LINHnHnpesXnf9wxbV6n0xQVT0wPwyjLc7xAasakefU,94467
11
+ megfile/sftp2_path.py,sha256=K90bnMVAx0MQPGXP6LogGuDRzaD4MPR6lMOfdY9C9-0,37942
12
+ megfile/sftp_path.py,sha256=_KU7_-Mq2m7lcLY1mpiGrju0SP-OsdEXlRjFhZH25UA,51223
13
+ megfile/smart.py,sha256=Lab2jxprj-zvPw5GqUWlWiEY8bcpRlviks_qp9r-km8,38224
14
+ megfile/smart_path.py,sha256=cI8LSD1M7p-pHFJ-yDIgen8g9FyfbfDLrDfQwkkKT-Q,12240
15
+ megfile/stdio_path.py,sha256=cxaDr8rtisTPnN-rjtaEpqQnshwiqwXFUJBM9xWY7Cg,2711
16
+ megfile/version.py,sha256=sWZ_cOSUdsW9iQos7P4NME_qRop6_sbMdttJcWoYa7o,19
17
+ megfile/webdav_path.py,sha256=96rt3jN_XfDXY0UYC_Kufrz5Uc5KySo34QnlVbDIQK8,31278
18
+ megfile/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ megfile/lib/base_memory_handler.py,sha256=i5-YHpL0k2tuFBnP9VMzb3_OsaU6D6j6thkmWgptnFg,2680
20
+ megfile/lib/base_prefetch_reader.py,sha256=MYaWOkXc3geZMYNPHlPZmmpOR6uSz-AMuCZwYdoz7t0,13296
21
+ megfile/lib/combine_reader.py,sha256=Kp2wEloOUpTlIU7dve87MBpSzmIM-F9OtpTawAjFkiU,4828
22
+ megfile/lib/compare.py,sha256=CPSbyqsQ396oSfxa7h0NdUUqBw5A3WOn6fHrNKkuinw,2188
23
+ megfile/lib/compat.py,sha256=SynEeHluys3tCK-lb_1oV3o_ft83yZvunqM_AjibLgE,207
24
+ megfile/lib/fnmatch.py,sha256=4MvGzEahMRA-u8Z7mxaD-Yw1idOwBoJJpVywQy29jwY,4162
25
+ megfile/lib/glob.py,sha256=Xt2lSEMn9FmffmH68Y2rlpJhq7K3pN2aOtZpw3byW74,9793
26
+ megfile/lib/hdfs_prefetch_reader.py,sha256=yCNpcXcTiC2SHKHC-Qp50KQx1ObSLmOgwNUKlG-4ADg,2131
27
+ megfile/lib/hdfs_tools.py,sha256=4K-OdMYFFSLBGmDzjatioHvuZuUbKVy7ACeJl-l0HLQ,435
28
+ megfile/lib/http_prefetch_reader.py,sha256=x0m5tKN8QLl5QkZyNEDW662UJaZoMf61GDHVvXsDrTQ,4030
29
+ megfile/lib/joinpath.py,sha256=R3sz3pvcgbv1e793vZUnwGH-NmDlEghEPNwq5IEMm4I,1251
30
+ megfile/lib/lazy_handler.py,sha256=bE7RGt1x_xYWMgGAvHr7dwEt52qy-D3z90X3oyCvE6g,1875
31
+ megfile/lib/s3_buffered_writer.py,sha256=a42tr48QXToTQtZD1XfK1Veju6qLCLF0RJC0V_P3pW8,8252
32
+ megfile/lib/s3_cached_handler.py,sha256=MkNt6AAapd5x8BH2gnW5_S0cLofN-mshEdb0qSoLho8,1426
33
+ megfile/lib/s3_limited_seekable_writer.py,sha256=rBlGCsrIJdVRKdsJ1uIAE_R6EN96Kl2JMskk-5czYmE,6289
34
+ megfile/lib/s3_memory_handler.py,sha256=YHakyN21hvBoSlGXSV1UfFMFBh3WJNYWmiwyEzmIytw,2125
35
+ megfile/lib/s3_pipe_handler.py,sha256=g3iAN1P9pCdvSNsGeJBGcBa10S62oqIg_9W3b3wc7os,3809
36
+ megfile/lib/s3_prefetch_reader.py,sha256=AqfADmbbZYA6nw4vxBOiFWX5q5CSYOd0hq1LWcf1PY0,4524
37
+ megfile/lib/s3_share_cache_reader.py,sha256=8uip5IdVjPXCquXrskjocsZx2-TiXqWZPY0gX8JC144,4020
38
+ megfile/lib/shadow_handler.py,sha256=TntewlvIW9ZxCfmqASDQREHoiZ8v42faOe9sovQYQz0,2779
39
+ megfile/lib/stdio_handler.py,sha256=IDdgENLQlhigEwkLL4zStueVSzdWg7xVcTF_koof_Ek,1987
40
+ megfile/lib/url.py,sha256=ER32pWy9Q2MAk3TraAaNEBWIqUeBmLuM57ol2cs7-Ks,103
41
+ megfile/lib/webdav_memory_handler.py,sha256=KDSU-Z3ECiH5p6mo8TsbqHxjSBCZNx-LtFW9nIimdOY,2508
42
+ megfile/lib/webdav_prefetch_reader.py,sha256=M0X6E6t-DS5q9KiLvjVZx_AZuiW9SaIkBnIPLc774GQ,3941
43
+ megfile/utils/__init__.py,sha256=4hBVSXbNTbDj7Je0y9SbwgcPm_s41H9v3eHUMr9JNGo,12700
44
+ megfile/utils/mutex.py,sha256=asb8opGLgK22RiuBJUnfsvB8LnMmodP8KzCVHKmQBWA,2561
45
+ megfile-5.0.0.dist-info/licenses/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
46
+ megfile-5.0.0.dist-info/licenses/LICENSE.pyre,sha256=9lf5nT-5ZH25JijpYAequ0bl8E8z5JmZB1qrjiUMp84,1080
47
+ megfile-5.0.0.dist-info/METADATA,sha256=xwRH2pja42oQN9jJHaiTsFeKO0Ib8Ih4Thvi2cyNns0,9225
48
+ megfile-5.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ megfile-5.0.0.dist-info/entry_points.txt,sha256=M6ZWSSv5_5_QtIpZafy3vq7WuOJ_5dSGQQnEZbByt2Q,49
50
+ megfile-5.0.0.dist-info/top_level.txt,sha256=i3rMgdU1ZAJekAceojhA-bkm3749PzshtRmLTbeLUPQ,8
51
+ megfile-5.0.0.dist-info/RECORD,,
megfile/fs.py DELETED
@@ -1,627 +0,0 @@
1
- import os
2
- from stat import S_ISDIR as stat_isdir
3
- from stat import S_ISLNK as stat_islnk
4
- from typing import IO, BinaryIO, Callable, Iterator, List, Optional, Tuple
5
-
6
- from megfile.fs_path import (
7
- FSPath,
8
- _make_stat,
9
- fs_path_join,
10
- is_fs,
11
- )
12
- from megfile.interfaces import Access, ContextIterator, FileEntry, PathLike, StatResult
13
-
14
- __all__ = [
15
- "is_fs",
16
- "fs_path_join",
17
- "fs_readlink",
18
- "fs_cwd",
19
- "fs_home",
20
- "fs_iglob",
21
- "fs_glob",
22
- "fs_glob_stat",
23
- "fs_rename",
24
- "fs_resolve",
25
- "fs_move",
26
- "fs_makedirs",
27
- "fs_lstat",
28
- "fs_isabs",
29
- "fs_abspath",
30
- "fs_access",
31
- "fs_exists",
32
- "fs_getmtime",
33
- "fs_getsize",
34
- "fs_expanduser",
35
- "fs_isdir",
36
- "fs_isfile",
37
- "fs_listdir",
38
- "fs_load_from",
39
- "fs_realpath",
40
- "fs_relpath",
41
- "fs_remove",
42
- "fs_scan",
43
- "fs_scan_stat",
44
- "fs_scandir",
45
- "fs_stat",
46
- "fs_unlink",
47
- "fs_walk",
48
- "fs_getmd5",
49
- "fs_copy",
50
- "fs_sync",
51
- "fs_symlink",
52
- "fs_islink",
53
- "fs_ismount",
54
- "fs_save_as",
55
- "fs_open",
56
- ]
57
-
58
-
59
- def fs_isabs(path: PathLike) -> bool:
60
- """Test whether a path is absolute
61
-
62
- :param path: Given path
63
- :returns: True if a path is absolute, else False
64
- """
65
- return FSPath(path).is_absolute()
66
-
67
-
68
- def fs_abspath(path: PathLike) -> str:
69
- """Return the absolute path of given path
70
-
71
- :param path: Given path
72
- :returns: Absolute path of given path
73
- """
74
- return FSPath(path).abspath()
75
-
76
-
77
- def fs_access(path: PathLike, mode: Access = Access.READ) -> bool:
78
- """
79
- Test if path has access permission described by mode
80
- Using ``os.access``
81
-
82
- :param path: Given path
83
- :param mode: access mode
84
- :returns: Access: Enum, the read/write access that path has.
85
- """
86
- return FSPath(path).access(mode)
87
-
88
-
89
- def fs_exists(path: PathLike, followlinks: bool = False) -> bool:
90
- """
91
- Test if the path exists
92
-
93
- .. note::
94
-
95
- The difference between this function and ``os.path.exists`` is that
96
- this function regard symlink as file.
97
- In other words, this function is equal to ``os.path.lexists``
98
-
99
- :param path: Given path
100
- :param followlinks: False if regard symlink as file, else True
101
- :returns: True if the path exists, else False
102
-
103
- """
104
- return FSPath(path).exists(followlinks)
105
-
106
-
107
- def fs_getmtime(path: PathLike, follow_symlinks: bool = False) -> float:
108
- """
109
- Get last-modified time of the file on the given path (in Unix timestamp format).
110
- If the path is an existent directory,
111
- return the latest modified time of all file in it.
112
-
113
- :param path: Given path
114
- :returns: last-modified time
115
- """
116
- return FSPath(path).getmtime(follow_symlinks)
117
-
118
-
119
- def fs_getsize(path: PathLike, follow_symlinks: bool = False) -> int:
120
- """
121
- Get file size on the given file path (in bytes).
122
- If the path in a directory, return the sum of all file size in it,
123
- including file in subdirectories (if exist).
124
- The result excludes the size of directory itself.
125
- In other words, return 0 Byte on an empty directory path.
126
-
127
- :param path: Given path
128
- :returns: File size
129
-
130
- """
131
- return FSPath(path).getsize(follow_symlinks)
132
-
133
-
134
- def fs_expanduser(path: PathLike):
135
- """Expand ~ and ~user constructions. If user or $HOME is unknown,
136
- do nothing.
137
- """
138
- return FSPath(path).expanduser()
139
-
140
-
141
- def fs_isdir(path: PathLike, followlinks: bool = False) -> bool:
142
- """
143
- Test if a path is directory
144
-
145
- .. note::
146
-
147
- The difference between this function and ``os.path.isdir`` is that
148
- this function regard symlink as file
149
-
150
- :param path: Given path
151
- :param followlinks: False if regard symlink as file, else True
152
- :returns: True if the path is a directory, else False
153
-
154
- """
155
- return FSPath(path).is_dir(followlinks)
156
-
157
-
158
- def fs_isfile(path: PathLike, followlinks: bool = False) -> bool:
159
- """
160
- Test if a path is file
161
-
162
- .. note::
163
-
164
- The difference between this function and ``os.path.isfile`` is that
165
- this function regard symlink as file
166
-
167
- :param path: Given path
168
- :param followlinks: False if regard symlink as file, else True
169
- :returns: True if the path is a file, else False
170
-
171
- """
172
- return FSPath(path).is_file(followlinks)
173
-
174
-
175
- def fs_listdir(path: Optional[PathLike] = None) -> List[str]:
176
- """
177
- Get all contents of given fs path.
178
- The result is in ascending alphabetical order.
179
-
180
- :param path: Given path
181
- :returns: All contents have in the path in ascending alphabetical order
182
- """
183
- if path is None:
184
- return sorted(os.listdir(path))
185
- return FSPath(path).listdir()
186
-
187
-
188
- def fs_load_from(path: PathLike) -> BinaryIO:
189
- """Read all content on specified path and write into memory
190
-
191
- User should close the BinaryIO manually
192
-
193
- :param path: Given path
194
- :returns: Binary stream
195
- """
196
- return FSPath(path).load()
197
-
198
-
199
- def fs_realpath(path: PathLike) -> str:
200
- """Return the real path of given path
201
-
202
- :param path: Given path
203
- :returns: Real path of given path
204
- """
205
- return FSPath(path).realpath()
206
-
207
-
208
- def fs_relpath(path: PathLike, start: Optional[str] = None) -> str:
209
- """Return the relative path of given path
210
-
211
- :param path: Given path
212
- :param start: Given start directory
213
- :returns: Relative path from start
214
- """
215
- return FSPath(path).relpath(start)
216
-
217
-
218
- def fs_remove(path: PathLike, missing_ok: bool = False) -> None:
219
- """
220
- Remove the file or directory on fs
221
-
222
- :param path: Given path
223
- :param missing_ok: if False and target file/directory not exists,
224
- raise FileNotFoundError
225
- """
226
- return FSPath(path).remove(missing_ok)
227
-
228
-
229
- def fs_scan(
230
- path: PathLike, missing_ok: bool = True, followlinks: bool = False
231
- ) -> Iterator[str]:
232
- """
233
- Iteratively traverse only files in given directory, in alphabetical order.
234
- Every iteration on generator yields a path string.
235
-
236
- If path is a file path, yields the file only
237
- If path is a non-existent path, return an empty generator
238
- If path is a bucket path, return all file paths in the bucket
239
-
240
- :param path: Given path
241
- :param missing_ok: If False and there's no file in the directory,
242
- raise FileNotFoundError
243
- :returns: A file path generator
244
- """
245
- return FSPath(path).scan(missing_ok, followlinks)
246
-
247
-
248
- def fs_scan_stat(
249
- path: PathLike, missing_ok: bool = True, followlinks: bool = False
250
- ) -> Iterator[FileEntry]:
251
- """
252
- Iteratively traverse only files in given directory, in alphabetical order.
253
- Every iteration on generator yields a tuple of path string and file stat
254
-
255
- :param path: Given path
256
- :param missing_ok: If False and there's no file in the directory,
257
- raise FileNotFoundError
258
- :returns: A file path generator
259
- """
260
- return FSPath(path).scan_stat(missing_ok, followlinks)
261
-
262
-
263
- def fs_scandir(path: Optional[PathLike] = None) -> Iterator[FileEntry]:
264
- """
265
- Get all content of given file path.
266
-
267
- :param path: Given path
268
- :returns: An iterator contains all contents have prefix path
269
- """
270
- if path is None:
271
-
272
- def create_generator():
273
- with os.scandir(None) as entries:
274
- for entry in entries:
275
- stat = entry.stat()
276
- yield FileEntry(
277
- entry.name,
278
- entry.path,
279
- StatResult(
280
- size=stat.st_size,
281
- ctime=stat.st_ctime,
282
- mtime=stat.st_mtime,
283
- isdir=stat_isdir(stat.st_mode),
284
- islnk=stat_islnk(stat.st_mode),
285
- extra=stat,
286
- ),
287
- )
288
-
289
- return ContextIterator(create_generator())
290
-
291
- return FSPath(path).scandir()
292
-
293
-
294
- def fs_stat(path: PathLike, follow_symlinks=True) -> StatResult:
295
- """
296
- Get StatResult of file on fs, including file size and mtime,
297
- referring to fs_getsize and fs_getmtime
298
-
299
- :param path: Given path
300
- :returns: StatResult
301
- """
302
- return FSPath(path).stat(follow_symlinks)
303
-
304
-
305
- def fs_unlink(path: PathLike, missing_ok: bool = False) -> None:
306
- """
307
- Remove the file on fs
308
-
309
- :param path: Given path
310
- :param missing_ok: if False and target file not exists, raise FileNotFoundError
311
- """
312
- return FSPath(path).unlink(missing_ok)
313
-
314
-
315
- def fs_walk(
316
- path: PathLike, followlinks: bool = False
317
- ) -> Iterator[Tuple[str, List[str], List[str]]]:
318
- """
319
- Generate the file names in a directory tree by walking the tree top-down.
320
- For each directory in the tree rooted at directory path (including path itself),
321
- it yields a 3-tuple (root, dirs, files).
322
-
323
- - root: a string of current path
324
- - dirs: name list of subdirectories (excluding '.' and '..' if they exist)
325
- in 'root'. The list is sorted by ascending alphabetical order
326
- - files: name list of non-directory files (link is regarded as file) in 'root'.
327
- The list is sorted by ascending alphabetical order
328
-
329
- If path not exists, or path is a file (link is regarded as file),
330
- return an empty generator
331
-
332
- .. note::
333
-
334
- Be aware that setting ``followlinks`` to True can lead to infinite recursion
335
- if a link points to a parent directory of itself. fs_walk() does not keep
336
- track of the directories it visited already.
337
-
338
- :param path: Given path
339
- :param followlinks: False if regard symlink as file, else True
340
-
341
- :returns: A 3-tuple generator
342
- """
343
- return FSPath(path).walk(followlinks)
344
-
345
-
346
- def fs_getmd5(path: PathLike, recalculate: bool = False, followlinks: bool = False):
347
- """
348
- Calculate the md5 value of the file
349
-
350
- :param path: Given path
351
- :param recalculate: Ignore this parameter, just for compatibility
352
- :param followlinks: Ignore this parameter, just for compatibility
353
-
354
- returns: md5 of file
355
- """
356
- return FSPath(path).md5(recalculate, followlinks)
357
-
358
-
359
- def fs_copy(
360
- src_path: PathLike,
361
- dst_path: PathLike,
362
- callback: Optional[Callable[[int], None]] = None,
363
- followlinks: bool = False,
364
- overwrite: bool = True,
365
- ):
366
- """File copy on file system
367
- Copy content (excluding meta date) of file on `src_path` to `dst_path`.
368
- `dst_path` must be a complete file name
369
-
370
- .. note ::
371
-
372
- The differences between this function and shutil.copyfile are:
373
-
374
- 1. If parent directory of dst_path doesn't exist, create it
375
-
376
- 2. Allow callback function, None by default.
377
- callback: Optional[Callable[[int], None]], the int data is means
378
- the size (in bytes) of the written data that is passed periodically
379
-
380
- 3. This function is thread-unsafe
381
-
382
- :param src_path: Given path
383
- :param dst_path: Target file path
384
- :param callback: Called periodically during copy, and the input parameter is
385
- the data size (in bytes) of copy since the last call
386
- :param followlinks: False if regard symlink as file, else True
387
- :param overwrite: whether or not overwrite file when exists, default is True
388
- """
389
- return FSPath(src_path).copy(dst_path, callback, followlinks, overwrite)
390
-
391
-
392
- def fs_sync(
393
- src_path: PathLike,
394
- dst_path: PathLike,
395
- followlinks: bool = False,
396
- force: bool = False,
397
- overwrite: bool = True,
398
- ) -> None:
399
- """Force write of everything to disk.
400
-
401
- :param src_path: Given path
402
- :param dst_path: Target file path
403
- :param followlinks: False if regard symlink as file, else True
404
- :param force: Sync file forcible, do not ignore same files,
405
- priority is higher than 'overwrite', default is False
406
- :param overwrite: whether or not overwrite file when exists, default is True
407
- """
408
- return FSPath(src_path).sync(dst_path, followlinks, force, overwrite)
409
-
410
-
411
- def fs_symlink(src_path: PathLike, dst_path: PathLike) -> None:
412
- """
413
- Create a symbolic link pointing to src_path named dst_path.
414
-
415
- :param src_path: Given path
416
- :param dst_path: Destination path
417
- """
418
- return FSPath(src_path).symlink(dst_path)
419
-
420
-
421
- def fs_islink(path: PathLike) -> bool:
422
- """Test whether a path is a symbolic link
423
-
424
- :param path: Given path
425
- :return: If path is a symbolic link return True, else False
426
- :rtype: bool
427
- """
428
- return FSPath(path).is_symlink()
429
-
430
-
431
- def fs_ismount(path: PathLike) -> bool:
432
- """Test whether a path is a mount point
433
-
434
- :param path: Given path
435
- :returns: True if a path is a mount point, else False
436
- """
437
- return FSPath(path).is_mount()
438
-
439
-
440
- def fs_save_as(file_object: BinaryIO, path: PathLike):
441
- """Write the opened binary stream to path
442
- If parent directory of path doesn't exist, it will be created.
443
-
444
- :param path: Given path
445
- :param file_object: stream to be read
446
- """
447
- return FSPath(path).save(file_object)
448
-
449
-
450
- def fs_readlink(path) -> str:
451
- """
452
- Return a string representing the path to which the symbolic link points.
453
- :returns: Return a string representing the path to which the symbolic link points.
454
- """
455
- return FSPath(path).readlink().path_without_protocol # pyre-ignore[7]
456
-
457
-
458
- def fs_cwd() -> str:
459
- """Return current working directory
460
-
461
- returns: Current working directory
462
- """
463
- return os.getcwd()
464
-
465
-
466
- def fs_home():
467
- """Return the home directory
468
-
469
- returns: Home directory path
470
- """
471
- return os.path.expanduser("~")
472
-
473
-
474
- def fs_iglob(
475
- path: PathLike, recursive: bool = True, missing_ok: bool = True
476
- ) -> Iterator[str]:
477
- """Return path iterator in ascending alphabetical order,
478
- in which path matches glob pattern
479
-
480
- 1. If doesn't match any path, return empty list
481
- Notice: ``glob.glob`` in standard library returns ['a/'] instead of empty list
482
- when pathname is like `a/**`, recursive is True and directory 'a' doesn't exist.
483
- fs_glob behaves like ``glob.glob`` in standard library under such circumstance.
484
- 2. No guarantee that each path in result is different, which means:
485
- Assume there exists a path `/a/b/c/b/d.txt`
486
- use path pattern like `/**/b/**/*.txt` to glob,
487
- the path above will be returned twice
488
- 3. `**` will match any matched file, directory, symlink and '' by default,
489
- when recursive is `True`
490
- 4. fs_glob returns same as glob.glob(pathname, recursive=True)
491
- in ascending alphabetical order.
492
- 5. Hidden files (filename stars with '.') will not be found in the result
493
-
494
- :param recursive: If False, `**` will not search directory recursively
495
- :param missing_ok: If False and target path doesn't match any file,
496
- raise FileNotFoundError
497
- :returns: An iterator contains paths match `pathname`
498
- """
499
- for path_obj in FSPath(path).iglob(
500
- pattern="", recursive=recursive, missing_ok=missing_ok
501
- ):
502
- yield path_obj.path_without_protocol # pyre-ignore[7]
503
-
504
-
505
- def fs_glob(
506
- path: PathLike, recursive: bool = True, missing_ok: bool = True
507
- ) -> List[str]:
508
- """Return path list in ascending alphabetical order,
509
- in which path matches glob pattern
510
-
511
- 1. If doesn't match any path, return empty list
512
- Notice: ``glob.glob`` in standard library returns ['a/'] instead of empty list
513
- when pathname is like `a/**`, recursive is True and directory 'a' doesn't exist.
514
- fs_glob behaves like ``glob.glob`` in standard library under such circumstance.
515
- 2. No guarantee that each path in result is different, which means:
516
- Assume there exists a path `/a/b/c/b/d.txt`
517
- use path pattern like `/**/b/**/*.txt` to glob,
518
- the path above will be returned twice
519
- 3. `**` will match any matched file, directory, symlink and '' by default,
520
- when recursive is `True`
521
- 4. fs_glob returns same as glob.glob(pathname, recursive=True)
522
- in ascending alphabetical order.
523
- 5. Hidden files (filename stars with '.') will not be found in the result
524
-
525
- :param recursive: If False, `**` will not search directory recursively
526
- :param missing_ok: If False and target path doesn't match any file,
527
- raise FileNotFoundError
528
- :returns: A list contains paths match `pathname`
529
- """
530
- return list(fs_iglob(path=path, recursive=recursive, missing_ok=missing_ok))
531
-
532
-
533
- def fs_glob_stat(
534
- path: PathLike, recursive: bool = True, missing_ok: bool = True
535
- ) -> Iterator[FileEntry]:
536
- """Return a list contains tuples of path and file stat,
537
- in ascending alphabetical order, in which path matches glob pattern
538
-
539
- 1. If doesn't match any path, return empty list
540
- Notice: ``glob.glob`` in standard library returns ['a/'] instead of empty list
541
- when pathname is like `a/**`, recursive is True and directory 'a' doesn't exist.
542
- fs_glob behaves like ``glob.glob`` in standard library under such circumstance.
543
- 2. No guarantee that each path in result is different, which means:
544
- Assume there exists a path `/a/b/c/b/d.txt`
545
- use path pattern like `/**/b/**/*.txt` to glob,
546
- the path above will be returned twice.
547
- 3. `**` will match any matched file, directory, symlink and '' by default,
548
- when recursive is `True`
549
- 4. fs_glob returns same as glob.glob(pathname, recursive=True)
550
- in ascending alphabetical order.
551
- 5. Hidden files (filename stars with '.') will not be found in the result
552
-
553
- :param recursive: If False, `**` will not search directory recursively
554
- :param missing_ok: If False and target path doesn't match any file,
555
- raise FileNotFoundError
556
- :returns: A list contains tuples of path and file stat,
557
- in which paths match `pathname`
558
- """
559
- for path in fs_iglob(path=path, recursive=recursive, missing_ok=missing_ok):
560
- yield FileEntry(os.path.basename(path), path, _make_stat(os.lstat(path)))
561
-
562
-
563
- def fs_resolve(path: PathLike) -> str:
564
- """Equal to fs_realpath, return the real path of given path
565
-
566
- :param path: Given path
567
- :returns: Real path of given path
568
- """
569
- return FSPath(path).realpath()
570
-
571
-
572
- def fs_makedirs(path: PathLike, exist_ok: bool = False):
573
- """
574
- make a directory on fs, including parent directory
575
-
576
- If there exists a file on the path, raise FileExistsError
577
-
578
- :param path: Given path
579
- :param exist_ok: If False and target directory exists, raise FileExistsError
580
- :raises: FileExistsError
581
- """
582
- return FSPath(path).mkdir(parents=True, exist_ok=exist_ok)
583
-
584
-
585
- def fs_lstat(path: PathLike) -> StatResult:
586
- """
587
- Like Path.stat() but, if the path points to a symbolic link,
588
- return the symbolic link’s information rather than its target’s.
589
-
590
- :param path: Given path
591
- :returns: StatResult
592
- """
593
- return FSPath(path).lstat()
594
-
595
-
596
- def fs_rename(src_path: PathLike, dst_path: PathLike, overwrite: bool = True) -> None:
597
- """
598
- rename file on fs
599
-
600
- :param src_path: Given path
601
- :param dst_path: Given destination path
602
- :param overwrite: whether or not overwrite file when exists
603
- """
604
- FSPath(src_path).rename(dst_path, overwrite)
605
-
606
-
607
- def fs_move(src_path: PathLike, dst_path: PathLike, overwrite: bool = True) -> None:
608
- """
609
- rename file on fs
610
-
611
- :param src_path: Given path
612
- :param dst_path: Given destination path
613
- :param overwrite: whether or not overwrite file when exists
614
- """
615
- return fs_rename(src_path, dst_path, overwrite)
616
-
617
-
618
- def fs_open(path: PathLike, mode: str = "r", **kwargs) -> IO:
619
- """
620
- Open file on fs
621
-
622
- :param path: Given path
623
- :param mode: File open mode, like built-in open function
624
- :param buffering: Buffering policy, like built-in open function
625
- :returns: A file-like object
626
- """
627
- return FSPath(path).open(mode, **kwargs)