megfile 3.0.6.post1__py3-none-any.whl → 3.1.0.post1__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 (49) hide show
  1. docs/conf.py +67 -0
  2. megfile/cli.py +16 -16
  3. megfile/config.py +37 -6
  4. megfile/errors.py +26 -20
  5. megfile/fs.py +13 -8
  6. megfile/fs_path.py +69 -49
  7. megfile/hdfs.py +13 -8
  8. megfile/hdfs_path.py +49 -41
  9. megfile/http.py +1 -1
  10. megfile/http_path.py +35 -28
  11. megfile/interfaces.py +119 -48
  12. megfile/lib/base_prefetch_reader.py +9 -8
  13. megfile/lib/combine_reader.py +7 -7
  14. megfile/lib/fnmatch.py +2 -2
  15. megfile/lib/glob.py +3 -3
  16. megfile/lib/hdfs_prefetch_reader.py +2 -1
  17. megfile/lib/http_prefetch_reader.py +3 -2
  18. megfile/lib/lazy_handler.py +6 -5
  19. megfile/lib/s3_buffered_writer.py +8 -7
  20. megfile/lib/s3_cached_handler.py +3 -4
  21. megfile/lib/s3_limited_seekable_writer.py +5 -3
  22. megfile/lib/s3_memory_handler.py +10 -6
  23. megfile/lib/s3_pipe_handler.py +1 -1
  24. megfile/lib/s3_prefetch_reader.py +7 -5
  25. megfile/lib/s3_share_cache_reader.py +2 -2
  26. megfile/lib/shadow_handler.py +5 -5
  27. megfile/lib/stdio_handler.py +3 -3
  28. megfile/pathlike.py +156 -170
  29. megfile/s3.py +19 -13
  30. megfile/s3_path.py +98 -83
  31. megfile/sftp.py +25 -16
  32. megfile/sftp_path.py +109 -94
  33. megfile/smart.py +38 -28
  34. megfile/smart_path.py +6 -6
  35. megfile/stdio.py +3 -3
  36. megfile/stdio_path.py +5 -5
  37. megfile/utils/__init__.py +8 -27
  38. megfile/version.py +1 -1
  39. {megfile-3.0.6.post1.dist-info → megfile-3.1.0.post1.dist-info}/METADATA +4 -5
  40. megfile-3.1.0.post1.dist-info/RECORD +55 -0
  41. {megfile-3.0.6.post1.dist-info → megfile-3.1.0.post1.dist-info}/WHEEL +1 -1
  42. megfile-3.1.0.post1.dist-info/top_level.txt +7 -0
  43. scripts/convert_results_to_sarif.py +124 -0
  44. scripts/generate_file.py +268 -0
  45. megfile-3.0.6.post1.dist-info/RECORD +0 -52
  46. megfile-3.0.6.post1.dist-info/top_level.txt +0 -1
  47. {megfile-3.0.6.post1.dist-info → megfile-3.1.0.post1.dist-info}/LICENSE +0 -0
  48. {megfile-3.0.6.post1.dist-info → megfile-3.1.0.post1.dist-info}/LICENSE.pyre +0 -0
  49. {megfile-3.0.6.post1.dist-info → megfile-3.1.0.post1.dist-info}/entry_points.txt +0 -0
megfile/pathlike.py CHANGED
@@ -1,36 +1,18 @@
1
+ # pyre-ignore-all-errors[16]
1
2
  import os
2
3
  import stat
3
4
  from collections.abc import Sequence
4
5
  from enum import Enum
5
- from functools import wraps
6
- from typing import IO, Any, AnyStr, BinaryIO, Callable, Iterator, List, NamedTuple, Optional, Tuple, Union
6
+ from functools import cached_property
7
+ from typing import IO, Any, BinaryIO, Iterator, List, NamedTuple, Optional, Tuple, Type, TypeVar, Union
7
8
 
8
9
  from megfile.lib.compat import PathLike as _PathLike
