megfile 3.1.0.post2__py3-none-any.whl → 3.1.2__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 (55) hide show
  1. docs/conf.py +2 -4
  2. megfile/__init__.py +394 -203
  3. megfile/cli.py +258 -238
  4. megfile/config.py +25 -21
  5. megfile/errors.py +124 -114
  6. megfile/fs.py +174 -140
  7. megfile/fs_path.py +462 -354
  8. megfile/hdfs.py +133 -101
  9. megfile/hdfs_path.py +290 -236
  10. megfile/http.py +15 -14
  11. megfile/http_path.py +111 -107
  12. megfile/interfaces.py +70 -65
  13. megfile/lib/base_prefetch_reader.py +94 -69
  14. megfile/lib/combine_reader.py +13 -12
  15. megfile/lib/compare.py +17 -13
  16. megfile/lib/compat.py +1 -5
  17. megfile/lib/fnmatch.py +29 -30
  18. megfile/lib/glob.py +54 -55
  19. megfile/lib/hdfs_prefetch_reader.py +40 -25
  20. megfile/lib/hdfs_tools.py +1 -3
  21. megfile/lib/http_prefetch_reader.py +69 -46
  22. megfile/lib/joinpath.py +5 -5
  23. megfile/lib/lazy_handler.py +7 -3
  24. megfile/lib/s3_buffered_writer.py +61 -52
  25. megfile/lib/s3_cached_handler.py +14 -13
  26. megfile/lib/s3_limited_seekable_writer.py +38 -28
  27. megfile/lib/s3_memory_handler.py +35 -29
  28. megfile/lib/s3_pipe_handler.py +25 -24
  29. megfile/lib/s3_prefetch_reader.py +71 -52
  30. megfile/lib/s3_share_cache_reader.py +37 -24
  31. megfile/lib/shadow_handler.py +8 -3
  32. megfile/lib/stdio_handler.py +9 -8
  33. megfile/lib/url.py +3 -3
  34. megfile/pathlike.py +259 -228
  35. megfile/s3.py +220 -153
  36. megfile/s3_path.py +977 -802
  37. megfile/sftp.py +190 -156
  38. megfile/sftp_path.py +540 -450
  39. megfile/smart.py +397 -330
  40. megfile/smart_path.py +100 -105
  41. megfile/stdio.py +10 -9
  42. megfile/stdio_path.py +32 -35
  43. megfile/utils/__init__.py +75 -54
  44. megfile/utils/mutex.py +11 -14
  45. megfile/version.py +1 -1
  46. {megfile-3.1.0.post2.dist-info → megfile-3.1.2.dist-info}/METADATA +5 -8
  47. megfile-3.1.2.dist-info/RECORD +55 -0
  48. {megfile-3.1.0.post2.dist-info → megfile-3.1.2.dist-info}/WHEEL +1 -1
  49. scripts/convert_results_to_sarif.py +45 -78
  50. scripts/generate_file.py +140 -64
  51. megfile-3.1.0.post2.dist-info/RECORD +0 -55
  52. {megfile-3.1.0.post2.dist-info → megfile-3.1.2.dist-info}/LICENSE +0 -0
  53. {megfile-3.1.0.post2.dist-info → megfile-3.1.2.dist-info}/LICENSE.pyre +0 -0
  54. {megfile-3.1.0.post2.dist-info → megfile-3.1.2.dist-info}/entry_points.txt +0 -0
  55. {megfile-3.1.0.post2.dist-info → megfile-3.1.2.dist-info}/top_level.txt +0 -0
megfile/sftp.py CHANGED
@@ -1,212 +1,232 @@
1
1
  from typing import IO, BinaryIO, Callable, Iterator, List, Optional, Tuple
2
2
 
3
3
  from megfile.interfaces import FileEntry, PathLike, StatResult
4
- from megfile.sftp_path import SftpPath, is_sftp, sftp_concat, sftp_download, sftp_glob, sftp_glob_stat, sftp_iglob, sftp_lstat, sftp_path_join, sftp_readlink, sftp_resolve, sftp_upload
4
+ from megfile.sftp_path import (
5
+ SftpPath,
6
+ is_sftp,
7
+ sftp_concat,
8
+ sftp_download,
9
+ sftp_glob,
10
+ sftp_glob_stat,
11
+ sftp_iglob,
12
+ sftp_lstat,
13
+ sftp_path_join,
14
+ sftp_readlink,
15
+ sftp_resolve,
16
+ sftp_upload,
17
+ )
5
18
 
