|
6 | 6 | from copy import copy |
7 | 7 | from pathlib import Path |
8 | 8 | from types import MappingProxyType |
| 9 | +from typing import IO |
9 | 10 | from typing import TYPE_CHECKING |
10 | 11 | from typing import Any |
| 12 | +from typing import BinaryIO |
| 13 | +from typing import Literal |
11 | 14 | from typing import Mapping |
| 15 | +from typing import TextIO |
12 | 16 | from typing import TypeVar |
| 17 | +from typing import overload |
13 | 18 | from urllib.parse import urlsplit |
14 | 19 |
|
15 | | -from fsspec import AbstractFileSystem |
16 | | -from fsspec import get_filesystem_class |
| 20 | +from fsspec.registry import get_filesystem_class |
| 21 | +from fsspec.spec import AbstractFileSystem |
17 | 22 |
|
18 | 23 | from upath._compat import FSSpecAccessorShim |
19 | 24 | from upath._compat import PathlibPathShim |
@@ -741,8 +746,64 @@ def is_socket(self): |
741 | 746 | def samefile(self, other_path): |
742 | 747 | raise NotImplementedError |
743 | 748 |
|
744 | | - def open(self, mode="r", buffering=-1, encoding=None, errors=None, newline=None): |
745 | | - return self.fs.open(self.path, mode) # fixme |
| 749 | + @overload |
| 750 | + def open( |
| 751 | + self, |
| 752 | + mode: Literal["r", "w", "a"] = ..., |
| 753 | + buffering: int = ..., |
| 754 | + encoding: str = ..., |
| 755 | + errors: str = ..., |
| 756 | + newline: str = ..., |
| 757 | + **fsspec_kwargs: Any, |
| 758 | + ) -> TextIO: ... |
| 759 | + |
| 760 | + @overload |
| 761 | + def open( |
| 762 | + self, |
| 763 | + mode: Literal["rb", "wb", "ab"] = ..., |
| 764 | + buffering: int = ..., |
| 765 | + encoding: str = ..., |
| 766 | + errors: str = ..., |
| 767 | + newline: str = ..., |
| 768 | + **fsspec_kwargs: Any, |
| 769 | + ) -> BinaryIO: ... |
| 770 | + |
| 771 | + def open( |
| 772 | + self, |
| 773 | + mode: str = "r", |
| 774 | + *args: Any, |
| 775 | + **fsspec_kwargs: Any, |
| 776 | + ) -> IO[Any]: |
| 777 | + """ |
| 778 | + Open the file pointed by this path and return a file object, as |
| 779 | + the built-in open() function does. |
| 780 | +
|
| 781 | + Parameters |
| 782 | + ---------- |
| 783 | + mode: |
| 784 | + Opening mode. Default is 'r'. |
| 785 | + buffering: |
| 786 | + Default is the block size of the underlying fsspec filesystem. |
| 787 | + encoding: |
| 788 | + Encoding is only used in text mode. Default is None. |
| 789 | + errors: |
| 790 | + Error handling for encoding. Only used in text mode. Default is None. |
| 791 | + newline: |
| 792 | + Newline handling. Only used in text mode. Default is None. |
| 793 | + **fsspec_kwargs: |
| 794 | + Additional options for the fsspec filesystem. |
| 795 | + """ |
| 796 | + # match the signature of pathlib.Path.open() |
| 797 | + for key, value in zip(["buffering", "encoding", "errors", "newline"], args): |
| 798 | + if key in fsspec_kwargs: |
| 799 | + raise TypeError( |
| 800 | + f"{type(self).__name__}.open() got multiple values for '{key}'" |
| 801 | + ) |
| 802 | + fsspec_kwargs[key] = value |
| 803 | + # translate pathlib buffering to fs block_size |
| 804 | + if "buffering" in fsspec_kwargs: |
| 805 | + fsspec_kwargs.setdefault("block_size", fsspec_kwargs.pop("buffering")) |
| 806 | + return self.fs.open(self.path, mode=mode, **fsspec_kwargs) |
746 | 807 |
|
747 | 808 | def iterdir(self): |
748 | 809 | for name in self.fs.listdir(self.path): |
|
0 commit comments