9
10
  from megfile.lib.compat import fspath
10
11
  from megfile.lib.fnmatch import _compile_pattern
11
12
  from megfile.lib.joinpath import uri_join
12
- from megfile.utils import cachedproperty, classproperty
13
+ from megfile.utils import classproperty
13
14
 
14
- # Python 3.5+ compatible
15
- '''
16
- class StatResult(NamedTuple):
17
-
18
- size: int = 0
19
- ctime: float = 0.0
20
- mtime: float = 0.0
21
- isdir: bool = False
22
- islnk: bool = False
23
- extra: Any = None # raw stat info
24
-
25
- in Python 3.6+
26
- '''
27
-
28
- _StatResult = NamedTuple(
29
- 'StatResult', [
30
- ('size', int), ('ctime', float), ('mtime', float), ('isdir', bool),
31
- ('islnk', bool), ('extra', Any)
32
- ])
33
- _StatResult.__new__.__defaults__ = (0, 0.0, 0.0, False, False, None)
15
+ Self = TypeVar('Self')
34
16
 
35
17
 
36
18
  class Access(Enum):
@@ -38,7 +20,13 @@ class Access(Enum):
38
20
  WRITE = 2
39
21
 
40
22
 
41
- class StatResult(_StatResult):
23
+ class StatResult(NamedTuple):
24
+ size: int = 0
25
+ ctime: float = 0.0
26
+ mtime: float = 0.0
27
+ isdir: bool = False
28
+ islnk: bool = False
29
+ extra: Any = None
42
30
 
43
31
  def is_file(self) -> bool:
44
32
  return not self.isdir or self.islnk
@@ -195,21 +183,12 @@ class StatResult(_StatResult):
195
183
  return 0
196
184
 
197
185
 
198
- '''
199
186
  class FileEntry(NamedTuple):
200
187
 
201
188
  name: str
189
+ path: str
202
190
  stat: StatResult
203
191
 
204
- in Python 3.6+
205
- '''
206
-
207
- _FileEntry = NamedTuple(
208
- 'FileEntry', [('name', str), ('path', str), ('stat', StatResult)])
209
-
210
-
211
- class FileEntry(_FileEntry):
212
-
213
192
  def inode(self) -> Optional[Union[int, str]]:
214
193
  return self.stat.st_ino
215
194
 
@@ -223,16 +202,6 @@ class FileEntry(_FileEntry):
223
202
  return self.stat.is_symlink()
224
203
 
225
204
 
226
- def method_not_implemented(func):
227
-
228
- @wraps(func)
229
- def wrapper(self, *args, **kwargs):
230
- raise NotImplementedError(
231
- 'method %r not implemented: %r' % (func.__name__, self))
232
-
233
- return wrapper
234
-
235
-
236
205
  class BasePath:
237
206
 
238
207
  def __init__(self, path: "PathLike"):
@@ -256,142 +225,160 @@ class BasePath:
256
225
  def __eq__(self, other_path: "BasePath") -> bool:
257
226
  return fspath(self) == fspath(other_path)
258
227
 
259
- # pytype: disable=bad-return-type
260
-
261
- @method_not_implemented
262
- def is_dir(self, followlinks: bool = False) -> bool: # type: ignore
228
+ def is_dir(self, followlinks: bool = False) -> bool:
263
229
  """Return True if the path points to a directory."""
230
+ raise NotImplementedError('method "is_dir" not implemented: %r' % self)
264
231
 
265
- @method_not_implemented
266
- def is_file(self, followlinks: bool = False) -> bool: # type: ignore
232
+ def is_file(self, followlinks: bool = False) -> bool:
267
233
  """Return True if the path points to a regular file."""
234
+ raise NotImplementedError('method "is_file" not implemented: %r' % self)
268
235
 
269
236
  def is_symlink(self) -> bool:
270
237
  return False
271
238
 