6
19
  __all__ = [
7
- 'is_sftp',
8
- 'sftp_readlink',
9
- 'sftp_glob',
10
- 'sftp_iglob',
11
- 'sftp_glob_stat',
12
- 'sftp_resolve',
13
- 'sftp_download',
14
- 'sftp_upload',
15
- 'sftp_path_join',
16
- 'sftp_concat',
17
- 'sftp_lstat',
18
- 'sftp_exists',
19
- 'sftp_getmtime',
20
- 'sftp_getsize',
21
- 'sftp_isdir',
22
- 'sftp_isfile',
23
- 'sftp_listdir',
24
- 'sftp_load_from',
25
- 'sftp_makedirs',
26
- 'sftp_realpath',
27
- 'sftp_rename',
28
- 'sftp_move',
29
- 'sftp_remove',
30
- 'sftp_scan',
31
- 'sftp_scan_stat',
32
- 'sftp_scandir',
33
- 'sftp_stat',
34
- 'sftp_unlink',
35
- 'sftp_walk',
36
- 'sftp_getmd5',
37
- 'sftp_symlink',
38
- 'sftp_islink',
39
- 'sftp_save_as',
40
- 'sftp_open',
41
- 'sftp_chmod',
42
- 'sftp_absolute',
43
- 'sftp_rmdir',
44
- 'sftp_copy',
45
- 'sftp_sync',
20
+ "is_sftp",
21
+ "sftp_readlink",
22
+ "sftp_glob",
23
+ "sftp_iglob",
24
+ "sftp_glob_stat",
25
+ "sftp_resolve",
26
+ "sftp_download",
27
+ "sftp_upload",
28
+ "sftp_path_join",
29
+ "sftp_concat",
30
+ "sftp_lstat",
31
+ "sftp_exists",
32
+ "sftp_getmtime",
33
+ "sftp_getsize",
34
+ "sftp_isdir",
35
+ "sftp_isfile",
36
+ "sftp_listdir",
37
+ "sftp_load_from",
38
+ "sftp_makedirs",
39
+ "sftp_realpath",
40
+ "sftp_rename",
41
+ "sftp_move",
42
+ "sftp_remove",
43
+ "sftp_scan",
44
+ "sftp_scan_stat",
45
+ "sftp_scandir",
46
+ "sftp_stat",
47
+ "sftp_unlink",
48
+ "sftp_walk",
49
+ "sftp_getmd5",
50
+ "sftp_symlink",
51
+ "sftp_islink",
52
+ "sftp_save_as",
53
+ "sftp_open",
54
+ "sftp_chmod",
55
+ "sftp_absolute",
56
+ "sftp_rmdir",
57
+ "sftp_copy",
58
+ "sftp_sync",
46
59
  ]
47
60
 
48
61
 
49
62
  def sftp_exists(path: PathLike, followlinks: bool = False) -> bool:
50
- '''
63
+ """
51
64
  Test if the path exists
52
65
 
53
66
  :param path: Given path
54
67
  :param followlinks: False if regard symlink as file, else True
55
68
  :returns: True if the path exists, else False
56
69
 
57
- '''
70
+ """
58
71
  return SftpPath(path).exists(followlinks)
59
72
 
60
73
 
61
74
  def sftp_getmtime(path: PathLike, follow_symlinks: bool = False) -> float:
62
- '''
75
+ """
63
76
  Get last-modified time of the file on the given path (in Unix timestamp format).
64
- If the path is an existent directory, return the latest modified time of all file in it.
77
+
78
+ If the path is an existent directory,
79
+ return the latest modified time of all file in it.
65
80
 
66
81
  :param path: Given path
67
82
  :returns: last-modified time
68
- '''
83
+ """
69
84
  return SftpPath(path).getmtime(follow_symlinks)
70
85
 
71
86
 
72
87
  def sftp_getsize(path: PathLike, follow_symlinks: bool = False) -> int:
73
- '''
88
+ """
74
89
  Get file size on the given file path (in bytes).
75
- If the path in a directory, return the sum of all file size in it, including file in subdirectories (if exist).
76
- The result excludes the size of directory itself. In other words, return 0 Byte on an empty directory path.
90
+
91
+ If the path in a directory, return the sum of all file size in it,
92
+ including file in subdirectories (if exist).
93
+
94
+ The result excludes the size of directory itself. In other words,
95
+ return 0 Byte on an empty directory path.
77
96
 
78
97
  :param path: Given path
79
98
  :returns: File size
80
99
 
81
- '''
100
+ """
82
101
  return SftpPath(path).getsize(follow_symlinks)
