diff options
Diffstat (limited to 'paramiko/sftp_client.py')
-rw-r--r-- | paramiko/sftp_client.py | 136 |
1 files changed, 72 insertions, 64 deletions
diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 14b8b58a..ea81fa5a 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -51,15 +51,15 @@ def _to_unicode(s): probably doesn't know the filename's encoding. """ try: - return s.encode('ascii') + return s.encode("ascii") except (UnicodeError, AttributeError): try: - return s.decode('utf-8') + return s.decode("utf-8") except UnicodeError: return s -b_slash = b'/' +b_slash = b"/" class SFTPClient(BaseSFTP, ClosingContextManager): @@ -71,6 +71,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): Instances of this class may be used as context managers. """ + def __init__(self, sock): """ Create an SFTP client from an existing `.Channel`. The channel @@ -97,15 +98,16 @@ class SFTPClient(BaseSFTP, ClosingContextManager): # override default logger transport = self.sock.get_transport() self.logger = util.get_logger( - transport.get_log_channel() + '.sftp') + transport.get_log_channel() + ".sftp" + ) self.ultra_debug = transport.get_hexdump() try: server_version = self._send_version() except EOFError: - raise SSHException('EOF during negotiation') + raise SSHException("EOF during negotiation") self._log( - INFO, - 'Opened sftp connection (server version %d)' % server_version) + INFO, "Opened sftp connection (server version %d)" % server_version + ) @classmethod def from_transport(cls, t, window_size=None, max_packet_size=None): @@ -131,11 +133,12 @@ class SFTPClient(BaseSFTP, ClosingContextManager): .. versionchanged:: 1.15 Added the ``window_size`` and ``max_packet_size`` arguments. """ - chan = t.open_session(window_size=window_size, - max_packet_size=max_packet_size) + chan = t.open_session( + window_size=window_size, max_packet_size=max_packet_size + ) if chan is None: return None - chan.invoke_subsystem('sftp') + chan.invoke_subsystem("sftp") return cls(chan) def _log(self, level, msg, *args): @@ -145,10 +148,12 @@ class SFTPClient(BaseSFTP, ClosingContextManager): else: # escape '%' in msg (they could come from file or directory names) # before logging - msg = msg.replace('%', '%%') + msg = msg.replace("%", "%%") super(SFTPClient, self)._log( level, - "[chan %s] " + msg, *([self.sock.get_name()] + list(args))) + "[chan %s] " + msg, + *([self.sock.get_name()] + list(args)) + ) def close(self): """ @@ -156,7 +161,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): .. versionadded:: 1.4 """ - self._log(INFO, 'sftp session closed.') + self._log(INFO, "sftp session closed.") self.sock.close() def get_channel(self): @@ -168,7 +173,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): """ return self.sock - def listdir(self, path='.'): + def listdir(self, path="."): """ Return a list containing the names of the entries in the given ``path``. @@ -182,7 +187,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): """ return [f.filename for f in self.listdir_attr(path)] - def listdir_attr(self, path='.'): + def listdir_attr(self, path="."): """ Return a list containing `.SFTPAttributes` objects corresponding to files in the given ``path``. The list is in arbitrary order. It does @@ -200,10 +205,10 @@ class SFTPClient(BaseSFTP, ClosingContextManager): .. versionadded:: 1.2 """ path = self._adjust_cwd(path) - self._log(DEBUG, 'listdir(%r)' % path) + self._log(DEBUG, "listdir(%r)" % path) t, msg = self._request(CMD_OPENDIR, path) if t != CMD_HANDLE: - raise SFTPError('Expected handle') + raise SFTPError("Expected handle") handle = msg.get_binary() filelist = [] while True: @@ -213,18 +218,18 @@ class SFTPClient(BaseSFTP, ClosingContextManager): # done with handle break if t != CMD_NAME: - raise SFTPError('Expected name response') + raise SFTPError("Expected name response") count = msg.get_int() for i in range(count): filename = msg.get_text() longname = msg.get_text() attr = SFTPAttributes._from_msg(msg, filename, longname) - if (filename != '.') and (filename != '..'): + if (filename != ".") and (filename != ".."): filelist.append(attr) self._request(CMD_CLOSE, handle) return filelist - def listdir_iter(self, path='.', read_aheads=50): + def listdir_iter(self, path=".", read_aheads=50): """ Generator version of `.listdir_attr`. @@ -239,11 +244,11 @@ class SFTPClient(BaseSFTP, ClosingContextManager): .. versionadded:: 1.15 """ path = self._adjust_cwd(path) - self._log(DEBUG, 'listdir(%r)' % path) + self._log(DEBUG, "listdir(%r)" % path) t, msg = self._request(CMD_OPENDIR, path) if t != CMD_HANDLE: - raise SFTPError('Expected handle') + raise SFTPError("Expected handle") handle = msg.get_string() @@ -258,7 +263,6 @@ class SFTPClient(BaseSFTP, ClosingContextManager): num = self._async_request(type(None), CMD_READDIR, handle) nums.append(num) - # For each of our sent requests # Read and parse the corresponding packets # If we're at the end of our queued requests, then fire off @@ -277,8 +281,9 @@ class SFTPClient(BaseSFTP, ClosingContextManager): filename = msg.get_text() longname = msg.get_text() attr = SFTPAttributes._from_msg( - msg, filename, longname) - if (filename != '.') and (filename != '..'): + msg, filename, longname + ) + if (filename != ".") and (filename != ".."): yield attr # If we've hit the end of our queued requests, reset nums. @@ -288,8 +293,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): self._request(CMD_CLOSE, handle) return - - def open(self, filename, mode='r', bufsize=-1): + def open(self, filename, mode="r", bufsize=-1): """ Open a file on the remote server. The arguments are the same as for Python's built-in `python:file` (aka `python:open`). A file-like @@ -322,26 +326,26 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :raises: ``IOError`` -- if the file could not be opened. """ filename = self._adjust_cwd(filename) - self._log(DEBUG, 'open(%r, %r)' % (filename, mode)) + self._log(DEBUG, "open(%r, %r)" % (filename, mode)) imode = 0 - if ('r' in mode) or ('+' in mode): + if ("r" in mode) or ("+" in mode): imode |= SFTP_FLAG_READ - if ('w' in mode) or ('+' in mode) or ('a' in mode): + if ("w" in mode) or ("+" in mode) or ("a" in mode): imode |= SFTP_FLAG_WRITE - if 'w' in mode: + if "w" in mode: imode |= SFTP_FLAG_CREATE | SFTP_FLAG_TRUNC - if 'a' in mode: + if "a" in mode: imode |= SFTP_FLAG_CREATE | SFTP_FLAG_APPEND - if 'x' in mode: + if "x" in mode: imode |= SFTP_FLAG_CREATE | SFTP_FLAG_EXCL attrblock = SFTPAttributes() t, msg = self._request(CMD_OPEN, filename, imode, attrblock) if t != CMD_HANDLE: - raise SFTPError('Expected handle') + raise SFTPError("Expected handle") handle = msg.get_binary() self._log( - DEBUG, - 'open(%r, %r) -> %s' % (filename, mode, u(hexlify(handle)))) + DEBUG, "open(%r, %r) -> %s" % (filename, mode, u(hexlify(handle))) + ) return SFTPFile(self, handle, mode, bufsize) # Python continues to vacillate about "open" vs "file"... @@ -357,7 +361,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :raises: ``IOError`` -- if the path refers to a folder (directory) """ path = self._adjust_cwd(path) - self._log(DEBUG, 'remove(%r)' % path) + self._log(DEBUG, "remove(%r)" % path) self._request(CMD_REMOVE, path) unlink = remove @@ -382,7 +386,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): """ oldpath = self._adjust_cwd(oldpath) newpath = self._adjust_cwd(newpath) - self._log(DEBUG, 'rename(%r, %r)' % (oldpath, newpath)) + self._log(DEBUG, "rename(%r, %r)" % (oldpath, newpath)) self._request(CMD_RENAME, oldpath, newpath) def posix_rename(self, oldpath, newpath): @@ -417,7 +421,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param int mode: permissions (posix-style) for the newly-created folder """ path = self._adjust_cwd(path) - self._log(DEBUG, 'mkdir(%r, %r)' % (path, mode)) + self._log(DEBUG, "mkdir(%r, %r)" % (path, mode)) attr = SFTPAttributes() attr.st_mode = mode self._request(CMD_MKDIR, path, attr) @@ -429,7 +433,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param str path: name of the folder to remove """ path = self._adjust_cwd(path) - self._log(DEBUG, 'rmdir(%r)' % path) + self._log(DEBUG, "rmdir(%r)" % path) self._request(CMD_RMDIR, path) def stat(self, path): @@ -452,10 +456,10 @@ class SFTPClient(BaseSFTP, ClosingContextManager): file """ path = self._adjust_cwd(path) - self._log(DEBUG, 'stat(%r)' % path) + self._log(DEBUG, "stat(%r)" % path) t, msg = self._request(CMD_STAT, path) if t != CMD_ATTRS: - raise SFTPError('Expected attributes') + raise SFTPError("Expected attributes") return SFTPAttributes._from_msg(msg) def lstat(self, path): @@ -470,10 +474,10 @@ class SFTPClient(BaseSFTP, ClosingContextManager): file """ path = self._adjust_cwd(path) - self._log(DEBUG, 'lstat(%r)' % path) + self._log(DEBUG, "lstat(%r)" % path) t, msg = self._request(CMD_LSTAT, path) if t != CMD_ATTRS: - raise SFTPError('Expected attributes') + raise SFTPError("Expected attributes") return SFTPAttributes._from_msg(msg) def symlink(self, source, dest): @@ -484,7 +488,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param str dest: path of the newly created symlink """ dest = self._adjust_cwd(dest) - self._log(DEBUG, 'symlink(%r, %r)' % (source, dest)) + self._log(DEBUG, "symlink(%r, %r)" % (source, dest)) source = bytestring(source) self._request(CMD_SYMLINK, source, dest) @@ -498,7 +502,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param int mode: new permissions """ path = self._adjust_cwd(path) - self._log(DEBUG, 'chmod(%r, %r)' % (path, mode)) + self._log(DEBUG, "chmod(%r, %r)" % (path, mode)) attr = SFTPAttributes() attr.st_mode = mode self._request(CMD_SETSTAT, path, attr) @@ -515,7 +519,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param int gid: new group id """ path = self._adjust_cwd(path) - self._log(DEBUG, 'chown(%r, %r, %r)' % (path, uid, gid)) + self._log(DEBUG, "chown(%r, %r, %r)" % (path, uid, gid)) attr = SFTPAttributes() attr.st_uid, attr.st_gid = uid, gid self._request(CMD_SETSTAT, path, attr) @@ -537,7 +541,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): path = self._adjust_cwd(path) if times is None: times = (time.time(), time.time()) - self._log(DEBUG, 'utime(%r, %r)' % (path, times)) + self._log(DEBUG, "utime(%r, %r)" % (path, times)) attr = SFTPAttributes() attr.st_atime, attr.st_mtime = times self._request(CMD_SETSTAT, path, attr) @@ -552,7 +556,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :param int size: the new size of the file """ path = self._adjust_cwd(path) - self._log(DEBUG, 'truncate(%r, %r)' % (path, size)) + self._log(DEBUG, "truncate(%r, %r)" % (path, size)) attr = SFTPAttributes() attr.st_size = size self._request(CMD_SETSTAT, path, attr) @@ -567,15 +571,15 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :return: target path, as a `str` """ path = self._adjust_cwd(path) - self._log(DEBUG, 'readlink(%r)' % path) + self._log(DEBUG, "readlink(%r)" % path) t, msg = self._request(CMD_READLINK, path) if t != CMD_NAME: - raise SFTPError('Expected name response') + raise SFTPError("Expected name response") count = msg.get_int() if count == 0: return None if count != 1: - raise SFTPError('Readlink returned %d results' % count) + raise SFTPError("Readlink returned %d results" % count) return _to_unicode(msg.get_string()) def normalize(self, path): @@ -591,13 +595,13 @@ class SFTPClient(BaseSFTP, ClosingContextManager): :raises: ``IOError`` -- if the path can't be resolved on the server """ path = self._adjust_cwd(path) - self._log(DEBUG, 'normalize(%r)' % path) + self._log(DEBUG, "normalize(%r)" % path) t, msg = self._request(CMD_REALPATH, path) if t != CMD_NAME: - raise SFTPError('Expected name response') + raise SFTPError("Expected name response") count = msg.get_int() if count != 1: - raise SFTPError('Realpath returned %d results' % count) + raise SFTPError("Realpath returned %d results" % count) return msg.get_text() def chdir(self, path=None): @@ -621,7 +625,8 @@ class SFTPClient(BaseSFTP, ClosingContextManager): return if not stat.S_ISDIR(self.stat(path).st_mode): raise SFTPError( - errno.ENOTDIR, "%s: %s" % (os.strerror(errno.ENOTDIR), path)) + errno.ENOTDIR, "%s: %s" % (os.strerror(errno.ENOTDIR), path) + ) self._cwd = b(self.normalize(path)) def getcwd(self): @@ -674,7 +679,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): .. versionadded:: 1.10 """ - with self.file(remotepath, 'wb') as fr: + with self.file(remotepath, "wb") as fr: fr.set_pipelined(True) size = self._transfer_with_callback( reader=fl, writer=fr, file_size=file_size, callback=callback @@ -683,7 +688,8 @@ class SFTPClient(BaseSFTP, ClosingContextManager): s = self.stat(remotepath) if s.st_size != size: raise IOError( - 'size mismatch in put! %d != %d' % (s.st_size, size)) + "size mismatch in put! %d != %d" % (s.st_size, size) + ) else: s = SFTPAttributes() return s @@ -717,7 +723,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): ``confirm`` param added. """ file_size = os.stat(localpath).st_size - with open(localpath, 'rb') as fl: + with open(localpath, "rb") as fl: return self.putfo(fl, remotepath, file_size, callback, confirm) def getfo(self, remotepath, fl, callback=None): @@ -738,7 +744,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): .. versionadded:: 1.10 """ file_size = self.stat(remotepath).st_size - with self.open(remotepath, 'rb') as fr: + with self.open(remotepath, "rb") as fr: fr.prefetch(file_size) return self._transfer_with_callback( reader=fr, writer=fl, file_size=file_size, callback=callback @@ -760,12 +766,13 @@ class SFTPClient(BaseSFTP, ClosingContextManager): .. versionchanged:: 1.7.4 Added the ``callback`` param """ - with open(localpath, 'wb') as fl: + with open(localpath, "wb") as fl: size = self.getfo(remotepath, fl, callback) s = os.stat(localpath) if s.st_size != size: raise IOError( - 'size mismatch in get! %d != %d' % (s.st_size, size)) + "size mismatch in get! %d != %d" % (s.st_size, size) + ) # ...internals... @@ -803,7 +810,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): try: t, data = self._read_packet() except EOFError as e: - raise SSHException('Server connection dropped: %s' % str(e)) + raise SSHException("Server connection dropped: %s" % str(e)) msg = Message(data) num = msg.get_int() self._lock.acquire() @@ -811,7 +818,7 @@ class SFTPClient(BaseSFTP, ClosingContextManager): if num not in self._expecting: # might be response for a file that was closed before # responses came back - self._log(DEBUG, 'Unexpected response #%d' % (num,)) + self._log(DEBUG, "Unexpected response #%d" % (num,)) if waitfor is None: # just doing a single check break @@ -878,4 +885,5 @@ class SFTP(SFTPClient): """ An alias for `.SFTPClient` for backwards compatibility. """ + pass |