272
- @method_not_implemented
273
- def access(self, mode: Access) -> bool: # type: ignore
239
+ def access(self, mode: Access) -> bool:
274
240
  """Return True if the path has access permission described by mode."""
241
+ raise NotImplementedError('method "access" not implemented: %r' % self)
275
242
 
276
- @method_not_implemented
277
- def exists(self, followlinks: bool = False) -> bool: # type: ignore
243
+ def exists(self, followlinks: bool = False) -> bool:
278
244
  """Whether the path points to an existing file or directory."""
245
+ raise NotImplementedError('method "exists" not implemented: %r' % self)
279
246
 
280
- # listdir or iterdir?
281
- @method_not_implemented
282
- def listdir(self) -> List[str]: # type: ignore
247
+ def listdir(self) -> List[str]:
283
248
  """Return the names of the entries in the directory the path points to."""
249
+ raise NotImplementedError('method "listdir" not implemented: %r' % self)
284
250
 
285
- @method_not_implemented
286
- def scandir(self) -> Iterator[FileEntry]: # type: ignore
251
+ def scandir(self) -> Iterator[FileEntry]:
287
252
  """Return an iterator of FileEntry objects corresponding to the entries in the directory."""
253
+ raise NotImplementedError('method "scandir" not implemented: %r' % self)
288
254
 
289
- @method_not_implemented
290
- def getsize(self, follow_symlinks: bool = True) -> int: # type: ignore
255
+ def getsize(self, follow_symlinks: bool = True) -> int:
291
256
  """Return the size, in bytes."""
257
+ raise NotImplementedError('method "getsize" not implemented: %r' % self)
292
258
 
293
- @method_not_implemented
294
- def getmtime(self, follow_symlinks: bool = True) -> float: # type: ignore
259
+ def getmtime(self, follow_symlinks: bool = True) -> float:
295
260
  """Return the time of last modification."""
261
+ raise NotImplementedError(
262
+ 'method "getmtime" not implemented: %r' % self)
296
263
 
297
- @method_not_implemented
298
- def stat(self, follow_symlinks=True) -> StatResult: # type: ignore
264
+ def stat(self, follow_symlinks=True) -> StatResult:
299
265
  """Get the status of the path."""
266
+ raise NotImplementedError('method "stat" not implemented: %r' % self)
300
267
 
301
- @method_not_implemented
302
268
  def remove(self, missing_ok: bool = False) -> None:
303
269
  """Remove (delete) the file."""
270
+ raise NotImplementedError('method "remove" not implemented: %r' % self)
304
271
 
305
- @method_not_implemented
306
272
  def unlink(self, missing_ok: bool = False) -> None:
307
273
  """Remove (delete) the file."""
274
+ raise NotImplementedError('method "unlink" not implemented: %r' % self)
308
275
 
309
- @method_not_implemented
310
276
  def mkdir(
311
- self, mode=0o777, parents: bool = False,
277
+ self,
278
+ mode=0o777,
279
+ parents: bool = False,
312
280
  exist_ok: bool = False) -> None:
313
281
  """Create a directory."""
282
+ raise NotImplementedError('method "mkdir" not implemented: %r' % self)
314
283
 
315
- @method_not_implemented
316
284
  def rmdir(self) -> None:
317
285
  """Remove (delete) the directory."""
286
+ raise NotImplementedError('method "rmdir" not implemented: %r' % self)
318
287
 
319
- @method_not_implemented
320
- def open(self, mode: str = 'r', **kwargs) -> IO[AnyStr]: # type: ignore
288
+ def open(self, mode: str = 'r', **kwargs) -> IO:
321
289
  """Open the file with mode."""
290
+ raise NotImplementedError('method "open" not implemented: %r' % self)
322
291
 
323
- @method_not_implemented
324
- def walk(self, followlinks: bool = False
325
- ) -> Iterator[Tuple[str, List[str], List[str]]]: # type: ignore
292
+ def walk(
293
+ self,
294
+ followlinks: bool = False
295
+ ) -> Iterator[Tuple[str, List[str], List[str]]]:
326
296
  """Generate the file names in a directory tree by walking the tree."""