83
102
 
84
103
 
85
104
  def sftp_isdir(path: PathLike, followlinks: bool = False) -> bool:
86
- '''
105
+ """
87
106
  Test if a path is directory
88
107
 
89
108
  .. note::
90
109
 
91
- The difference between this function and ``os.path.isdir`` is that this function regard symlink as file
110
+ The difference between this function and ``os.path.isdir`` is that
111
+ this function regard symlink as file
92
112
 
93
113
  :param path: Given path
94
114
  :param followlinks: False if regard symlink as file, else True
95
115
  :returns: True if the path is a directory, else False
96
116
 
97
- '''
117
+ """
98
118
  return SftpPath(path).is_dir(followlinks)
99
119
 
100
120
 
101
121
  def sftp_isfile(path: PathLike, followlinks: bool = False) -> bool:
102
- '''
122
+ """
103
123
  Test if a path is file
104
124
 
105
125
  .. note::
106
126
 
107
- The difference between this function and ``os.path.isfile`` is that this function regard symlink as file
127
+ The difference between this function and ``os.path.isfile`` is that
128
+ this function regard symlink as file
108
129
 
109
130
  :param path: Given path
110
131
  :param followlinks: False if regard symlink as file, else True
111
132
  :returns: True if the path is a file, else False
112
133
 
113
- '''
134
+ """
114
135
  return SftpPath(path).is_file(followlinks)
115
136
 
116
137
 
117
138
  def sftp_listdir(path: PathLike) -> List[str]:
118
- '''
119
- Get all contents of given sftp path. The result is in ascending alphabetical order.
139
+ """
140
+ Get all contents of given sftp path.
141
+ The result is in ascending alphabetical order.
120
142
 
121
143
  :param path: Given path
122
144
  :returns: All contents have in the path in ascending alphabetical order
123
- '''
145
+ """
124
146
  return SftpPath(path).listdir()
125
147
 
126
148
 
127
149
  def sftp_load_from(path: PathLike) -> BinaryIO:
128
- '''Read all content on specified path and write into memory
150
+ """Read all content on specified path and write into memory
129
151
 
130
152
  User should close the BinaryIO manually
131
153
 
132
154
  :param path: Given path
133
155
  :returns: Binary stream
134
- '''
156
+ """
135
157
  return SftpPath(path).load()
136
158
 
137
159
 
138
160
  def sftp_makedirs(
139
- path: PathLike,
140
- mode=0o777,
141
- parents: bool = False,
142
- exist_ok: bool = False):
143
- '''
161
+ path: PathLike, mode=0o777, parents: bool = False, exist_ok: bool = False
162
+ ):
163
+ """
144
164
  make a directory on sftp, including parent directory.
145
165
  If there exists a file on the path, raise FileExistsError
146
166
 
147
167
  :param path: Given path
148
- :param mode: If mode is given, it is combined with the process’ umask value to determine the file mode and access flags.
149
- :param parents: If parents is true, any missing parents of this path are created as needed;
150
- If parents is false (the default), a missing parent raises FileNotFoundError.
168
+ :param mode: If mode is given, it is combined with the process’ umask value to
169
+ determine the file mode and access flags.
170
+ :param parents: If parents is true, any missing parents of this path
171
+ are created as needed; If parents is false (the default),
172
+ a missing parent raises FileNotFoundError.
151
173
  :param exist_ok: If False and target directory exists, raise FileExistsError
152
174
 
153
175
  :raises: FileExistsError
154
- '''
176
+ """
155
177
  return SftpPath(path).mkdir(mode, parents, exist_ok)
156
178
 
157
179
 
158
180
  def sftp_realpath(path: PathLike) -> str:
159
- '''Return the real path of given path
181
+ """Return the real path of given path
160
182
 
161
183
  :param path: Given path
162
184
  :returns: Real path of given path
163
- '''
185
+ """
164
186
  return SftpPath(path).realpath()
165
187
 
166
188
 
