From ca15e1123ff335feea5a74926feb97a8f04986cb Mon Sep 17 00:00:00 2001 From: Ron Frederick Date: Sat, 16 Nov 2024 10:07:54 -0800 Subject: [PATCH] Fix a couple of SFTP block size issues and a couple of doc errors This commit fixes an issue with AsyncSSH not honoring the block_size in calls to the high level SFTP get/put/copy functions when the default block size is smaller than the requested value. It also, fixes a problem when a block_size of 0 is passed in to these functions. Now, a block_size of 0 is treated the same as leaving it set to the default, automatically choosing a value based on the advertised server limits, falling back to 16 KB if the server doesn't advertise limits. This commit also fixes a copy of errors in the documentation for the SFTP put() and copy() methods. Thanks go to Krzysztof Kotlenga for finding and reporting these issues! --- asyncssh/sftp.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/asyncssh/sftp.py b/asyncssh/sftp.py index aa3fad2..b5f139d 100644 --- a/asyncssh/sftp.py +++ b/asyncssh/sftp.py @@ -272,7 +272,8 @@ async def symlink(self, oldpath: bytes, newpath: bytes) -> None: """Create a symbolic link""" @async_context_manager - async def open(self, path: bytes, mode: str) -> SFTPFileProtocol: + async def open(self, path: bytes, mode: str, + block_size: int = -1) -> SFTPFileProtocol: """Open a file""" @@ -797,8 +798,10 @@ async def run(self) -> None: """Perform parallel file copy""" try: - self._src = await self._srcfs.open(self._srcpath, 'rb') - self._dst = await self._dstfs.open(self._dstpath, 'wb') + self._src = await self._srcfs.open(self._srcpath, 'rb', + block_size=0) + self._dst = await self._dstfs.open(self._dstpath, 'wb', + block_size=0) if self._progress_handler and self._total_bytes == 0: self._progress_handler(self._srcpath, self._dstpath, 0, 0) @@ -3787,7 +3790,7 @@ async def _begin_copy(self, srcfs: _SFTPFSProtocol, dstfs: _SFTPFSProtocol, error_handler: SFTPErrorHandler) -> None: """Begin a new file upload, download, or copy""" - if block_size == -1: + if block_size <= 0: block_size = min(srcfs.limits.max_read_len, dstfs.limits.max_write_len) @@ -3989,7 +3992,7 @@ async def put(self, localpaths: _SFTPPaths, watch out for links that result in loops. The block_size argument specifies the size of read and write - requests issued when downloading the files, defaulting to + requests issued when uploading the files, defaulting to the maximum allowed by the server, or 16 KB if the server doesn't advertise limits. @@ -4095,8 +4098,8 @@ async def copy(self, srcpaths: _SFTPPaths, watch out for links that result in loops. The block_size argument specifies the size of read and write - requests issued when downloading the files, defaulting to - the maximum allowed by the server, or 16 KB if the server + requests issued when copying the files, defaulting to the + maximum allowed by the server, or 16 KB if the server doesn't advertise limits. The max_requests argument specifies the maximum number of @@ -7622,7 +7625,8 @@ async def symlink(self, oldpath: bytes, newpath: bytes) -> None: os.symlink(_to_local_path(oldpath), _to_local_path(newpath)) @async_context_manager - async def open(self, path: bytes, mode: str) -> LocalFile: + async def open(self, path: bytes, mode: str, + block_size: int = -1) -> LocalFile: """Open a local file""" # pylint: disable=unused-argument