297
+ raise NotImplementedError('method "walk" not implemented: %r' % self)
327
298
 
328
- @method_not_implemented
329
- def scan(self, missing_ok: bool = True,
330
- followlinks: bool = False) -> Iterator[str]: # type: ignore
299
+ def scan(self,
300
+ missing_ok: bool = True,
301
+ followlinks: bool = False) -> Iterator[str]:
331
302
  """Iterate through the files in the directory."""
303
+ raise NotImplementedError('method "scan" not implemented: %r' % self)
332
304
 
333
- @method_not_implemented
334
- def scan_stat(self, missing_ok: bool = True, followlinks: bool = False
335
- ) -> Iterator[FileEntry]: # type: ignore
305
+ def scan_stat(self,
306
+ missing_ok: bool = True,
307
+ followlinks: bool = False) -> Iterator[FileEntry]:
336
308
  """Iterate through the files in the directory, with file stat."""
309
+ raise NotImplementedError(
310
+ 'method "scan_stat" not implemented: %r' % self)
337
311
 
338
- @method_not_implemented
339
- def glob(self, pattern, recursive: bool = True,
340
- missing_ok: bool = True) -> List['BasePath']: # type: ignore
312
+ def glob(
313
+ self: Self,
314
+ pattern: str,
315
+ recursive: bool = True,
316
+ missing_ok: bool = True) -> List[Self]:
341
317
  """Return files whose paths match the glob pattern."""
318
+ raise NotImplementedError('method "glob" not implemented: %r' % self)
342
319
 
343
- @method_not_implemented
344
- def iglob(self, pattern, recursive: bool = True,
345
- missing_ok: bool = True) -> Iterator['BasePath']: # type: ignore
320
+ def iglob(
321
+ self: Self,
322
+ pattern: str,
323
+ recursive: bool = True,
324
+ missing_ok: bool = True) -> Iterator[Self]:
346
325
  """Return an iterator of files whose paths match the glob pattern."""
326
+ raise NotImplementedError('method "iglob" not implemented: %r' % self)
347
327
 
348
- @method_not_implemented
349
328
  def glob_stat(
350
- self, pattern, recursive: bool = True,
351
- missing_ok: bool = True) -> Iterator[FileEntry]: # type: ignore
329
+ self,
330
+ pattern: str,
331
+ recursive: bool = True,
332
+ missing_ok: bool = True) -> Iterator[FileEntry]:
352
333
  """Return an iterator of files with stat whose paths match the glob pattern."""
334
+ raise NotImplementedError(
335
+ 'method "glob_stat" not implemented: %r' % self)
353
336
 
354
- @method_not_implemented
355
- def load(self) -> BinaryIO: # type: ignore
337
+ def load(self) -> BinaryIO:
356
338
  """Read all content in binary."""
339
+ raise NotImplementedError('method "load" not implemented: %r' % self)
357
340
 
358
- @method_not_implemented
359
341
  def save(self, file_object: BinaryIO):
360
342
  """Write the opened binary stream to the path."""
343
+ raise NotImplementedError('method "save" not implemented: %r' % self)
361
344
 
362
- @method_not_implemented
363
- def joinpath(self, *other_paths: "PathLike") -> 'BasePath': # type: ignore
345
+ def joinpath(self: Self, *other_paths: "PathLike") -> Self:
364
346
  """Join or or more path."""
347
+ raise NotImplementedError(
348
+ 'method "joinpath" not implemented: %r' % self)
365
349
 
366
- @method_not_implemented
367
- def abspath(self): # type: ignore
368
- """Return a normalized absolutized version of the path."""
350
+ def abspath(self):
351
+ """Return a normalized absolute version of the path."""
352
+ raise NotImplementedError('method "abspath" not implemented: %r' % self)
369
353
 