167
189
  def sftp_rename(
168
- src_path: PathLike,
169
- dst_path: PathLike,
170
- overwrite: bool = True) -> 'SftpPath':
171
- '''
190
+ src_path: PathLike, dst_path: PathLike, overwrite: bool = True
191
+ ) -> "SftpPath":
192
+ """
172
193
  rename file on sftp
173
194
 
174
195
  :param src_path: Given path
175
196
  :param dst_path: Given destination path
176
197
  :param overwrite: whether or not overwrite file when exists
177
- '''
198
+ """
178
199
  return SftpPath(src_path).rename(dst_path, overwrite)
179
200
 
180
201
 
181
202
  def sftp_move(
182
- src_path: PathLike,
183
- dst_path: PathLike,
184
- overwrite: bool = True) -> 'SftpPath':
185
- '''
203
+ src_path: PathLike, dst_path: PathLike, overwrite: bool = True
204
+ ) -> "SftpPath":
205
+ """
186
206
  move file on sftp
187
207
 
188
208
  :param src_path: Given path
189
209
  :param dst_path: Given destination path
190
210
  :param overwrite: whether or not overwrite file when exists
191
- '''
211
+ """
192
212
  return SftpPath(src_path).replace(dst_path, overwrite)
193
213
 
194
214
 
195
215
  def sftp_remove(path: PathLike, missing_ok: bool = False) -> None:
196
- '''
216
+ """
197
217
  Remove the file or directory on sftp
198
218
 
199
219
  :param path: Given path
200
- :param missing_ok: if False and target file/directory not exists, raise FileNotFoundError
201
- '''
220
+ :param missing_ok: if False and target file/directory not exists,
221
+ raise FileNotFoundError
222
+ """
202
223
  return SftpPath(path).remove(missing_ok)
203
224
 
204
225
 
205
226
  def sftp_scan(
206
- path: PathLike,
207
- missing_ok: bool = True,
208
- followlinks: bool = False) -> Iterator[str]:
209
- '''
227
+ path: PathLike, missing_ok: bool = True, followlinks: bool = False
228
+ ) -> Iterator[str]:
229
+ """
210
230
  Iteratively traverse only files in given directory, in alphabetical order.
211
231
  Every iteration on generator yields a path string.
212
232
 
@@ -215,86 +235,91 @@ def sftp_scan(
215
235
  If path is a bucket path, return all file paths in the bucket
216
236
 
217
237
  :param path: Given path
218
- :param missing_ok: If False and there's no file in the directory, raise FileNotFoundError
238
+ :param missing_ok: If False and there's no file in the directory,
239
+ raise FileNotFoundError
219
240
  :returns: A file path generator
220
- '''
241
+ """
221
242
  return SftpPath(path).scan(missing_ok, followlinks)
222
243
 
223
244
 
224
245
  def sftp_scan_stat(
225
- path: PathLike,
226
- missing_ok: bool = True,
227
- followlinks: bool = False) -> Iterator[FileEntry]:
228
- '''
246
+ path: PathLike, missing_ok: bool = True, followlinks: bool = False
247
+ ) -> Iterator[FileEntry]:
248
+ """
229
249
  Iteratively traverse only files in given directory, in alphabetical order.
230
250
  Every iteration on generator yields a tuple of path string and file stat
231
251
 
232
252
  :param path: Given path
233
- :param missing_ok: If False and there's no file in the directory, raise FileNotFoundError
253
+ :param missing_ok: If False and there's no file in the directory,
254
+ raise FileNotFoundError
234
255
  :returns: A file path generator
235
- '''
256
+ """
236
257
  return SftpPath(path).scan_stat(missing_ok, followlinks)
237
258
 
238
259
 
239
260
  def sftp_scandir(path: PathLike) -> Iterator[FileEntry]:
240
- '''
261
+ """
241
262
  Get all content of given file path.
242
263
 
243
264
  :param path: Given path
244
265
  :returns: An iterator contains all contents have prefix path
245
- '''
266
+ """
246
267
  return SftpPath(path).scandir()
247
268
 
248
269
 
249
270
  def sftp_stat(path: PathLike, follow_symlinks=True) -> StatResult:
250
- '''
251
- Get StatResult of file on sftp, including file size and mtime, referring to fs_getsize and fs_getmtime
271
+ """
272
+ Get StatResult of file on sftp, including file size and mtime,
273
+ referring to fs_getsize and fs_getmtime
252
274
 
253
275
  :param path: Given path
254
276
  :returns: StatResult
255
- '''
277
+ """
256
278
  return SftpPath(path).stat(follow_symlinks)
257
279
 
258
280
 
259
281
  def sftp_unlink(path: PathLike, missing_ok: bool = False) -> None:
260
- '''
282
+ """
261
283
  Remove the file on sftp
262
284
 
263
285
  :param path: Given path
