From 448613e33c395917771c2751e62888a74ff663b3 Mon Sep 17 00:00:00 2001 From: John Begeman Date: Wed, 9 Jan 2013 12:39:33 -0500 Subject: Add listdir_iter to sftp_client.SFTPClient --- paramiko/sftp_client.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 8cb8ceaf..b546363d 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -193,6 +193,75 @@ class SFTPClient (BaseSFTP): self._request(CMD_CLOSE, handle) return filelist + def listdir_iter(self, path='.', read_ahead_requests=50): + """ + Generator yielding L{SFTPAttributes} objects corresponding to + files in the given C{path}. Files are yielded in arbitrary order. It does + not include the special entries C{'.'} and C{'..'} even if they are + present in the folder. + + The returned L{SFTPAttributes} objects will each have an additional + field: C{longname}, which may contain a formatted string of the file's + attributes, in unix format. The content of this string will probably + depend on the SFTP server implementation. + + @param path: path to list (defaults to C{'.'}) + @type path: str + @return: Yields L{SFTPAttributes} + @rtype: L{SFTPAttributes} + + @since: 1.9 + """ + path = self._adjust_cwd(path) + self._log(DEBUG, 'listdir(%r)' % path) + t, msg = self._request(CMD_OPENDIR, path) + + if t != CMD_HANDLE: + raise SFTPError('Expected handle') + + handle = msg.get_string() + + nums = list() + while True: + try: + # Assume the handle IDs we're getting will be in sequence... + # Send out a bunch of readdir requests so that we can read the responses later on + # Section 6.7 of the SSH file transfer RFC explains this + # http://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt + for i in range(read_ahead_requests): + 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 some more requests + # Exit the loop when we've reached the end of the directory handle + for num in nums: + # Avoid using self._request as it does a bunch of shit we don't care about in scanning directories + t, pkt_data = self._read_packet() + msg = Message(pkt_data) + new_num = msg.get_int() + if num == new_num: + if t == CMD_STATUS: + self._convert_status(msg) + count = msg.get_int() + for i in range(count): + filename = msg.get_string() + longname = msg.get_string() + attr = SFTPAttributes._from_msg(msg, filename, longname) + if (filename != '.') and (filename != '..'): + now = datetime.datetime.now() + yield attr + + # If we've hit the end of our queued requests, reset nums. + nums = list() + + except EOFError as e: + self._request(CMD_CLOSE, handle) + return + + def open(self, filename, mode='r', bufsize=-1): """ Open a file on the remote server. The arguments are the same as for -- cgit v1.2.3 From 6313ad0c3a942f2c3eb471e8fed265028a469234 Mon Sep 17 00:00:00 2001 From: John Begeman Date: Wed, 9 Jan 2013 15:02:21 -0500 Subject: Remove some debug stuff I inadvertently left in and remove some confusing comments --- paramiko/sftp_client.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index b546363d..4c69da26 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -224,7 +224,6 @@ class SFTPClient (BaseSFTP): nums = list() while True: try: - # Assume the handle IDs we're getting will be in sequence... # Send out a bunch of readdir requests so that we can read the responses later on # Section 6.7 of the SSH file transfer RFC explains this # http://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt @@ -238,7 +237,6 @@ class SFTPClient (BaseSFTP): # If we're at the end of our queued requests, then fire off some more requests # Exit the loop when we've reached the end of the directory handle for num in nums: - # Avoid using self._request as it does a bunch of shit we don't care about in scanning directories t, pkt_data = self._read_packet() msg = Message(pkt_data) new_num = msg.get_int() @@ -251,7 +249,6 @@ class SFTPClient (BaseSFTP): longname = msg.get_string() attr = SFTPAttributes._from_msg(msg, filename, longname) if (filename != '.') and (filename != '..'): - now = datetime.datetime.now() yield attr # If we've hit the end of our queued requests, reset nums. -- cgit v1.2.3 From 683b3c22893be899d2fdbf1ada35e61fba8a3d70 Mon Sep 17 00:00:00 2001 From: John Begeman Date: Wed, 9 Jan 2013 15:26:55 -0500 Subject: Add python 2.5 support except block to listdir_iter --- paramiko/sftp_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 4c69da26..5c2eb8bb 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -254,7 +254,7 @@ class SFTPClient (BaseSFTP): # If we've hit the end of our queued requests, reset nums. nums = list() - except EOFError as e: + except EOFError: self._request(CMD_CLOSE, handle) return -- cgit v1.2.3 From 3fce8abf68f386d18f2fad9f086e0d436af57b3a Mon Sep 17 00:00:00 2001 From: Antoine Brenner Date: Wed, 16 Apr 2014 21:58:03 +0200 Subject: BufferedFile.read() now returns byte strings instead of text strings It is the right thing to do since we have no idea what encoding the file is in, or even if the file is text data. BufferedFile.readline() is unchanged and returns text strings assuming the file is utf-8 encoded. This should fix the following issue: http://comments.gmane.org/gmane.comp.sysutils.backup.obnam/252 Antoine Brenner Conflicts: sites/www/changelog.rst --- paramiko/file.py | 21 +++++++++++++++------ sites/www/changelog.rst | 7 +++++++ tests/test_file.py | 45 +++++++++++++++++++++++++-------------------- tests/test_sftp.py | 10 +++++----- tests/test_sftp_big.py | 4 ++-- 5 files changed, 54 insertions(+), 33 deletions(-) diff --git a/paramiko/file.py b/paramiko/file.py index f57aa79f..725ca5f6 100644 --- a/paramiko/file.py +++ b/paramiko/file.py @@ -124,10 +124,15 @@ class BufferedFile (object): file first). If the ``size`` argument is negative or omitted, read all the remaining data in the file. + `'b' mode flag is ignored (self.FLAG_BINARY in self._flags), because + SSH treats all files as binary, since we have no idea what encoding + the file is in, or even if the file is text data. + + :param int size: maximum number of bytes to read :return: - data read from the file (as a `str`), or an empty string if EOF was - encountered immediately + data read from the file (as bytes ), or an empty string + if EOF was encountered immediately """ if self._closed: raise IOError('File is closed') @@ -148,12 +153,12 @@ class BufferedFile (object): result += new_data self._realpos += len(new_data) self._pos += len(new_data) - return result if self._flags & self.FLAG_BINARY else u(result) + return result if size <= len(self._rbuffer): result = self._rbuffer[:size] self._rbuffer = self._rbuffer[size:] self._pos += len(result) - return result if self._flags & self.FLAG_BINARY else u(result) + return result while len(self._rbuffer) < size: read_size = size - len(self._rbuffer) if self._flags & self.FLAG_BUFFERED: @@ -169,7 +174,7 @@ class BufferedFile (object): result = self._rbuffer[:size] self._rbuffer = self._rbuffer[size:] self._pos += len(result) - return result if self._flags & self.FLAG_BINARY else u(result) + return result def readline(self, size=None): """ @@ -186,8 +191,12 @@ class BufferedFile (object): :param int size: maximum length of returned string. :return: - next line of the file (`str`), or an empty string if the end of the + next line of the file, or an empty string if the end of the file has been reached. + If the file was opened in binary 'b' mode: bytes are returned + Else: the encoding of the file is assumed to be utf-8 (default + encoding used by paramiko.py3compat.u) and character strings + (`str`) are returned """ # it's almost silly how complex this function is. if self._closed: diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 21ba6e12..67c4f827 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,13 @@ Changelog ========= +* :bug: BufferedFile.read() now returns byte strings instead of text strings + It is the right thing to do since we have no idea what encoding the file + is in, or even if the file is text data. BufferedFile.readline() is + unchanged and returns text strings assuming the file is utf-8 encoded. + This should fix the following issue: + http://comments.gmane.org/gmane.comp.sysutils.backup.obnam/252 + Thanks Antoine Brenner * :bug:`-` Added self.args for exception classes. Used for unpickling. Related to (`Fabric #986 `_, `Fabric #714 `_). Thanks to Alex diff --git a/tests/test_file.py b/tests/test_file.py index e11d7fd5..c6edd7af 100755 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -53,7 +53,7 @@ class BufferedFileTest (unittest.TestCase): def test_1_simple(self): f = LoopbackFile('r') try: - f.write('hi') + f.write(b'hi') self.assertTrue(False, 'no exception on write to read-only file') except: pass @@ -69,7 +69,7 @@ class BufferedFileTest (unittest.TestCase): def test_2_readline(self): f = LoopbackFile('r+U') - f.write('First line.\nSecond line.\r\nThird line.\nFinal line non-terminated.') + f.write(b'First line.\nSecond line.\r\nThird line.\nFinal line non-terminated.') self.assertEqual(f.readline(), 'First line.\n') # universal newline mode should convert this linefeed: self.assertEqual(f.readline(), 'Second line.\n') @@ -93,9 +93,9 @@ class BufferedFileTest (unittest.TestCase): try to trick the linefeed detector. """ f = LoopbackFile('r+U') - f.write('First line.\r') + f.write(b'First line.\r') self.assertEqual(f.readline(), 'First line.\n') - f.write('\nSecond.\r\n') + f.write(b'\nSecond.\r\n') self.assertEqual(f.readline(), 'Second.\n') f.close() self.assertEqual(f.newlines, crlf) @@ -105,7 +105,7 @@ class BufferedFileTest (unittest.TestCase): verify that write buffering is on. """ f = LoopbackFile('r+', 1) - f.write('Complete line.\nIncomplete line.') + f.write(b'Complete line.\nIncomplete line.') self.assertEqual(f.readline(), 'Complete line.\n') self.assertEqual(f.readline(), '') f.write('..\n') @@ -118,12 +118,12 @@ class BufferedFileTest (unittest.TestCase): """ f = LoopbackFile('r+', 512) f.write('Not\nquite\n512 bytes.\n') - self.assertEqual(f.read(1), '') + self.assertEqual(f.read(1), b'') f.flush() - self.assertEqual(f.read(5), 'Not\nq') - self.assertEqual(f.read(10), 'uite\n512 b') - self.assertEqual(f.read(9), 'ytes.\n') - self.assertEqual(f.read(3), '') + self.assertEqual(f.read(5), b'Not\nq') + self.assertEqual(f.read(10), b'uite\n512 b') + self.assertEqual(f.read(9), b'ytes.\n') + self.assertEqual(f.read(3), b'') f.close() def test_6_buffering(self): @@ -131,12 +131,12 @@ class BufferedFileTest (unittest.TestCase): verify that flushing happens automatically on buffer crossing. """ f = LoopbackFile('r+', 16) - f.write('Too small.') - self.assertEqual(f.read(4), '') - f.write(' ') - self.assertEqual(f.read(4), '') - f.write('Enough.') - self.assertEqual(f.read(20), 'Too small. Enough.') + f.write(b'Too small.') + self.assertEqual(f.read(4), b'') + f.write(b' ') + self.assertEqual(f.read(4), b'') + f.write(b'Enough.') + self.assertEqual(f.read(20), b'Too small. Enough.') f.close() def test_7_read_all(self): @@ -144,9 +144,14 @@ class BufferedFileTest (unittest.TestCase): verify that read(-1) returns everything left in the file. """ f = LoopbackFile('r+', 16) - f.write('The first thing you need to do is open your eyes. ') - f.write('Then, you need to close them again.\n') + f.write(b'The first thing you need to do is open your eyes. ') + f.write(b'Then, you need to close them again.\n') s = f.read(-1) - self.assertEqual(s, 'The first thing you need to do is open your eyes. Then, you ' + - 'need to close them again.\n') + self.assertEqual(s, b'The first thing you need to do is open your eyes. Then, you ' + + b'need to close them again.\n') f.close() + +if __name__ == '__main__': + from unittest import main + main() + diff --git a/tests/test_sftp.py b/tests/test_sftp.py index e0534eb0..720b8215 100755 --- a/tests/test_sftp.py +++ b/tests/test_sftp.py @@ -405,7 +405,7 @@ class SFTPTest (unittest.TestCase): self.assertEqual(sftp.stat(FOLDER + '/testing.txt').st_size, 13) with sftp.open(FOLDER + '/testing.txt', 'r') as f: data = f.read(20) - self.assertEqual(data, 'hello kiddy.\n') + self.assertEqual(data, b'hello kiddy.\n') finally: sftp.remove(FOLDER + '/testing.txt') @@ -466,8 +466,8 @@ class SFTPTest (unittest.TestCase): f.write('?\n') with sftp.open(FOLDER + '/happy.txt', 'r') as f: - self.assertEqual(f.readline(), 'full line?\n') - self.assertEqual(f.read(7), 'partial') + self.assertEqual(f.readline(), u'full line?\n') + self.assertEqual(f.read(7), b'partial') finally: try: sftp.remove(FOLDER + '/happy.txt') @@ -662,8 +662,8 @@ class SFTPTest (unittest.TestCase): fd, localname = mkstemp() os.close(fd) - text = 'All I wanted was a plastic bunny rabbit.\n' - with open(localname, 'w') as f: + text = b'All I wanted was a plastic bunny rabbit.\n' + with open(localname, 'wb') as f: f.write(text) saved_progress = [] diff --git a/tests/test_sftp_big.py b/tests/test_sftp_big.py index 521fbdc8..abed27b8 100644 --- a/tests/test_sftp_big.py +++ b/tests/test_sftp_big.py @@ -85,7 +85,7 @@ class BigSFTPTest (unittest.TestCase): write a 1MB file with no buffering. """ sftp = get_sftp() - kblob = (1024 * 'x') + kblob = (1024 * b'x') start = time.time() try: with sftp.open('%s/hongry.txt' % FOLDER, 'w') as f: @@ -231,7 +231,7 @@ class BigSFTPTest (unittest.TestCase): without using it, to verify that paramiko doesn't get confused. """ sftp = get_sftp() - kblob = (1024 * 'x') + kblob = (1024 * b'x') try: with sftp.open('%s/hongry.txt' % FOLDER, 'w') as f: f.set_pipelined(True) -- cgit v1.2.3 From 5636381591aa26a9f31efab450b6bfdd6659cbb3 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 24 Apr 2014 09:33:38 -0700 Subject: Reword docs/changelog re #315 --- paramiko/file.py | 19 +++++++++---------- sites/www/changelog.rst | 20 +++++++++++++------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/paramiko/file.py b/paramiko/file.py index 725ca5f6..70243e40 100644 --- a/paramiko/file.py +++ b/paramiko/file.py @@ -124,15 +124,14 @@ class BufferedFile (object): file first). If the ``size`` argument is negative or omitted, read all the remaining data in the file. - `'b' mode flag is ignored (self.FLAG_BINARY in self._flags), because - SSH treats all files as binary, since we have no idea what encoding - the file is in, or even if the file is text data. - + ``'b'`` mode flag is ignored (``self.FLAG_BINARY`` in ``self._flags``), + because SSH treats all files as binary, since we have no idea what + encoding the file is in, or even if the file is text data. :param int size: maximum number of bytes to read :return: - data read from the file (as bytes ), or an empty string - if EOF was encountered immediately + data read from the file (as bytes), or an empty string if EOF was + encountered immediately """ if self._closed: raise IOError('File is closed') @@ -193,10 +192,10 @@ class BufferedFile (object): :return: next line of the file, or an empty string if the end of the file has been reached. - If the file was opened in binary 'b' mode: bytes are returned - Else: the encoding of the file is assumed to be utf-8 (default - encoding used by paramiko.py3compat.u) and character strings - (`str`) are returned + + If the file was opened in binary (``'b'``) mode: bytes are returned + Else: the encoding of the file is assumed to be UTF-8 and character + strings (`str`) are returned """ # it's almost silly how complex this function is. if self._closed: diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 67c4f827..8a4b0f56 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,13 +2,19 @@ Changelog ========= -* :bug: BufferedFile.read() now returns byte strings instead of text strings - It is the right thing to do since we have no idea what encoding the file - is in, or even if the file is text data. BufferedFile.readline() is - unchanged and returns text strings assuming the file is utf-8 encoded. - This should fix the following issue: - http://comments.gmane.org/gmane.comp.sysutils.backup.obnam/252 - Thanks Antoine Brenner +* :bug:`-` `paramiko.file.BufferedFile.read` incorrectly returned text strings + after the Python 3 migration, despite bytes being more appropriate for file + contents (which may be binary or of an unknown encoding.) This has been + addressed. + + .. note:: + `paramiko.file.BufferedFile.readline` continues to return strings, not + bytes, as "lines" only make sense for textual data. It assumes UTF-8 by + default. + + This should fix `this issue raised on the Obnam mailing list + `_. Thanks + to Antoine Brenner for the patch. * :bug:`-` Added self.args for exception classes. Used for unpickling. Related to (`Fabric #986 `_, `Fabric #714 `_). Thanks to Alex -- cgit v1.2.3 From a759a8e8df0127e624d69f0e2c02704a95e0cc0c Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 24 Apr 2014 09:33:48 -0700 Subject: Fix incorrect monospacing --- sites/www/installing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sites/www/installing.rst b/sites/www/installing.rst index 3587949f..0ca9b156 100644 --- a/sites/www/installing.rst +++ b/sites/www/installing.rst @@ -18,8 +18,8 @@ We currently support **Python 2.5/2.6/2.7**, with support for Python 3 coming soon. Users on Python 2.4 or older are urged to upgrade. Paramiko *may* work on Python 2.4 still, but there is no longer any support guarantee. -Paramiko has two dependencies: the pure-Python ECDSA module `ecdsa`, and the -PyCrypto C extension. `ecdsa` is easily installable from wherever you +Paramiko has two dependencies: the pure-Python ECDSA module ``ecdsa``, and the +PyCrypto C extension. ``ecdsa`` is easily installable from wherever you obtained Paramiko's package; PyCrypto may require more work. Read on for details. -- cgit v1.2.3 From ac4c75471821fa5686c1f15e1b8613fe70639355 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 24 Apr 2014 09:33:48 -0700 Subject: Fix incorrect monospacing --- sites/www/installing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sites/www/installing.rst b/sites/www/installing.rst index 3587949f..0ca9b156 100644 --- a/sites/www/installing.rst +++ b/sites/www/installing.rst @@ -18,8 +18,8 @@ We currently support **Python 2.5/2.6/2.7**, with support for Python 3 coming soon. Users on Python 2.4 or older are urged to upgrade. Paramiko *may* work on Python 2.4 still, but there is no longer any support guarantee. -Paramiko has two dependencies: the pure-Python ECDSA module `ecdsa`, and the -PyCrypto C extension. `ecdsa` is easily installable from wherever you +Paramiko has two dependencies: the pure-Python ECDSA module ``ecdsa``, and the +PyCrypto C extension. ``ecdsa`` is easily installable from wherever you obtained Paramiko's package; PyCrypto may require more work. Read on for details. -- cgit v1.2.3 From 7e84566772db39ec7e28558a0ec5c8c0c3987f4b Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 13 Mar 2014 21:06:14 -0700 Subject: Update copyright in README to be more accurate --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 77866b8f..005fd6f3 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ paramiko :Paramiko: Python SSH module :Copyright: Copyright (c) 2003-2009 Robey Pointer -:Copyright: Copyright (c) 2014 Jeff Forcier +:Copyright: Copyright (c) 2013-2014 Jeff Forcier :License: LGPL :Homepage: https://github.com/paramiko/paramiko/ :API docs: http://docs.paramiko.org -- cgit v1.2.3 From 7a709498dce3d75d5c8125270760305ac1354a44 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Sun, 6 Apr 2014 12:36:50 -0700 Subject: Formatting --- setup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 2910a7fe..4a858326 100644 --- a/setup.py +++ b/setup.py @@ -40,9 +40,10 @@ import sys try: from setuptools import setup kw = { - 'install_requires': ['pycrypto >= 2.1, != 2.4', - 'ecdsa', - ], + 'install_requires': [ + 'pycrypto >= 2.1, != 2.4', + 'ecdsa', + ], } except ImportError: from distutils.core import setup -- cgit v1.2.3 From 4fe3ad2220996354b7f096cbd2d3000caf5cfdf0 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Sun, 6 Apr 2014 18:52:58 -0700 Subject: Nuke Fab-oriented link color override --- sites/shared_conf.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/sites/shared_conf.py b/sites/shared_conf.py index c61ca638..c265fc49 100644 --- a/sites/shared_conf.py +++ b/sites/shared_conf.py @@ -14,9 +14,6 @@ html_theme_options = { 'github_repo': 'paramiko', 'gittip_user': 'bitprophet', 'analytics_id': 'UA-18486793-2', - - 'link': '#3782BE', - 'link_hover': '#3782BE', } html_sidebars = { '**': [ -- cgit v1.2.3 From a1c2a9829a620c3ace6ddc6187bf05262e10b137 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 14 Apr 2014 10:48:33 -0400 Subject: Errything uses intersphinx to Python --- sites/docs/conf.py | 7 +------ sites/shared_conf.py | 7 ++++++- sites/www/conf.py | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/sites/docs/conf.py b/sites/docs/conf.py index f9355715..5674fed1 100644 --- a/sites/docs/conf.py +++ b/sites/docs/conf.py @@ -5,16 +5,11 @@ sys.path.append(os.path.abspath('../..')) from shared_conf import * # Enable autodoc, intersphinx -extensions.extend(['sphinx.ext.autodoc', 'sphinx.ext.intersphinx']) +extensions.extend(['sphinx.ext.autodoc']) # Autodoc settings autodoc_default_flags = ['members', 'special-members'] -# Intersphinx connection to stdlib -intersphinx_mapping = { - 'python': ('http://docs.python.org/2.6', None), -} - # Sister-site links to WWW html_theme_options['extra_nav_links'] = { "Main website": 'http://www.paramiko.org', diff --git a/sites/shared_conf.py b/sites/shared_conf.py index c265fc49..e0afe92e 100644 --- a/sites/shared_conf.py +++ b/sites/shared_conf.py @@ -5,7 +5,7 @@ import alabaster # Alabaster theme + mini-extension html_theme_path = [alabaster.get_path()] -extensions = ['alabaster'] +extensions = ['alabaster', 'sphinx.ext.intersphinx'] # Paths relative to invoking conf.py - not this shared file html_theme = 'alabaster' html_theme_options = { @@ -24,6 +24,11 @@ html_sidebars = { ] } +# Everything intersphinx's to Python +intersphinx_mapping = { + 'python': ('http://docs.python.org/2.6', None), +} + # Regular settings project = 'Paramiko' year = datetime.now().year diff --git a/sites/www/conf.py b/sites/www/conf.py index 1c6c9254..c7828203 100644 --- a/sites/www/conf.py +++ b/sites/www/conf.py @@ -25,9 +25,7 @@ target = join(dirname(__file__), '..', 'docs', '_build') if os.environ.get('READTHEDOCS') == 'True': # TODO: switch to docs.paramiko.org post go-live of sphinx API docs target = 'http://docs.paramiko.org/en/latest/' -intersphinx_mapping = { - 'docs': (target, None), -} +intersphinx_mapping['docs'] = (target, None) # Sister-site links to API docs html_theme_options['extra_nav_links'] = { -- cgit v1.2.3 From 24309559bbdc4742a94854eb33c9d6047635497c Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Tue, 15 Apr 2014 15:04:46 -0400 Subject: Show Travis status in website sidebar --- sites/shared_conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sites/shared_conf.py b/sites/shared_conf.py index e0afe92e..69908388 100644 --- a/sites/shared_conf.py +++ b/sites/shared_conf.py @@ -14,6 +14,7 @@ html_theme_options = { 'github_repo': 'paramiko', 'gittip_user': 'bitprophet', 'analytics_id': 'UA-18486793-2', + 'travis_button': True, } html_sidebars = { '**': [ -- cgit v1.2.3 From 337f4432d3aef1230ecb588dace0afd445a262c6 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 13 Mar 2014 21:06:57 -0700 Subject: README py3 update --- README | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README b/README index 005fd6f3..9305bfb3 100644 --- a/README +++ b/README @@ -34,7 +34,8 @@ that should have come with this archive. Requirements ------------ - - python 2.6 or better + - Python 2.6 or better - this includes Python + 3.3 and higher as well. - pycrypto 2.1 or better - ecdsa 0.9 or better -- cgit v1.2.3 From 74c612e328b962f348f9f425f47d1ecbaef3b207 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Sun, 6 Apr 2014 16:19:03 -0700 Subject: Use newer alabaster w/ showhidden in sidebar TOC Lets us not have 2x TOCs on landing page --- dev-requirements.txt | 2 +- sites/www/index.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 5744f331..91ae8549 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -5,5 +5,5 @@ tox>=1.4,<1.5 invoke>=0.7.0 invocations>=0.5.0 sphinx>=1.1.3 -alabaster>=0.3.1 +alabaster>=0.4.0 releases>=0.5.2 diff --git a/sites/www/index.rst b/sites/www/index.rst index 7fefedd2..0f07d7e9 100644 --- a/sites/www/index.rst +++ b/sites/www/index.rst @@ -12,6 +12,8 @@ usage and API documentation can be found at our code documentation site, `docs.paramiko.org `_. .. toctree:: + :hidden: + changelog installing contributing -- cgit v1.2.3 From 6f4c159b052eae52def9fde0ddcbb7c864ef6592 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 24 Apr 2014 10:25:37 -0700 Subject: Merge updated a01e449 from al-tonio --- paramiko/file.py | 8 +++++--- tests/test_sftp.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/paramiko/file.py b/paramiko/file.py index 70243e40..856cc101 100644 --- a/paramiko/file.py +++ b/paramiko/file.py @@ -124,9 +124,11 @@ class BufferedFile (object): file first). If the ``size`` argument is negative or omitted, read all the remaining data in the file. - ``'b'`` mode flag is ignored (``self.FLAG_BINARY`` in ``self._flags``), - because SSH treats all files as binary, since we have no idea what - encoding the file is in, or even if the file is text data. + .. note:: + ``'b'`` mode flag is ignored (``self.FLAG_BINARY`` in + ``self._flags``), because SSH treats all files as binary, since we + have no idea what encoding the file is in, or even if the file is + text data. :param int size: maximum number of bytes to read :return: diff --git a/tests/test_sftp.py b/tests/test_sftp.py index 720b8215..c70d0cde 100755 --- a/tests/test_sftp.py +++ b/tests/test_sftp.py @@ -67,6 +67,18 @@ liver insulin receptors. Their sensitivity to insulin is, however, similarly decreased compared with chicken. ''' + +# Here is how unicode characters are encoded over 1 to 6 bytes in utf-8 +# U-00000000 - U-0000007F: 0xxxxxxx +# U-00000080 - U-000007FF: 110xxxxx 10xxxxxx +# U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx +# U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx +# U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx +# U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx +# Note that: hex(int('11000011',2)) == '0xc3' +# Thus, the following 2-bytes sequence is not valid utf8: "invalid continuation byte" +NON_UTF8_DATA = b'\xC3\xC3' + FOLDER = os.environ.get('TEST_FOLDER', 'temp-testing000') sftp = None @@ -466,7 +478,7 @@ class SFTPTest (unittest.TestCase): f.write('?\n') with sftp.open(FOLDER + '/happy.txt', 'r') as f: - self.assertEqual(f.readline(), u'full line?\n') + self.assertEqual(f.readline(), u('full line?\n')) self.assertEqual(f.read(7), b'partial') finally: try: @@ -747,6 +759,23 @@ class SFTPTest (unittest.TestCase): sftp.remove(FOLDER + '/test%file') + def test_O_non_utf8_data(self): + """Test write() and read() of non utf8 data""" + try: + with sftp.open('%s/nonutf8data' % FOLDER, 'w') as f: + f.write(NON_UTF8_DATA) + with sftp.open('%s/nonutf8data' % FOLDER, 'r') as f: + data = f.read() + self.assertEqual(data, NON_UTF8_DATA) + with sftp.open('%s/nonutf8data' % FOLDER, 'wb') as f: + f.write(NON_UTF8_DATA) + with sftp.open('%s/nonutf8data' % FOLDER, 'rb') as f: + data = f.read() + self.assertEqual(data, NON_UTF8_DATA) + finally: + sftp.remove('%s/nonutf8data' % FOLDER) + + if __name__ == '__main__': SFTPTest.init_loopback() # logging is required by test_N_file_with_percent -- cgit v1.2.3 From c7c1a24e3023a45cf6713e553c176e42a71a6d3d Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 24 Apr 2014 10:26:33 -0700 Subject: Fix some trailing whitespace --- paramiko/file.py | 2 +- tests/test_sftp.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/paramiko/file.py b/paramiko/file.py index 856cc101..3ebcfa39 100644 --- a/paramiko/file.py +++ b/paramiko/file.py @@ -124,7 +124,7 @@ class BufferedFile (object): file first). If the ``size`` argument is negative or omitted, read all the remaining data in the file. - .. note:: + .. note:: ``'b'`` mode flag is ignored (``self.FLAG_BINARY`` in ``self._flags``), because SSH treats all files as binary, since we have no idea what encoding the file is in, or even if the file is diff --git a/tests/test_sftp.py b/tests/test_sftp.py index c70d0cde..2b6aa3b6 100755 --- a/tests/test_sftp.py +++ b/tests/test_sftp.py @@ -69,8 +69,8 @@ decreased compared with chicken. # Here is how unicode characters are encoded over 1 to 6 bytes in utf-8 -# U-00000000 - U-0000007F: 0xxxxxxx -# U-00000080 - U-000007FF: 110xxxxx 10xxxxxx +# U-00000000 - U-0000007F: 0xxxxxxx +# U-00000080 - U-000007FF: 110xxxxx 10xxxxxx # U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx # U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx # U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- cgit v1.2.3 From 5837b7c21a10b4c0664412cae1f9604580ba5934 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 24 Apr 2014 10:26:46 -0700 Subject: Formatting --- paramiko/file.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/paramiko/file.py b/paramiko/file.py index 3ebcfa39..2238f0bf 100644 --- a/paramiko/file.py +++ b/paramiko/file.py @@ -287,7 +287,8 @@ class BufferedFile (object): Set the file's current position, like stdio's ``fseek``. Not all file objects support seeking. - .. note:: If a file is opened in append mode (``'a'`` or ``'a+'``), any seek + .. note:: + If a file is opened in append mode (``'a'`` or ``'a+'``), any seek operations will be undone at the next write (as the file position will move back to the end of the file). -- cgit v1.2.3 From c0667e1e6a1dd9b6cf2e47762b51d085417eb7c8 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Wed, 7 May 2014 13:39:39 -0700 Subject: Cut 1.11.6 --- paramiko/__init__.py | 2 +- setup.py | 2 +- sites/www/changelog.rst | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/paramiko/__init__.py b/paramiko/__init__.py index ce3f0cf9..25ec6679 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -23,7 +23,7 @@ if sys.version_info < (2, 5): __author__ = "Jeff Forcier " -__version__ = "1.11.5" +__version__ = "1.11.6" __version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/setup.py b/setup.py index 6222a7b0..6cb40de1 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,7 @@ if sys.platform == 'darwin': setup( name = "paramiko", - version = "1.11.5", + version = "1.11.6", description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index b84f7758..6ad85927 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,7 @@ Changelog ========= +* :release:`1.11.6 <2014-05-07>` * :bug:`-` Added self.args for exception classes. Used for unpickling. Related to (`Fabric #986 `_, `Fabric #714 `_). Thanks to Alex -- cgit v1.2.3 From 09e9d48db06b7e6eff090dc2cbbb94fef18a1b2c Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Wed, 7 May 2014 13:47:09 -0700 Subject: Cut 1.12.4 --- paramiko/__init__.py | 2 +- setup.py | 2 +- sites/www/changelog.rst | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/paramiko/__init__.py b/paramiko/__init__.py index 63d52bd3..d6a03898 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -23,7 +23,7 @@ if sys.version_info < (2, 5): __author__ = "Jeff Forcier " -__version__ = "1.12.3" +__version__ = "1.12.4" __version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/setup.py b/setup.py index 5fd9d044..04286b15 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ if sys.platform == 'darwin': setup( name = "paramiko", - version = "1.12.3", + version = "1.12.4", description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 3f8fbdc7..524cf0dc 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,7 @@ Changelog ========= +* :release:`1.12.4 <2014-05-07>` * :release:`1.11.6 <2014-05-07>` * :bug:`-` Added self.args for exception classes. Used for unpickling. Related to (`Fabric #986 `_, `Fabric -- cgit v1.2.3 From 7484a221803a3f9aa959d9fd02770ee9c2c90ad5 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Wed, 7 May 2014 14:14:05 -0700 Subject: Cut 1.13.1 --- paramiko/__init__.py | 2 +- setup.py | 2 +- sites/www/changelog.rst | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/paramiko/__init__.py b/paramiko/__init__.py index b1d9aaa9..22f1bc21 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -23,7 +23,7 @@ if sys.version_info < (2, 6): __author__ = "Jeff Forcier " -__version__ = "1.13.0" +__version__ = "1.13.1" __version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/setup.py b/setup.py index 4a858326..05dc98d5 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ if sys.platform == 'darwin': setup( name = "paramiko", - version = "1.13.0", + version = "1.13.1", description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index fbb3270f..a652e565 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,7 @@ Changelog ========= +* :release:`1.13.1 <2014-05-07>` * :release:`1.12.4 <2014-05-07>` * :release:`1.11.6 <2014-05-07>` * :bug:`-` `paramiko.file.BufferedFile.read` incorrectly returned text strings -- cgit v1.2.3 From ccb01f1981b8bf7dece06a5d572ef4c98330d8dc Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Wed, 7 May 2014 15:36:15 -0700 Subject: Need wheel to build wheels! --- dev-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-requirements.txt b/dev-requirements.txt index 91ae8549..88a32964 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -7,3 +7,4 @@ invocations>=0.5.0 sphinx>=1.1.3 alabaster>=0.4.0 releases>=0.5.2 +wheel==0.23.0 -- cgit v1.2.3 From 6d00c591cd30f1ae877ade16eaac14a05327cfe8 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Wed, 7 May 2014 16:09:55 -0700 Subject: Bump alabaster for things like travis_button --- dev-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 88a32964..e9052898 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -5,6 +5,6 @@ tox>=1.4,<1.5 invoke>=0.7.0 invocations>=0.5.0 sphinx>=1.1.3 -alabaster>=0.4.0 +alabaster>=0.6.0 releases>=0.5.2 wheel==0.23.0 -- cgit v1.2.3 From 951faed80b017e553a27c4cb98f210df44341f8f Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Wed, 7 May 2014 16:13:33 -0700 Subject: Cut 1.14 --- paramiko/__init__.py | 2 +- setup.py | 2 +- sites/www/changelog.rst | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/paramiko/__init__.py b/paramiko/__init__.py index 22f1bc21..4c62ad4a 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -23,7 +23,7 @@ if sys.version_info < (2, 6): __author__ = "Jeff Forcier " -__version__ = "1.13.1" +__version__ = "1.14.0" __version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/setup.py b/setup.py index 05dc98d5..c0f1e579 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ if sys.platform == 'darwin': setup( name = "paramiko", - version = "1.13.1", + version = "1.14.0", description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 52fe4ff3..f8a4d2c1 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,7 @@ Changelog ========= +* :release:`1.14.0 <2014-05-07>` * :release:`1.13.1 <2014-05-07>` * :release:`1.12.4 <2014-05-07>` * :release:`1.11.6 <2014-05-07>` -- cgit v1.2.3 From e811e715833373dd2f2ba898089695eee9c882ed Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Sun, 25 May 2014 14:57:58 -0700 Subject: We support 3.2 --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 9305bfb3..61c5c852 100644 --- a/README +++ b/README @@ -35,7 +35,7 @@ Requirements ------------ - Python 2.6 or better - this includes Python - 3.3 and higher as well. + 3.2 and higher as well. - pycrypto 2.1 or better - ecdsa 0.9 or better -- cgit v1.2.3 From 9ef02e1a97477a1476f64e690fb6bc21e78be037 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jul 2014 23:51:38 +0200 Subject: Support passing in "buffer" objects again where bytestrings are expected. This fixes bzr's use of paramiko. Fixes issue #343/#285. --- paramiko/py3compat.py | 4 ++++ tests/test_file.py | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/paramiko/py3compat.py b/paramiko/py3compat.py index 8842b988..57c096b2 100644 --- a/paramiko/py3compat.py +++ b/paramiko/py3compat.py @@ -39,6 +39,8 @@ if PY2: return s elif isinstance(s, unicode): return s.encode(encoding) + elif isinstance(s, buffer): + return s else: raise TypeError("Expected unicode or bytes, got %r" % s) @@ -49,6 +51,8 @@ if PY2: return s.decode(encoding) elif isinstance(s, unicode): return s + elif isinstance(s, buffer): + return s.decode(encoding) else: raise TypeError("Expected unicode or bytes, got %r" % s) diff --git a/tests/test_file.py b/tests/test_file.py index c6edd7af..22a34aca 100755 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -23,6 +23,7 @@ Some unit tests for the BufferedFile abstraction. import unittest from paramiko.file import BufferedFile from paramiko.common import linefeed_byte, crlf, cr_byte +import sys class LoopbackFile (BufferedFile): @@ -151,6 +152,15 @@ class BufferedFileTest (unittest.TestCase): b'need to close them again.\n') f.close() + def test_8_buffering(self): + """ + verify that buffered objects can be written + """ + if sys.version_info[0] == 2: + f = LoopbackFile('r+', 16) + f.write(buffer(b'Too small.')) + f.close() + if __name__ == '__main__': from unittest import main main() -- cgit v1.2.3 From 6d48018d11a2058213481fdfeed8887fccc31854 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 11 Aug 2014 10:31:02 -0700 Subject: Add FAQ about nonstandard SSH implementations --- sites/www/faq.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/sites/www/faq.rst b/sites/www/faq.rst index a7e80014..bf450f63 100644 --- a/sites/www/faq.rst +++ b/sites/www/faq.rst @@ -7,3 +7,20 @@ Which version should I use? I see multiple active releases. Please see :ref:`the installation docs ` which have an explicit section about this topic. + +Paramiko doesn't work with my Cisco, Windows or other non-Unix system! +====================================================================== + +In an ideal world, the developers would love to support every possible target +system. Unfortunately, volunteer development time and access to non-mainstream +platforms are limited, meaning that we can only fully support standard OpenSSH +implementations such as those found on the average Linux distribution (as well +as on Mac OS X and \*BSD.) + +Because of this, **we typically close bug reports for nonstandard SSH +implementations**. + +However, **closed does not imply locked** - affected users can still post +comments on such tickets - and **we will always consider actual patch +submissions for these issues**, provided they can get +1s from similarly +affected users and are proven to not break existing functionality. -- cgit v1.2.3 From dac6952331109bdab441040cc8b0136697252297 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 11 Aug 2014 10:55:46 -0700 Subject: Make links to Github more explicit --- sites/www/contact.rst | 1 + sites/www/contributing.rst | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/sites/www/contact.rst b/sites/www/contact.rst index 2b6583f5..7e6c947e 100644 --- a/sites/www/contact.rst +++ b/sites/www/contact.rst @@ -9,3 +9,4 @@ following ways: * Mailing list: ``paramiko@librelist.com`` (see `the LibreList homepage `_ for usage details). * This website - a blog section is forthcoming. +* Submit contributions on Github - see the :doc:`contributing` page. diff --git a/sites/www/contributing.rst b/sites/www/contributing.rst index 634c2b26..a44414e8 100644 --- a/sites/www/contributing.rst +++ b/sites/www/contributing.rst @@ -5,18 +5,22 @@ Contributing How to get the code =================== -Our primary Git repository is on Github at `paramiko/paramiko -`_; please follow their instructions for -cloning to your local system. (If you intend to submit patches/pull requests, -we recommend forking first, then cloning your fork. Github has excellent -documentation for all this.) +Our primary Git repository is on Github at `paramiko/paramiko`_; +please follow their instructions for cloning to your local system. (If you +intend to submit patches/pull requests, we recommend forking first, then +cloning your fork. Github has excellent documentation for all this.) How to submit bug reports or new code ===================================== Please see `this project-agnostic contribution guide -`_ - we follow it explicitly. +`_ - we follow it explicitly. Again, our code +repository and bug tracker is `on Github`_. Our current changelog is located in ``sites/www/changelog.rst`` - the top level files like ``ChangeLog.*`` and ``NEWS`` are historical only. + + +.. _paramiko/paramiko: +.. _on Github: https://github.com/paramiko/paramiko -- cgit v1.2.3 From 991d56bad32c1ea4eda6c86771a4a4b7bef00475 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 11 Aug 2014 11:40:20 -0700 Subject: Clarify FAQ --- sites/www/faq.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/www/faq.rst b/sites/www/faq.rst index bf450f63..a5d9b383 100644 --- a/sites/www/faq.rst +++ b/sites/www/faq.rst @@ -18,7 +18,7 @@ implementations such as those found on the average Linux distribution (as well as on Mac OS X and \*BSD.) Because of this, **we typically close bug reports for nonstandard SSH -implementations**. +implementations or host systems**. However, **closed does not imply locked** - affected users can still post comments on such tickets - and **we will always consider actual patch -- cgit v1.2.3 From 23c03b812242736bbfa1bf2e7780911ff180aaae Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Sun, 25 May 2014 14:57:58 -0700 Subject: We support 3.2 --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 9305bfb3..61c5c852 100644 --- a/README +++ b/README @@ -35,7 +35,7 @@ Requirements ------------ - Python 2.6 or better - this includes Python - 3.3 and higher as well. + 3.2 and higher as well. - pycrypto 2.1 or better - ecdsa 0.9 or better -- cgit v1.2.3 From a429e17e8e5cc3f5d442d374fb4843badfd4dd48 Mon Sep 17 00:00:00 2001 From: Olle Lundberg Date: Thu, 14 Aug 2014 12:00:46 +0200 Subject: Join the threads with a low timeout. Instead of using private methods on the threading class, let the thread join, but with a low timeout. --- test.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test.py b/test.py index 2b3d4ed4..92a3e6d0 100755 --- a/test.py +++ b/test.py @@ -149,10 +149,7 @@ def main(): # TODO: make that not a problem, jeez for thread in threading.enumerate(): if thread is not threading.currentThread(): - if PY2: - thread._Thread__stop() - else: - thread._stop() + thread.join(timeout=1) # Exit correctly if not result.wasSuccessful(): sys.exit(1) -- cgit v1.2.3 From 075f5c0338cf48e2b0280dd97b35aa6e40d94b3d Mon Sep 17 00:00:00 2001 From: Olle Lundberg Date: Thu, 14 Aug 2014 12:03:32 +0200 Subject: Support py3.4. --- .travis.yml | 1 + setup.py | 1 + tox.ini | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7042570f..c7abce9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ python: - "2.7" - "3.2" - "3.3" + - "3.4" install: # Self-install for setup.py-driven deps - pip install -e . diff --git a/setup.py b/setup.py index c0f1e579..163c44be 100644 --- a/setup.py +++ b/setup.py @@ -79,6 +79,7 @@ setup( 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', ], **kw ) diff --git a/tox.ini b/tox.ini index 43c391dd..83704dfc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py26,py27,py32,py33 +envlist = py26,py27,py32,py33,py34 [testenv] commands = pip install --use-mirrors -q -r tox-requirements.txt -- cgit v1.2.3 From d8a71fcdf0b57837632ccfa806386443fdb6dcc2 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 18 Aug 2014 18:36:59 -0700 Subject: Sphinx conf cleanup --- sites/www/conf.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/sites/www/conf.py b/sites/www/conf.py index bdb5929a..0b0fb85c 100644 --- a/sites/www/conf.py +++ b/sites/www/conf.py @@ -12,13 +12,10 @@ extensions.append('releases') releases_release_uri = "https://github.com/paramiko/paramiko/tree/v%s" releases_issue_uri = "https://github.com/paramiko/paramiko/issues/%s" -# Intersphinx for referencing API/usage docs -extensions.append('sphinx.ext.intersphinx') # Default is 'local' building, but reference the public docs site when building # under RTD. target = join(dirname(__file__), '..', 'docs', '_build') if os.environ.get('READTHEDOCS') == 'True': - # TODO: switch to docs.paramiko.org post go-live of sphinx API docs target = 'http://docs.paramiko.org/en/latest/' intersphinx_mapping['docs'] = (target, None) -- cgit v1.2.3 From 178e43060c52b9f65026a5ec57bbe5fae166ba4e Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 21 Aug 2014 09:28:58 -0700 Subject: This isn't worth having and then always forgetting about --- sites/www/installing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/www/installing.rst b/sites/www/installing.rst index a28ce6cd..546aad9d 100644 --- a/sites/www/installing.rst +++ b/sites/www/installing.rst @@ -32,7 +32,7 @@ Release lines Users desiring stability may wish to pin themselves to a specific release line once they first start using Paramiko; to assist in this, we guarantee bugfixes -for at least the last 2-3 releases including the latest stable one. This currently means Paramiko **1.11** through **1.13**. +for at least the last 2-3 releases including the latest stable one. If you're unsure which version to install, we have suggestions: -- cgit v1.2.3 From e941d56e8a385f4f2ef5c0e9a77e66c844b5a729 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Thu, 21 Aug 2014 09:30:12 -0700 Subject: More tweaks - don't make it sound like we routinely support >3, we don't --- sites/www/installing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/www/installing.rst b/sites/www/installing.rst index 546aad9d..729147c5 100644 --- a/sites/www/installing.rst +++ b/sites/www/installing.rst @@ -32,7 +32,7 @@ Release lines Users desiring stability may wish to pin themselves to a specific release line once they first start using Paramiko; to assist in this, we guarantee bugfixes -for at least the last 2-3 releases including the latest stable one. +for the last 2-3 releases including the latest stable one. If you're unsure which version to install, we have suggestions: -- cgit v1.2.3 From 2a88241ea7ed3facf730678ef28a8281903cf9a9 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 16:27:15 -0700 Subject: Add a plus to our 3.3 support to denote 3.4 and on --- sites/www/installing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/www/installing.rst b/sites/www/installing.rst index 729147c5..052825c4 100644 --- a/sites/www/installing.rst +++ b/sites/www/installing.rst @@ -16,7 +16,7 @@ via `pip `_:: Users who want the bleeding edge can install the development version via ``pip install paramiko==dev``. -We currently support **Python 2.6, 2.7 and 3.3** (Python **3.2** should also +We currently support **Python 2.6, 2.7 and 3.3+** (Python **3.2** should also work but has a less-strong compatibility guarantee from us.) Users on Python 2.5 or older are urged to upgrade. -- cgit v1.2.3 From 5d010cd8c496e1ed7e13e7110f7fca9632c08e47 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 16:28:02 -0700 Subject: Changelog re #371 --- sites/www/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index f8a4d2c1..5ed0c961 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,8 @@ Changelog ========= +* :support:`371` Add Travis support & docs update for Python 3.4. Thanks to + Olle Lundberg. * :release:`1.14.0 <2014-05-07>` * :release:`1.13.1 <2014-05-07>` * :release:`1.12.4 <2014-05-07>` -- cgit v1.2.3 From fd1e162243898e34545ef5c1985bedee16174981 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 21:59:59 -0700 Subject: Changelog re #285, re #352 --- sites/www/changelog.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 5ed0c961..2e2d2f63 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,12 @@ Changelog ========= +* :bug:`285` (also :issue:`352`) Update our Python 3 ``b()`` compatibility shim + to handle ``buffer`` objects correctly; this fixes a frequently reported + issue affecting many users, including users of the ``bzr`` software suite. + Thanks to ``@basictheprogram`` for the initial report, Jelmer Vernooij for + the fix and Andrew Starr-Bochicchio & Jeremy T. Bouse (among others) for + discussion & feedback. * :support:`371` Add Travis support & docs update for Python 3.4. Thanks to Olle Lundberg. * :release:`1.14.0 <2014-05-07>` -- cgit v1.2.3 From c3ba66b90e9da0cce9c88fbc45894fde492edfd0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jul 2014 23:51:38 +0200 Subject: Support passing in "buffer" objects again where bytestrings are expected. This fixes bzr's use of paramiko. Fixes issue #343/#285. --- paramiko/py3compat.py | 4 ++++ tests/test_file.py | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/paramiko/py3compat.py b/paramiko/py3compat.py index 8842b988..57c096b2 100644 --- a/paramiko/py3compat.py +++ b/paramiko/py3compat.py @@ -39,6 +39,8 @@ if PY2: return s elif isinstance(s, unicode): return s.encode(encoding) + elif isinstance(s, buffer): + return s else: raise TypeError("Expected unicode or bytes, got %r" % s) @@ -49,6 +51,8 @@ if PY2: return s.decode(encoding) elif isinstance(s, unicode): return s + elif isinstance(s, buffer): + return s.decode(encoding) else: raise TypeError("Expected unicode or bytes, got %r" % s) diff --git a/tests/test_file.py b/tests/test_file.py index c6edd7af..22a34aca 100755 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -23,6 +23,7 @@ Some unit tests for the BufferedFile abstraction. import unittest from paramiko.file import BufferedFile from paramiko.common import linefeed_byte, crlf, cr_byte +import sys class LoopbackFile (BufferedFile): @@ -151,6 +152,15 @@ class BufferedFileTest (unittest.TestCase): b'need to close them again.\n') f.close() + def test_8_buffering(self): + """ + verify that buffered objects can be written + """ + if sys.version_info[0] == 2: + f = LoopbackFile('r+', 16) + f.write(buffer(b'Too small.')) + f.close() + if __name__ == '__main__': from unittest import main main() -- cgit v1.2.3 From d05ca17db876055a5f584e720b1b0733116b4365 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 21:59:59 -0700 Subject: Changelog re #285, re #352 Conflicts: sites/www/changelog.rst --- sites/www/changelog.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index a652e565..5c8e02f4 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,12 @@ Changelog ========= +* :bug:`285` (also :issue:`352`) Update our Python 3 ``b()`` compatibility shim + to handle ``buffer`` objects correctly; this fixes a frequently reported + issue affecting many users, including users of the ``bzr`` software suite. + Thanks to ``@basictheprogram`` for the initial report, Jelmer Vernooij for + the fix and Andrew Starr-Bochicchio & Jeremy T. Bouse (among others) for + discussion & feedback. * :release:`1.13.1 <2014-05-07>` * :release:`1.12.4 <2014-05-07>` * :release:`1.11.6 <2014-05-07>` -- cgit v1.2.3 From ab8ea174501023fda3686d836057a6f8b475ab61 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 22:25:40 -0700 Subject: Minor refactor, re #169 --- paramiko/sftp_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 1caaf165..cbef8f71 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -584,7 +584,7 @@ class SFTPClient(BaseSFTP): """ file_size = os.stat(localpath).st_size with open(localpath, 'rb') as fl: - return self.putfo(fl, remotepath, os.stat(localpath).st_size, callback, confirm) + return self.putfo(fl, remotepath, file_size, callback, confirm) def getfo(self, remotepath, fl, callback=None): """ -- cgit v1.2.3 From 87f6f56196b0b384c906db96ef5593c5cb6a0c61 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 22:26:33 -0700 Subject: Changelog re #169 --- sites/www/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 5c8e02f4..b9d0df0b 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,8 @@ Changelog ========= +* :support:`169 backported` Minor refactor of + `paramiko.sftp_client.SFTPClient.put` thanks to Abhinav Upadhyay. * :bug:`285` (also :issue:`352`) Update our Python 3 ``b()`` compatibility shim to handle ``buffer`` objects correctly; this fixes a frequently reported issue affecting many users, including users of the ``bzr`` software suite. -- cgit v1.2.3 From 5fc6969e23ec5e013f432e4efbe12d771150c1e1 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 22:32:21 -0700 Subject: Fix docstrings re: addition of `getfo`/`putfo`, closes #229 --- paramiko/sftp_client.py | 8 ++------ sites/www/changelog.rst | 2 ++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index cbef8f71..2ff2d51d 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -534,9 +534,7 @@ class SFTPClient(BaseSFTP): an `.SFTPAttributes` object containing attributes about the given file. - .. versionadded:: 1.4 - .. versionchanged:: 1.7.4 - Began returning rich attribute objects. + .. versionadded:: 1.10 """ with self.file(remotepath, 'wb') as fr: fr.set_pipelined(True) @@ -601,9 +599,7 @@ class SFTPClient(BaseSFTP): the bytes transferred so far and the total bytes to be transferred :return: the `number ` of bytes written to the opened file object - .. versionadded:: 1.4 - .. versionchanged:: 1.7.4 - Added the ``callable`` param. + .. versionadded:: 1.10 """ with self.open(remotepath, 'rb') as fr: file_size = self.stat(remotepath).st_size diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index b9d0df0b..cdd513f4 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,8 @@ Changelog ========= +* :support:`229` Fix a couple of incorrectly-copied docstrings' ``.. + versionadded::`` RST directives. Thanks to Aarni Koskela for the catch. * :support:`169 backported` Minor refactor of `paramiko.sftp_client.SFTPClient.put` thanks to Abhinav Upadhyay. * :bug:`285` (also :issue:`352`) Update our Python 3 ``b()`` compatibility shim -- cgit v1.2.3 From 12e752d11aa22ee6ba959115725e386ca779c1cb Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 22:44:54 -0700 Subject: Rework re #239 to work off post-1.13 codebase. Closes #239 --- paramiko/config.py | 2 +- sites/www/changelog.rst | 2 ++ tests/test_util.py | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/paramiko/config.py b/paramiko/config.py index 77fa13d7..f650ee24 100644 --- a/paramiko/config.py +++ b/paramiko/config.py @@ -55,7 +55,7 @@ class SSHConfig (object): """ host = {"host": ['*'], "config": {}} for line in file_obj: - line = line.rstrip('\n').lstrip() + line = line.rstrip('\r\n').lstrip() if (line == '') or (line[0] == '#'): continue if '=' in line: diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index cdd513f4..903e6378 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,8 @@ Changelog ========= +* :bug:`239` Add Windows-style CRLF support to SSH config file parsing. Props + to Christopher Swenson. * :support:`229` Fix a couple of incorrectly-copied docstrings' ``.. versionadded::`` RST directives. Thanks to Aarni Koskela for the catch. * :support:`169 backported` Minor refactor of diff --git a/tests/test_util.py b/tests/test_util.py index 6bde4045..ecf8db72 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -338,3 +338,9 @@ IdentityFile something_%l_using_fqdn """ config = paramiko.util.parse_ssh_config(StringIO(test_config)) assert config.lookup('meh') # will die during lookup() if bug regresses + + def test_13_config_dos_crlf_succeeds(self): + config_file = StringIO("host abcqwerty\r\nHostName 127.0.0.1\r\n") + config = paramiko.SSHConfig() + config.parse(config_file) + self.assertEqual(config.lookup("abcqwerty")["hostname"], "127.0.0.1") -- cgit v1.2.3 From 16b820aede0d3050bc8c96ab59f0aa9a79bebcdb Mon Sep 17 00:00:00 2001 From: Sigmund Augdal Date: Sat, 22 Feb 2014 15:52:53 +0100 Subject: Don't hash the input hostname when checking a host key if the input hostname is already hashed This happens in the loop checking if a hostkey is already loaded when loading host key files. This reduces time to load host keys file with about two seconds for me --- paramiko/hostkeys.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paramiko/hostkeys.py b/paramiko/hostkeys.py index f32fbeb6..7c6a5aa5 100644 --- a/paramiko/hostkeys.py +++ b/paramiko/hostkeys.py @@ -176,7 +176,7 @@ class HostKeys (MutableMapping): entries = [] for e in self._entries: for h in e.hostnames: - if h.startswith('|1|') and constant_time_bytes_eq(self.hash_host(hostname, h), h) or h == hostname: + if h.startswith('|1|') and not hostname.startswith('|1|') and constant_time_bytes_eq(self.hash_host(hostname, h), h) or h == hostname: entries.append(e) if len(entries) == 0: return None -- cgit v1.2.3 From 118d581f92b1aa49a482c68faa73df0c8967b3c4 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 22:58:58 -0700 Subject: Changelog re #272 --- sites/www/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 903e6378..99115727 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,10 @@ Changelog ========= +* :bug:`272` Fix a bug where ``known_hosts`` parsing hashed the input hostname + as well as the hostnames from the ``known_hosts`` file, on every comparison. + Thanks to ``@sigmunau`` for final patch and ``@ostacey`` for the original + report. * :bug:`239` Add Windows-style CRLF support to SSH config file parsing. Props to Christopher Swenson. * :support:`229` Fix a couple of incorrectly-copied docstrings' ``.. -- cgit v1.2.3 From adaf8a2c36bf37aa98c347874316ef1809dc40a3 Mon Sep 17 00:00:00 2001 From: Simon Percivall Date: Tue, 15 Apr 2014 11:17:24 +0200 Subject: Set Transport.active to False early in Transport.__init__. --- paramiko/transport.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/paramiko/transport.py b/paramiko/transport.py index 1471b543..d904da1d 100644 --- a/paramiko/transport.py +++ b/paramiko/transport.py @@ -164,6 +164,8 @@ class Transport (threading.Thread): :param socket sock: a socket or socket-like object to create the session over. """ + self.active = False + if isinstance(sock, string_types): # convert "host:port" into (host, port) hl = sock.split(':', 1) @@ -220,7 +222,6 @@ class Transport (threading.Thread): self.H = None self.K = None - self.active = False self.initial_kex_done = False self.in_kex = False self.authenticated = False -- cgit v1.2.3 From c7ffe1718a3bae232b7ecef959545dac9f729095 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 23:07:57 -0700 Subject: Changelog re #312, closes #312 --- sites/www/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 99115727..b315b0d7 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,10 @@ Changelog ========= +* :bug:`312` `paramiko.transport.Transport` had a bug in its ``__repr__`` which + surfaces during errors encountered within its ``__init__``, causing + problematic tracebacks in such situations. Thanks to Simon Percivall for + catch & patch. * :bug:`272` Fix a bug where ``known_hosts`` parsing hashed the input hostname as well as the hostnames from the ``known_hosts`` file, on every comparison. Thanks to ``@sigmunau`` for final patch and ``@ostacey`` for the original -- cgit v1.2.3 From 488cd21f6bc6bdf9e91ac891c4247897acc3bcb5 Mon Sep 17 00:00:00 2001 From: Roy Wellington Ⅳ Date: Wed, 7 May 2014 16:21:49 -0700 Subject: Fix some minor typos. --- paramiko/channel.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/paramiko/channel.py b/paramiko/channel.py index e10ddbac..23323650 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -279,7 +279,7 @@ class Channel (object): def recv_exit_status(self): """ Return the exit status from the process on the server. This is - mostly useful for retrieving the reults of an `exec_command`. + mostly useful for retrieving the results of an `exec_command`. If the command hasn't finished yet, this method will wait until it does, or until the channel is closed. If no exit status is provided by the server, -1 is returned. @@ -329,7 +329,7 @@ class Channel (object): If you omit the auth_cookie, a new secure random 128-bit value will be generated, used, and returned. You will need to use this value to verify incoming x11 requests and replace them with the actual local - x11 cookie (which requires some knoweldge of the x11 protocol). + x11 cookie (which requires some knowledge of the x11 protocol). If a handler is passed in, the handler is called from another thread whenever a new x11 connection arrives. The default handler queues up @@ -338,7 +338,7 @@ class Channel (object): handler(channel: Channel, (address: str, port: int)) - :param int screen_number: the x11 screen number (0, 10, etc) + :param int screen_number: the x11 screen number (0, 10, etc.) :param str auth_protocol: the name of the X11 authentication method used; if none is given, ``"MIT-MAGIC-COOKIE-1"`` is used @@ -743,10 +743,10 @@ class Channel (object): :raises socket.timeout: if sending stalled for longer than the timeout set by `settimeout`. :raises socket.error: - if an error occured before the entire string was sent. + if an error occurred before the entire string was sent. .. note:: - If the channel is closed while only part of the data hase been + If the channel is closed while only part of the data has been sent, there is no way to determine how much data (if any) was sent. This is irritating, but identically follows Python's API. """ @@ -770,7 +770,7 @@ class Channel (object): :raises socket.timeout: if sending stalled for longer than the timeout set by `settimeout`. :raises socket.error: - if an error occured before the entire string was sent. + if an error occurred before the entire string was sent. .. versionadded:: 1.1 """ @@ -811,7 +811,7 @@ class Channel (object): def fileno(self): """ Returns an OS-level file descriptor which can be used for polling, but - but not for reading or writing. This is primaily to allow Python's + but not for reading or writing. This is primarily to allow Python's ``select`` module to work. The first time ``fileno`` is called on a channel, a pipe is created to -- cgit v1.2.3 From 77919c6c25d9016c74537ea9b901cedc19050983 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 23:15:22 -0700 Subject: Changelog re #324, closes #324 --- sites/www/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index b315b0d7..6979b97e 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,8 @@ Changelog ========= +* :support:`324 backported` A bevvy of documentation typo fixes, courtesy of Roy + Wellington. * :bug:`312` `paramiko.transport.Transport` had a bug in its ``__repr__`` which surfaces during errors encountered within its ``__init__``, causing problematic tracebacks in such situations. Thanks to Simon Percivall for -- cgit v1.2.3 From 1fa69c7003bac49c22721ac694fe399f369ece8a Mon Sep 17 00:00:00 2001 From: w3iBStime Date: Thu, 19 Jun 2014 15:26:53 -0500 Subject: Updating doco for sftp_client.put() Adding a note to indicate that the remotepath should include a filename. --- paramiko/sftp_client.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 2ff2d51d..99a29e36 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -564,7 +564,9 @@ class SFTPClient(BaseSFTP): The SFTP operations use pipelining for speed. :param str localpath: the local file to copy - :param str remotepath: the destination path on the SFTP server + :param str remotepath: the destination path on the SFTP server. Note + that the filename should be included. Only specifying a directory + may result in an error. :param callable callback: optional callback function (form: ``func(int, int)``) that accepts the bytes transferred so far and the total bytes to be transferred -- cgit v1.2.3 From c50d023c91210eb25416bf5f3a4e05353cb16ca4 Mon Sep 17 00:00:00 2001 From: Olle Lundberg Date: Fri, 15 Aug 2014 15:53:07 +0200 Subject: Don't make unnecessary calls to LazyFqdn.__str__. Before this patch we always tried to expand variables in the config even if they weren't present. This meant that we made an expensive call to LazyFqdn.__str__ the first iteration of the expand loop, stealing precious cpu and user time. We now check that the expansion actually exists in the config before expanding it, this will speed up the case where %l is not used. This fixes #338 --- paramiko/config.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/paramiko/config.py b/paramiko/config.py index f650ee24..96ec9ef7 100644 --- a/paramiko/config.py +++ b/paramiko/config.py @@ -83,7 +83,7 @@ class SSHConfig (object): #identityfile, localforward, remoteforward keys are special cases, since they are allowed to be # specified multiple times and they should be tried in order # of specification. - + elif key in ['identityfile', 'localforward', 'remoteforward']: if key in host['config']: host['config'][key].append(value) @@ -200,10 +200,12 @@ class SSHConfig (object): for find, replace in replacements[k]: if isinstance(config[k], list): for item in range(len(config[k])): - config[k][item] = config[k][item].\ - replace(find, str(replace)) + if find in config[k][item]: + config[k][item] = config[k][item].\ + replace(find, str(replace)) else: - config[k] = config[k].replace(find, str(replace)) + if find in config[k]: + config[k] = config[k].replace(find, str(replace)) return config -- cgit v1.2.3 From 3908baad6e1d6d4fc62da24111cd466ce5cb9a88 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 23:34:13 -0700 Subject: Changelog re #376, closes #376 --- sites/www/changelog.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 6979b97e..9258cfec 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,9 @@ Changelog ========= +* :bug:`376` Be less aggressive about expanding variables in ``ssh_config`` + files, which results in a speedup of SSH config parsing. Credit to Olle + Lundberg. * :support:`324 backported` A bevvy of documentation typo fixes, courtesy of Roy Wellington. * :bug:`312` `paramiko.transport.Transport` had a bug in its ``__repr__`` which -- cgit v1.2.3 From 1b69e0f4095883ef3f282552fde12dfb00ebdda4 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 23:42:21 -0700 Subject: Cut 1.13.2 --- paramiko/__init__.py | 2 +- setup.py | 2 +- sites/www/changelog.rst | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/paramiko/__init__.py b/paramiko/__init__.py index 22f1bc21..d86b868b 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -23,7 +23,7 @@ if sys.version_info < (2, 6): __author__ = "Jeff Forcier " -__version__ = "1.13.1" +__version__ = "1.13.2" __version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/setup.py b/setup.py index 05dc98d5..082a843e 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ if sys.platform == 'darwin': setup( name = "paramiko", - version = "1.13.1", + version = "1.13.2", description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 9258cfec..9c519c03 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,7 @@ Changelog ========= +* :release:`1.13.2 <2014-08-25>` * :bug:`376` Be less aggressive about expanding variables in ``ssh_config`` files, which results in a speedup of SSH config parsing. Credit to Olle Lundberg. -- cgit v1.2.3 From d7b93df7aaf9f409da7578a107829c138d042121 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 23:43:48 -0700 Subject: Cut 1.14.1 --- paramiko/__init__.py | 2 +- setup.py | 2 +- sites/www/changelog.rst | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/paramiko/__init__.py b/paramiko/__init__.py index 4c62ad4a..2ebc8a65 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -23,7 +23,7 @@ if sys.version_info < (2, 6): __author__ = "Jeff Forcier " -__version__ = "1.14.0" +__version__ = "1.14.1" __version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/setup.py b/setup.py index c0f1e579..38e444f5 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ if sys.platform == 'darwin': setup( name = "paramiko", - version = "1.14.0", + version = "1.14.1", description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index c4c1e698..0fcde10f 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,7 @@ Changelog ========= +* :release:`1.14.1 <2014-08-25>` * :release:`1.13.2 <2014-08-25>` * :bug:`376` Be less aggressive about expanding variables in ``ssh_config`` files, which results in a speedup of SSH config parsing. Credit to Olle -- cgit v1.2.3 From 28b7db145fed32840f8d2edea8fdce27dc00ca26 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 23:48:28 -0700 Subject: Consolidate version info. Closes #249 --- paramiko/__init__.py | 3 +-- paramiko/_version.py | 2 ++ setup.py | 9 ++++++++- sites/www/changelog.rst | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 paramiko/_version.py diff --git a/paramiko/__init__.py b/paramiko/__init__.py index 2ebc8a65..65f6f8a2 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -17,14 +17,13 @@ # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. import sys +from paramiko._version import __version__, __version_info__ if sys.version_info < (2, 6): raise RuntimeError('You need Python 2.6+ for this module.') __author__ = "Jeff Forcier " -__version__ = "1.14.1" -__version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/paramiko/_version.py b/paramiko/_version.py new file mode 100644 index 00000000..a7857b09 --- /dev/null +++ b/paramiko/_version.py @@ -0,0 +1,2 @@ +__version_info__ = (1, 15, 0) +__version__ = '.'.join(map(str, __version_info__)) diff --git a/setup.py b/setup.py index 3d8268d1..13386c8e 100644 --- a/setup.py +++ b/setup.py @@ -54,9 +54,16 @@ if sys.platform == 'darwin': setup_helper.install_custom_make_tarball() +# Version info -- read without importing +_locals = {} +with open('paramiko/_version.py') as fp: + exec(fp.read(), None, _locals) +version = _locals['__version__'] + + setup( name = "paramiko", - version = "1.14.1", + version = version, description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 089ec30e..b6fa7ccc 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,8 @@ Changelog ========= +* :support:`249` Consolidate version information into one spot. Thanks to Gabi + Davar for the reminder. * :release:`1.14.1 <2014-08-25>` * :release:`1.13.2 <2014-08-25>` * :bug:`376` Be less aggressive about expanding variables in ``ssh_config`` -- cgit v1.2.3 From 38332e0054eddbb0a0a9812894920e38a721eab2 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Tue, 26 Aug 2014 00:04:22 -0700 Subject: Fix up release task --- dev-requirements.txt | 2 +- tasks.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 88a32964..19cf7503 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -2,7 +2,7 @@ tox>=1.4,<1.5 # For newer tasks like building Sphinx docs. # NOTE: Requires Python >=2.6 -invoke>=0.7.0 +invoke>=0.7.0,<0.8 invocations>=0.5.0 sphinx>=1.1.3 alabaster>=0.4.0 diff --git a/tasks.py b/tasks.py index 38282b8e..94bf0aa2 100644 --- a/tasks.py +++ b/tasks.py @@ -36,8 +36,10 @@ def coverage(ctx): # Until we stop bundling docs w/ releases. Need to discover use cases first. -@task('docs') # Will invoke the API doc site build +@task def release(ctx): + # Build docs first. Use terribad workaround pending invoke #146 + ctx.run("inv docs") # Move the built docs into where Epydocs used to live target = 'docs' rmtree(target, ignore_errors=True) -- cgit v1.2.3 From 9014c735fc94d133c5d9aada93d43f1f5d1145f2 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Tue, 26 Aug 2014 00:14:02 -0700 Subject: Forgot to mark one support-bug as backported --- sites/www/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 9c519c03..1ca3dfef 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -18,7 +18,7 @@ Changelog report. * :bug:`239` Add Windows-style CRLF support to SSH config file parsing. Props to Christopher Swenson. -* :support:`229` Fix a couple of incorrectly-copied docstrings' ``.. +* :support:`229 backported` Fix a couple of incorrectly-copied docstrings' ``.. versionadded::`` RST directives. Thanks to Aarni Koskela for the catch. * :support:`169 backported` Minor refactor of `paramiko.sftp_client.SFTPClient.put` thanks to Abhinav Upadhyay. -- cgit v1.2.3 From b641c69a80e2bd4737c636e7edd0918d6753c3d0 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Tue, 26 Aug 2014 12:50:10 -0700 Subject: Backport #378 to 1.13, closes #378 --- paramiko/config.py | 12 +++++++----- sites/www/changelog.rst | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/paramiko/config.py b/paramiko/config.py index 96ec9ef7..30e000e7 100644 --- a/paramiko/config.py +++ b/paramiko/config.py @@ -56,7 +56,7 @@ class SSHConfig (object): host = {"host": ['*'], "config": {}} for line in file_obj: line = line.rstrip('\r\n').lstrip() - if (line == '') or (line[0] == '#'): + if not line or line.startswith('#'): continue if '=' in line: # Ensure ProxyCommand gets properly split @@ -90,7 +90,7 @@ class SSHConfig (object): else: host['config'][key] = [value] elif key not in host['config']: - host['config'].update({key: value}) + host['config'][key] = value self._config.append(host) def lookup(self, hostname): @@ -111,8 +111,10 @@ class SSHConfig (object): :param str hostname: the hostname to lookup """ - matches = [config for config in self._config if - self._allowed(hostname, config['host'])] + matches = [ + config for config in self._config + if self._allowed(config['host'], hostname) + ] ret = {} for match in matches: @@ -128,7 +130,7 @@ class SSHConfig (object): ret = self._expand_variables(ret, hostname) return ret - def _allowed(self, hostname, hosts): + def _allowed(self, hosts, hostname): match = False for host in hosts: if host.startswith('!') and fnmatch.fnmatch(hostname, host[1:]): diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 1ca3dfef..0cbc933f 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,8 @@ Changelog ========= +* :support:`378 backported` Minor code cleanup in the SSH config module + courtesy of Olle Lundberg. * :release:`1.13.2 <2014-08-25>` * :bug:`376` Be less aggressive about expanding variables in ``ssh_config`` files, which results in a speedup of SSH config parsing. Credit to Olle -- cgit v1.2.3 From 162eebf704b5111d34f430488868d3185d51ba21 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Mon, 25 Aug 2014 23:48:28 -0700 Subject: Consolidate version info. Closes #249 Conflicts: paramiko/__init__.py setup.py sites/www/changelog.rst --- paramiko/__init__.py | 3 +-- paramiko/_version.py | 2 ++ setup.py | 9 ++++++++- sites/www/changelog.rst | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 paramiko/_version.py diff --git a/paramiko/__init__.py b/paramiko/__init__.py index d86b868b..65f6f8a2 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -17,14 +17,13 @@ # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. import sys +from paramiko._version import __version__, __version_info__ if sys.version_info < (2, 6): raise RuntimeError('You need Python 2.6+ for this module.') __author__ = "Jeff Forcier " -__version__ = "1.13.2" -__version_info__ = tuple([ int(d) for d in __version__.split(".") ]) __license__ = "GNU Lesser General Public License (LGPL)" diff --git a/paramiko/_version.py b/paramiko/_version.py new file mode 100644 index 00000000..0402fcf2 --- /dev/null +++ b/paramiko/_version.py @@ -0,0 +1,2 @@ +__version_info__ = (1, 13, 3) +__version__ = '.'.join(map(str, __version_info__)) diff --git a/setup.py b/setup.py index 082a843e..235fd0e3 100644 --- a/setup.py +++ b/setup.py @@ -54,9 +54,16 @@ if sys.platform == 'darwin': setup_helper.install_custom_make_tarball() +# Version info -- read without importing +_locals = {} +with open('paramiko/_version.py') as fp: + exec(fp.read(), None, _locals) +version = _locals['__version__'] + + setup( name = "paramiko", - version = "1.13.2", + version = version, description = "SSH2 protocol library", long_description = longdesc, author = "Jeff Forcier", diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 0cbc933f..0f79775c 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -4,6 +4,8 @@ Changelog * :support:`378 backported` Minor code cleanup in the SSH config module courtesy of Olle Lundberg. +* :support:`249` Consolidate version information into one spot. Thanks to Gabi + Davar for the reminder. * :release:`1.13.2 <2014-08-25>` * :bug:`376` Be less aggressive about expanding variables in ``ssh_config`` files, which results in a speedup of SSH config parsing. Credit to Olle -- cgit v1.2.3 From 23fc8a76da7cd376aef1f27bdd5fc4d7416ced04 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 10:10:15 -0700 Subject: No notices for travis irc notifications --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7042570f..801356e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,6 @@ notifications: - "%{repository}@%{branch}: %{message} (%{build_url})" on_success: change on_failure: change - use_notice: true email: false after_success: - coveralls -- cgit v1.2.3 From 5f73547aa5fa8f677f3d9064d2cd95b5979a3767 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 10:11:15 -0700 Subject: Nuke old comment --- dev-requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 19cf7503..a21a48ed 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,7 +1,6 @@ # Older junk tox>=1.4,<1.5 # For newer tasks like building Sphinx docs. -# NOTE: Requires Python >=2.6 invoke>=0.7.0,<0.8 invocations>=0.5.0 sphinx>=1.1.3 -- cgit v1.2.3 From 43c5cdaa3094c59718c8df69b1de834aee15485c Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 10:12:40 -0700 Subject: s/gittip/gratipay/ --- dev-requirements.txt | 2 +- sites/shared_conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index a21a48ed..7a0ccbc5 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -4,6 +4,6 @@ tox>=1.4,<1.5 invoke>=0.7.0,<0.8 invocations>=0.5.0 sphinx>=1.1.3 -alabaster>=0.4.0 +alabaster>=0.6.1 releases>=0.5.2 wheel==0.23.0 diff --git a/sites/shared_conf.py b/sites/shared_conf.py index 69908388..4a6a5c4e 100644 --- a/sites/shared_conf.py +++ b/sites/shared_conf.py @@ -12,7 +12,7 @@ html_theme_options = { 'description': "A Python implementation of SSHv2.", 'github_user': 'paramiko', 'github_repo': 'paramiko', - 'gittip_user': 'bitprophet', + 'gratipay_user': 'bitprophet', 'analytics_id': 'UA-18486793-2', 'travis_button': True, } -- cgit v1.2.3 From 0b9280f5994c4bfc0504452276464d35b04370f1 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 11:16:16 -0700 Subject: Update docstring for listdir_iter --- paramiko/sftp_client.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 252e7b96..39f08fbc 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -198,22 +198,17 @@ class SFTPClient(BaseSFTP): def listdir_iter(self, path='.', read_ahead_requests=50): """ - Generator yielding L{SFTPAttributes} objects corresponding to - files in the given C{path}. Files are yielded in arbitrary order. It does - not include the special entries C{'.'} and C{'..'} even if they are - present in the folder. + Generator version of `.listdir_attr`. - The returned L{SFTPAttributes} objects will each have an additional - field: C{longname}, which may contain a formatted string of the file's - attributes, in unix format. The content of this string will probably - depend on the SFTP server implementation. + See the API docs for `.listdir_attr` for overall details. - @param path: path to list (defaults to C{'.'}) - @type path: str - @return: Yields L{SFTPAttributes} - @rtype: L{SFTPAttributes} + This function adds one more kwarg on top of `.listdir_attr`: + ``read_ahead_requests``, an integer controlling how many + ``SSH_FXP_READDIR`` requests are made to the server. The default of 50 + should suffice for most file listings as each request/response cycle + may contain multiple files (dependant on server implementation.) - @since: 1.9 + .. versionadded:: 1.15 """ path = self._adjust_cwd(path) self._log(DEBUG, 'listdir(%r)' % path) -- cgit v1.2.3 From f4de3307b1133c0b207f5af40227c64a8cb5389d Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 11:16:52 -0700 Subject: 80-col tweaks --- paramiko/sftp_client.py | 14 +++++++++----- tests/test_sftp.py | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index 39f08fbc..ee25aa6a 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -222,8 +222,9 @@ class SFTPClient(BaseSFTP): nums = list() while True: try: - # Send out a bunch of readdir requests so that we can read the responses later on - # Section 6.7 of the SSH file transfer RFC explains this + # Send out a bunch of readdir requests so that we can read the + # responses later on Section 6.7 of the SSH file transfer RFC + # explains this # http://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt for i in range(read_ahead_requests): num = self._async_request(type(None), CMD_READDIR, handle) @@ -232,8 +233,10 @@ class SFTPClient(BaseSFTP): # 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 some more requests - # Exit the loop when we've reached the end of the directory handle + # If we're at the end of our queued requests, then fire off + # some more requests + # Exit the loop when we've reached the end of the directory + # handle for num in nums: t, pkt_data = self._read_packet() msg = Message(pkt_data) @@ -245,7 +248,8 @@ class SFTPClient(BaseSFTP): for i in range(count): filename = msg.get_string() longname = msg.get_string() - attr = SFTPAttributes._from_msg(msg, filename, longname) + attr = SFTPAttributes._from_msg( + msg, filename, longname) if (filename != '.') and (filename != '..'): yield attr diff --git a/tests/test_sftp.py b/tests/test_sftp.py index 2b6aa3b6..26929bdb 100755 --- a/tests/test_sftp.py +++ b/tests/test_sftp.py @@ -279,8 +279,8 @@ class SFTPTest (unittest.TestCase): def test_7_listdir(self): """ - verify that a folder can be created, a bunch of files can be placed in it, - and those files show up in sftp.listdir. + verify that a folder can be created, a bunch of files can be placed in + it, and those files show up in sftp.listdir. """ try: sftp.open(FOLDER + '/duck.txt', 'w').close() -- cgit v1.2.3 From e5fc6a6ecc064f6b2b9862a9405b27f40385f821 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 11:38:27 -0700 Subject: Add quick test re #131 --- tests/test_sftp.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_sftp.py b/tests/test_sftp.py index 26929bdb..1ae9781d 100755 --- a/tests/test_sftp.py +++ b/tests/test_sftp.py @@ -298,6 +298,26 @@ class SFTPTest (unittest.TestCase): sftp.remove(FOLDER + '/fish.txt') sftp.remove(FOLDER + '/tertiary.py') + def test_7_5_listdir_iter(self): + """ + listdir_iter version of above test + """ + try: + sftp.open(FOLDER + '/duck.txt', 'w').close() + sftp.open(FOLDER + '/fish.txt', 'w').close() + sftp.open(FOLDER + '/tertiary.py', 'w').close() + + x = [x.filename for x in sftp.listdir_iter(FOLDER)] + self.assertEqual(len(x), 3) + self.assertTrue('duck.txt' in x) + self.assertTrue('fish.txt' in x) + self.assertTrue('tertiary.py' in x) + self.assertTrue('random' not in x) + finally: + sftp.remove(FOLDER + '/duck.txt') + sftp.remove(FOLDER + '/fish.txt') + sftp.remove(FOLDER + '/tertiary.py') + def test_8_setstat(self): """ verify that the setstat functions (chown, chmod, utime, truncate) work. -- cgit v1.2.3 From 4aa798ef21dc643a271e4ff5581ddf7cbde4c144 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 11:40:12 -0700 Subject: Try skipping docs builds under Python 3.2 --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 801356e0..e17bdafd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,8 +17,9 @@ script: # Run 'docs' first since its objects.inv is referred to by 'www'. # Also force warnings to be errors since most of them tend to be actual # problems. - - invoke docs -o -W - - invoke www -o -W + # Finally, skip them under Python 3.2 due to sphinx shenanigans + - "[[ $TRAVIS_PYTHON_VERSION != 3.2 ]] && invoke docs -o -W || true" + - "[[ $TRAVIS_PYTHON_VERSION != 3.2 ]] && invoke www -o -W || true" notifications: irc: channels: "irc.freenode.org#paramiko" -- cgit v1.2.3 From b2323505b0a3e22d37a30ecdab9624bd086726e6 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 11:42:27 -0700 Subject: Make read ahead kwarg a bit less verbose --- paramiko/sftp_client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index ee25aa6a..d3b95933 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -196,14 +196,14 @@ class SFTPClient(BaseSFTP): self._request(CMD_CLOSE, handle) return filelist - def listdir_iter(self, path='.', read_ahead_requests=50): + def listdir_iter(self, path='.', read_aheads=50): """ Generator version of `.listdir_attr`. See the API docs for `.listdir_attr` for overall details. This function adds one more kwarg on top of `.listdir_attr`: - ``read_ahead_requests``, an integer controlling how many + ``read_aheads``, an integer controlling how many ``SSH_FXP_READDIR`` requests are made to the server. The default of 50 should suffice for most file listings as each request/response cycle may contain multiple files (dependant on server implementation.) @@ -226,7 +226,7 @@ class SFTPClient(BaseSFTP): # responses later on Section 6.7 of the SSH file transfer RFC # explains this # http://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt - for i in range(read_ahead_requests): + for i in range(read_aheads): num = self._async_request(type(None), CMD_READDIR, handle) nums.append(num) -- cgit v1.2.3 From 35b9d1540bd98af39e133960c61b06aba621f30d Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 11:44:22 -0700 Subject: Changelog re #131 --- sites/www/changelog.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 24679d5f..e18b5368 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,9 @@ Changelog ========= +* :feature:`131` Add a `~paramiko.sftp_client.SFTPClient.listdir_iter` method + to `~paramiko.sftp_client.SFTPClient` allowing for more efficient, + async/generator based file listings. Thanks to John Begeman. * :support:`378 backported` Minor code cleanup in the SSH config module courtesy of Olle Lundberg. * :support:`249` Consolidate version information into one spot. Thanks to Gabi -- cgit v1.2.3 From 720806734a05d9de0f47588d816de05646a06f0b Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 5 Sep 2014 12:49:35 -0700 Subject: Fix an oversight re: py3 & strings in listdir_iter --- paramiko/sftp_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paramiko/sftp_client.py b/paramiko/sftp_client.py index d3b95933..3e85a8c9 100644 --- a/paramiko/sftp_client.py +++ b/paramiko/sftp_client.py @@ -246,8 +246,8 @@ class SFTPClient(BaseSFTP): self._convert_status(msg) count = msg.get_int() for i in range(count): - filename = msg.get_string() - longname = msg.get_string() + filename = msg.get_text() + longname = msg.get_text() attr = SFTPAttributes._from_msg( msg, filename, longname) if (filename != '.') and (filename != '..'): -- cgit v1.2.3