370
- @method_not_implemented
371
- def realpath(self): # type: ignore
354
+ def realpath(self):
372
355
  """Return the canonical path of the path."""
356
+ raise NotImplementedError(
357
+ 'method "realpath" not implemented: %r' % self)
373
358
 
374
- @method_not_implemented
375
- def relpath(self, start=None): # type: ignore
359
+ def relpath(self, start=None):
376
360
  """Return the relative path."""
361
+ raise NotImplementedError('method "relpath" not implemented: %r' % self)
377
362
 
378
- @method_not_implemented
379
- def is_absolute(self) -> bool: # type: ignore
363
+ def is_absolute(self) -> bool:
380
364
  """Return True if the path is an absolute pathname."""
365
+ raise NotImplementedError(
366
+ 'method "is_absolute" not implemented: %r' % self)
381
367
 
382
- @method_not_implemented
383
- def is_mount(self) -> bool: # type: ignore
368
+ def is_mount(self) -> bool:
384
369
  """Return True if the path is a mount point."""
370
+ raise NotImplementedError(
371
+ 'method "is_mount" not implemented: %r' % self)
385
372
 
386
- @method_not_implemented
387
- def resolve(self): # type: ignore
373
+ def resolve(self):
388
374
  """Alias of realpath."""
375
+ raise NotImplementedError('method "resolve" not implemented: %r' % self)
389
376
 
390
377
  def touch(self):
391
378
  with self.open('w'):
392
379
  pass
393
380
 
394
- # will be deleted in next version
381
+ # TODO: will be deleted in next version
395
382
  def is_link(self) -> bool:
396
383
  return self.is_symlink()
397
384
 
@@ -401,8 +388,6 @@ class BasePath:
401
388
  '''
402
389
  self.mkdir(parents=True, exist_ok=exist_ok)
403
390
 
404
- # pytype: enable=bad-return-type
405
-
406
391
 
407
392
  PathLike = Union[str, BasePath, _PathLike]
408
393
 
@@ -410,14 +395,14 @@ PathLike = Union[str, BasePath, _PathLike]
410
395
  class BaseURIPath(BasePath):
411
396
 
412
397
  # #####
413
- # Backwards compatible API, will be removed in megfile 1.0
398
+ # TODO: Backwards compatible API, will be removed in megfile 1.0
414
399
  @classmethod
415
400
  def get_protocol(self) -> Optional[str]:
416
401
  pass # pragma: no cover
417
402
 
418
403
  @classproperty
419
404
  def protocol(cls) -> str:
420
- return cls.get_protocol()
405
+ return cls.get_protocol() or ""
421
406
 
422
407
  def make_uri(self) -> str:
423
408
  return self.path_with_protocol
@@ -427,20 +412,20 @@ class BaseURIPath(BasePath):
427
412
 
428
413
  # #####
429
414
 
430
- @cachedproperty
415
+ @cached_property
431
416
  def path_with_protocol(self) -> str:
432
417
  '''Return path with protocol, like file:///root, s3://bucket/key'''
433
418
  path = self.path
434
- protocol_prefix = self.protocol + "://"
419
+ protocol_prefix = self.protocol + "://" # pyre-ignore[58]
435
420
  if path.startswith(protocol_prefix):
436
421
  return path
437
422
  return protocol_prefix + path.lstrip('/')
438
423
 
439
- @cachedproperty
424
+ @cached_property
440
425
  def path_without_protocol(self) -> str:
441
426
  '''Return path without protocol, example: if path is s3://bucket/key, return bucket/key'''
442
427
  path = self.path
443
- protocol_prefix = self.protocol + "://"
428
+ protocol_prefix = self.protocol + "://" # pyre-ignore[58]
444
429
  if path.startswith(protocol_prefix):
445
430
  path = path[len(protocol_prefix):]
446
431
  return path