264
286
  :param missing_ok: if False and target file not exists, raise FileNotFoundError
265
- '''
287
+ """
266
288
  return SftpPath(path).unlink(missing_ok)
267
289
 
268
290
 
269
291
  def sftp_walk(
270
- path: PathLike,
271
- followlinks: bool = False
292
+ path: PathLike, followlinks: bool = False
272
293
  ) -> Iterator[Tuple[str, List[str], List[str]]]:
273
- '''
294
+ """
274
295
  Generate the file names in a directory tree by walking the tree top-down.
275
296
  For each directory in the tree rooted at directory path (including path itself),
276
297
  it yields a 3-tuple (root, dirs, files).
277
298
 
278
- root: a string of current path
279
- dirs: name list of subdirectories (excluding '.' and '..' if they exist) in 'root'. The list is sorted by ascending alphabetical order
280
- files: name list of non-directory files (link is regarded as file) in 'root'. The list is sorted by ascending alphabetical order
299
+ - root: a string of current path
300
+ - dirs: name list of subdirectories (excluding '.' and '..' if they exist)
301
+ in 'root'. The list is sorted by ascending alphabetical order
302
+ - files: name list of non-directory files (link is regarded as file) in 'root'.
303
+ The list is sorted by ascending alphabetical order
281
304
 
282
- If path not exists, or path is a file (link is regarded as file), return an empty generator
305
+ If path not exists, or path is a file (link is regarded as file),
306
+ return an empty generator
283
307
 
284
308
  .. note::
285
309
 
286
- Be aware that setting ``followlinks`` to True can lead to infinite recursion if a link points to a parent directory of itself. fs_walk() does not keep track of the directories it visited already.
310
+ Be aware that setting ``followlinks`` to True can lead to infinite recursion
311
+ if a link points to a parent directory of itself. fs_walk() does not keep
312
+ track of the directories it visited already.
287
313
 
288
314
  :param path: Given path
289
315
  :param followlinks: False if regard symlink as file, else True
290
316
  :returns: A 3-tuple generator
291
- '''
317
+ """
292
318
  return SftpPath(path).walk(followlinks)
293
319
 
294
320
 
295
- def sftp_getmd5(
296
- path: PathLike, recalculate: bool = False, followlinks: bool = True):
297
- '''
321
+ def sftp_getmd5(path: PathLike, recalculate: bool = False, followlinks: bool = True):
322
+ """
298
323
  Calculate the md5 value of the file
299
324
 
300
325
  :param path: Given path
@@ -302,97 +327,104 @@ def sftp_getmd5(
302
327
  :param followlinks: Ignore this parameter, just for compatibility
303
328
 
304
329
  returns: md5 of file
305
- '''
330
+ """
306
331
  return SftpPath(path).md5(recalculate, followlinks)
307
332
 
308
333
 
309
334
  def sftp_symlink(src_path: PathLike, dst_path: PathLike) -> None:
310
- '''
335
+ """
311
336
  Create a symbolic link pointing to src_path named dst_path.
312
337
 
313
338
  :param src_path: Given path
314
339
  :param dst_path: Destination path
315
- '''
340
+ """
316
341
  return SftpPath(src_path).symlink(dst_path)
317
342
 
318
343
 
319
344
  def sftp_islink(path: PathLike) -> bool:
320
- '''Test whether a path is a symbolic link
345
+ """Test whether a path is a symbolic link
321
346
 
322
347
  :param path: Given path
323
348
  :return: If path is a symbolic link return True, else False
324
349
  :rtype: bool
325
- '''
350
+ """
326
351
  return SftpPath(path).is_symlink()
327
352
 
328
353
 
329
354
  def sftp_save_as(file_object: BinaryIO, path: PathLike):
330
- '''Write the opened binary stream to path
355
+ """Write the opened binary stream to path
331
356
  If parent directory of path doesn't exist, it will be created.
332
357
 
333
358
  :param path: Given path
334
359
  :param file_object: stream to be read
335
- '''
360
+ """
336
361
  return SftpPath(path).save(file_object)
337
362
 
338
363
 
339
364
  def sftp_open(
340
- path: PathLike,
341
- mode: str = 'r',
342
- buffering=-1,
343
- encoding: Optional[str] = None,
344
- errors: Optional[str] = None,
345
- **kwargs) -> IO:
346
- '''Open a file on the path.
365
+ path: PathLike,
366
+ mode: str = "r",
367
+ buffering=-1,
368
+ encoding: Optional[str] = None,
369
+ errors: Optional[str] = None,
370
+ **kwargs,
371
+ ) -> IO:
372
+ """Open a file on the path.
347
373
 