@@ -449,25 +434,6 @@ class BaseURIPath(BasePath):
449
434
  '''Return a string representation of the path with forward slashes (/)'''
450
435
  return self.path_with_protocol
451
436
 
452
- @classmethod
453
- def from_path(cls, path) -> "BaseURIPath":
454
- """Return new instance of this class
455
-
456
- :param path: new path
457
- :return: new instance of new path
458
- :rtype: BaseURIPath
459
- """
460
- return cls(path)
461
-
462
- @classmethod
463
- def from_uri(cls, path: str) -> "BaseURIPath":
464
- protocol_prefix = cls.protocol + "://"
465
- if path[:len(protocol_prefix)] != protocol_prefix:
466
- raise ValueError(
467
- "protocol not match, expected: %r, got: %r" %
468
- (cls.protocol, path))
469
- return cls.from_path(path[len(protocol_prefix):])
470
-
471
437
  def __fspath__(self) -> str:
472
438
  return self.as_uri()
473
439
 
@@ -513,11 +479,11 @@ class BaseURIPath(BasePath):
513
479
 
514
480
  @classproperty
515
481
  def root(self) -> str:
516
- return self.protocol + '://'
482
+ return self.protocol + '://' # pyre-ignore[58]
517
483
 
518
484
  @classproperty
519
485
  def anchor(self) -> str:
520
- return self.root
486
+ return self.root # pyre-ignore[7]
521
487
 
522
488
 
523
489
  class URIPath(BaseURIPath):
@@ -527,7 +493,28 @@ class URIPath(BaseURIPath):
527
493
  path = self.from_path(path).joinpath(*other_paths)
528
494
  self.path = str(path)
529
495
 
530
- def __truediv__(self, other_path: PathLike) -> "BaseURIPath":
496
+ @classmethod
497
+ def from_path(cls: Type[Self], path: PathLike) -> Self:
498
+ """Return new instance of this class
499
+
500
+ :param path: new path
501
+
502
+ :return: new instance of new path
503
+ :rtype: Self
504
+ """
505
+ return cls(path) # pyre-ignore[19]
506
+
507
+ @classmethod
508
+ def from_uri(cls: Type[Self], path: PathLike) -> Self:
509
+ path = fspath(path)
510
+ protocol_prefix = cls.protocol + "://"
511
+ if path[:len(protocol_prefix)] != protocol_prefix:
512
+ raise ValueError(
513
+ "protocol not match, expected: %r, got: %r" %
514
+ (cls.protocol, path))
515
+ return cls.from_path(path[len(protocol_prefix):])
516
+
517
+ def __truediv__(self: Self, other_path: PathLike) -> Self:
531
518
  if isinstance(other_path, BaseURIPath):
532
519
  if self.protocol != other_path.protocol:
533
520
  raise TypeError(
@@ -537,27 +524,27 @@ class URIPath(BaseURIPath):
537
524
  raise TypeError("%r is not 'str' nor 'URIPath'" % other_path)
538
525
  return self.joinpath(other_path)
539
526
 
540
- def joinpath(self, *other_paths: PathLike) -> "BaseURIPath":
527
+ def joinpath(self: Self, *other_paths: PathLike) -> Self:
541
528
  '''Calling this method is equivalent to combining the path with each of the other arguments in turn'''
542
529
  return self.from_path(uri_join(str(self), *map(str, other_paths)))
543
530
 
544
- @cachedproperty
545
- def parts(self) -> Tuple[str]:
531
+ @cached_property
532
+ def parts(self) -> Tuple[str, ...]:
546
533
  '''A tuple giving access to the path’s various components'''
547
534
  parts = [self.root]
548
535
  path = self.path_without_protocol
549
536
  path = path.lstrip('/')
550
537
  if path != '':
551
538
  parts.extend(path.split('/'))
552
- return tuple(parts)
539
+ return tuple(parts) # pyre-ignore[7]
553
540
 
554
- @cachedproperty
541
+ @cached_property
555
542
  def parents(self) -> "URIPathParents":
556
543
  '''An immutable sequence providing access to the logical ancestors of the path'''
557
544
  return URIPathParents(self)
558
545
 
559
- @cachedproperty
560
- def parent(self) -> "BaseURIPath":
546
+ @cached_property
547
+ def parent(self: Self) -> Self:
561
548
  '''The logical parent of the path'''
562
549
  if self.path_without_protocol == "/":
563
550
  return self
@@ -565,15 +552,16 @@ class URIPath(BaseURIPath):
565
552
  return self.parents[0]
566
553
  return self.from_path("")
567
554
 
568
- @cachedproperty
555
+ @cached_property
569
556
  def name(self) -> str:
570
557
  '''A string representing the final path component, excluding the drive and root'''
571
558
  parts = self.parts
572
- if len(parts) == 1 and parts[0] == self.protocol + "://":
559
+ if len(parts
560
+ ) == 1 and parts[0] == self.protocol + "://": # pyre-ignore[58]
573
561
  return ''
574
562
  return parts[-1]
575
563
 
576
- @cachedproperty
564
+ @cached_property
577
565
  def suffix(self) -> str:
578
566
  '''The file extension of the final component'''
579
567
  name = self.name
@@ -582,7 +570,7 @@ class URIPath(BaseURIPath):
582
570
  return name[i:]
583
571
  return ''
584
572
 
585
- @cachedproperty
573
+ @cached_property
586
574
  def suffixes(self) -> List[str]:
587
575
  '''A list of the path’s file extensions'''
588
576
  name = self.name
@@ -591,7 +579,7 @@ class URIPath(BaseURIPath):
591
579
  name = name.lstrip('.')
592
580
  return ['.' + suffix for suffix in name.split('.')[1:]]
593
581
 
594
- @cachedproperty
582
+ @cached_property
595
583
  def stem(self) -> str:
596
584
  '''The final path component, without its suffix'''
597
585
  name = self.name
@@ -620,7 +608,7 @@ class URIPath(BaseURIPath):
620
608
  except Exception:
621
609
  return False
622
610
 
623
- def relative_to(self, *other) -> "BaseURIPath":
611
+ def relative_to(self: Self, *other: str) -> Self:
624
612
  '''
625
613
  Compute a version of this path relative to the path represented by other.
626
614
  If it’s impossible, ValueError is raised.
@@ -637,21 +625,21 @@ class URIPath(BaseURIPath):
637
625
  if path.startswith(other_path):
638
626
  relative = path[len(other_path):]
639
627
  relative = relative.lstrip('/')
640
- return type(self)(relative)
628
+ return type(self)(relative) # pyre-ignore[19]
641
629
  else:
642
630
  raise ValueError("%r does not start with %r" % (path, other))
643
631
 
644
- def with_name(self, name) -> "BaseURIPath":
632
+ def with_name(self: Self, name: str) -> Self:
645
633
  '''Return a new path with the name changed'''
646
634
  path = str(self)
647
635
  raw_name = self.name
648
636
  return self.from_path(path[:len(path) - len(raw_name)] + name)
649
637
 
650
- def with_stem(self, stem) -> "BaseURIPath":
638
+ def with_stem(self: Self, stem: str) -> Self:
651
639
  '''Return a new path with the stem changed'''
652
640
  return self.with_name("".join([stem, self.suffix]))
653
641
 
654
- def with_suffix(self, suffix) -> "BaseURIPath":
642
+ def with_suffix(self: Self, suffix: str) -> Self:
655
643
  '''Return a new path with the suffix changed'''
656
644
  path = str(self)
657
645
  raw_suffix = self.suffix
@@ -700,7 +688,7 @@ class URIPath(BaseURIPath):
700
688
  return False
701
689
 
702
690
  def abspath(self) -> str:
703
- """Return a normalized absolutized version of the path."""
691
+ """Return a normalized absolute version of the path."""
704
692
  return self.path_with_protocol
705
693
 
706
694
  def realpath(self) -> str:
@@ -723,14 +711,14 @@ class URIPath(BaseURIPath):
723
711
  def read_bytes(self) -> bytes:
724
712
  '''Return the binary contents of the pointed-to file as a bytes object'''
725
713
  with self.open(mode='rb') as f:
726
- return f.read()
714
+ return f.read() # pytype: disable=bad-return-type
727
715
 
728
716
  def read_text(self) -> str:
729
717
  '''Return the decoded contents of the pointed-to file as a string'''
730
718
  with self.open(mode='r') as f:
731
- return f.read()
719
+ return f.read() # pytype: disable=bad-return-type
732
720
 
733
- def rename(self, dst_path: PathLike, overwrite: bool = True) -> 'URIPath':
721
+ def rename(self: Self, dst_path: PathLike, overwrite: bool = True) -> Self:
734
722
  '''
735
723
  rename file
736
724
 
@@ -739,7 +727,7 @@ class URIPath(BaseURIPath):
739
727
  '''
740
728
  raise NotImplementedError(f"'rename' is unsupported on '{type(self)}'")
741
729
 
742
- def replace(self, dst_path: PathLike, overwrite: bool = True) -> 'URIPath':
730
+ def replace(self: Self, dst_path: PathLike, overwrite: bool = True) -> Self:
743
731
  '''
744
732
  move file
745
733
 
@@ -748,7 +736,7 @@ class URIPath(BaseURIPath):
748
736
  '''
749
737
  return self.rename(dst_path=dst_path, overwrite=overwrite)
750
738
 
751
- def rglob(self, pattern) -> List['URIPath']:
739
+ def rglob(self: Self, pattern) -> List[Self]:
752
740
  '''
753
741
  This is like calling Path.glob() with “**/” added in front of the given relative pattern
754
742
  '''
@@ -785,9 +773,7 @@ class URIPath(BaseURIPath):
785
773
  symlink_to's arguments is the reverse of symlink's.
786
774
  Target_is_directory’s value is ignored, only be compatible with pathlib.Path
787
775
  '''
788
- return self.from_path(
789
- target).symlink( # type: ignore
790
- dst_path=self.path)
776
+ return self.from_path(target).symlink(dst_path=self.path)
791
777
 
792
778
  def hardlink_to(self, target):
793
779
  '''
@@ -831,18 +817,18 @@ class URIPath(BaseURIPath):
831
817
  raise NotImplementedError(
832
818
  f"'expanduser' is unsupported on '{type(self)}'")
833
819
 
834
- def cwd(self) -> 'URIPath':
820
+ def cwd(self: Self) -> Self:
835
821
  '''Return current working directory
836
822
 
837
823
  returns: Current working directory
838
824
  '''
839
825
  raise NotImplementedError(f"'cwd' is unsupported on '{type(self)}'")
840
826
 
841
- def iterdir(self) -> Iterator['URIPath']:
827
+ def iterdir(self: Self) -> Iterator[Self]:
842
828
  '''
843
- Get all contents of given fs path. The result is in acsending alphabetical order.
829
+ Get all contents of given fs path. The result is in ascending alphabetical order.
844
830
 
845
- :returns: All contents have in the path in acsending alphabetical order
831
+ :returns: All contents have in the path in ascending alphabetical order
846
832
  '''
847
833
  raise NotImplementedError(f"'iterdir' is unsupported on '{type(self)}'")
848
834
 
@@ -852,7 +838,7 @@ class URIPath(BaseURIPath):
852
838
  '''
853
839
  raise NotImplementedError(f"'owner' is unsupported on '{type(self)}'")
854
840
 
855
- def absolute(self) -> 'URIPath':
841
+ def absolute(self: Self) -> Self:
856
842
  '''
857
843
  Make the path absolute, without normalization or resolving symlinks. Returns a new path object
858
844
  '''