348
374
  :param path: Given path
349
375
  :param mode: Mode to open file
350
- :param buffering: buffering is an optional integer used to set the buffering policy.
351
- :param encoding: encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode.
352
- :param errors: errors is an optional string that specifies how encoding and decoding errors are to be handled—this cannot be used in binary mode.
376
+ :param buffering: buffering is an optional integer used to
377
+ set the buffering policy.
378
+ :param encoding: encoding is the name of the encoding used to decode or encode
379
+ the file. This should only be used in text mode.
380
+ :param errors: errors is an optional string that specifies how encoding and
381
+ decoding errors are to be handled—this cannot be used in binary mode.
353
382
  :returns: File-Like object
354
- '''
383
+ """
355
384
  return SftpPath(path).open(mode, buffering, encoding, errors)
356
385
 
357
386
 
358
387
  def sftp_chmod(path: PathLike, mode: int, follow_symlinks: bool = True):
359
- '''
388
+ """
360
389
  Change the file mode and permissions, like os.chmod().
361
390
 
362
391
  :param path: Given path
363
392
  :param mode: the file mode you want to change
364
393
  :param followlinks: Ignore this parameter, just for compatibility
365
- '''
394
+ """
366
395
  return SftpPath(path).chmod(mode, follow_symlinks)
367
396
 
368
397
 
369
- def sftp_absolute(path: PathLike) -> 'SftpPath':
370
- '''
371
- Make the path absolute, without normalization or resolving symlinks. Returns a new path object
372
- '''
398
+ def sftp_absolute(path: PathLike) -> "SftpPath":
399
+ """
400
+ Make the path absolute, without normalization or resolving symlinks.
401
+ Returns a new path object
402
+ """
373
403
  return SftpPath(path).absolute()
374
404
 
375
405
 
376
406
  def sftp_rmdir(path: PathLike):
377
- '''
407
+ """
378
408
  Remove this directory. The directory must be empty.
379
- '''
409
+ """
380
410
  return SftpPath(path).rmdir()
381
411
 
382
412
 
383
413
  def sftp_copy(
384
- src_path: PathLike,
385
- dst_path: PathLike,
386
- callback: Optional[Callable[[int], None]] = None,
387
- followlinks: bool = False,
388
- overwrite: bool = True):
414
+ src_path: PathLike,
415
+ dst_path: PathLike,
416
+ callback: Optional[Callable[[int], None]] = None,
417
+ followlinks: bool = False,
418
+ overwrite: bool = True,
419
+ ):
389
420
  """
390
421
  Copy the file to the given destination path.
391
422
 
392
423
  :param src_path: Given path
393
424
  :param dst_path: The destination path to copy the file to.
394
- :param callback: An optional callback function that takes an integer parameter and is called
395
- periodically during the copy operation to report the number of bytes copied.
425
+ :param callback: An optional callback function that takes an integer parameter
426
+ and is called periodically during the copy operation to report the number
427
+ of bytes copied.
396
428
  :param followlinks: Whether to follow symbolic links when copying directories.
397
429
  :raises IsADirectoryError: If the source is a directory.
398
430
  :raises OSError: If there is an error copying the file.
@@ -401,17 +433,19 @@ def sftp_copy(
401
433
 
402
434
 
403
435
  def sftp_sync(
404
- src_path: PathLike,
405
- dst_path: PathLike,
406
- followlinks: bool = False,
407
- force: bool = False,
408
- overwrite: bool = True):
409
- '''Copy file/directory on src_url to dst_url
436
+ src_path: PathLike,
437
+ dst_path: PathLike,
438
+ followlinks: bool = False,
439
+ force: bool = False,
440
+ overwrite: bool = True,
441
+ ):
442
+ """Copy file/directory on src_url to dst_url
410
443
 
411
444
  :param src_path: Given path
412
445
  :param dst_url: Given destination path
413
446
  :param followlinks: False if regard symlink as file, else True
414
- :param force: Sync file forcible, do not ignore same files, priority is higher than 'overwrite', default is False
447
+ :param force: Sync file forcible, do not ignore same files,
448
+ priority is higher than 'overwrite', default is False
415
449
  :param overwrite: whether or not overwrite file when exists, default is True
416
- '''
450
+ """
417
451
  return SftpPath(src_path).sync(dst_path, followlinks, force, overwrite)