diff options
author | Jeff Forcier <jeff@bitprophet.org> | 2014-03-05 17:03:37 -0800 |
---|---|---|
committer | Jeff Forcier <jeff@bitprophet.org> | 2014-03-05 17:03:37 -0800 |
commit | b2be63ec623b5944f9b84cac8b8f41aeb2b42fb7 (patch) | |
tree | 389e17b0c08cd34872a2e3afbc34860ab44fb3ed /paramiko/file.py | |
parent | bd61c7c0a9a4a2020d0acfb6a01e9ec85bb43b8e (diff) | |
parent | ae078f51d622931954e47e78029a889c4e721a05 (diff) | |
download | paramiko-b2be63ec623b5944f9b84cac8b8f41aeb2b42fb7.tar.gz |
Merge remote-tracking branch 'scottkmaxwell/py3-support-without-py25' into python3
Conflicts:
dev-requirements.txt
paramiko/__init__.py
paramiko/file.py
paramiko/hostkeys.py
paramiko/message.py
paramiko/proxy.py
paramiko/server.py
paramiko/transport.py
paramiko/util.py
paramiko/win_pageant.py
setup.py
Diffstat (limited to 'paramiko/file.py')
-rw-r--r-- | paramiko/file.py | 72 |
1 files changed, 45 insertions, 27 deletions
diff --git a/paramiko/file.py b/paramiko/file.py index 253ffcd0..9f002423 100644 --- a/paramiko/file.py +++ b/paramiko/file.py @@ -16,7 +16,7 @@ # along with Paramiko; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -from cStringIO import StringIO +from paramiko.common import * class BufferedFile (object): @@ -43,8 +43,8 @@ class BufferedFile (object): self.newlines = None self._flags = 0 self._bufsize = self._DEFAULT_BUFSIZE - self._wbuffer = StringIO() - self._rbuffer = '' + self._wbuffer = BytesIO() + self._rbuffer = bytes() self._at_trailing_cr = False self._closed = False # pos - position within the file, according to the user @@ -82,9 +82,10 @@ class BufferedFile (object): buffering is not turned on. """ self._write_all(self._wbuffer.getvalue()) - self._wbuffer = StringIO() + self._wbuffer = BytesIO() return + if PY2: def next(self): """ Returns the next line from the input, or raises @@ -99,6 +100,22 @@ class BufferedFile (object): if not line: raise StopIteration return line + else: + def __next__(self): + """ + Returns the next line from the input, or raises L{StopIteration} when + EOF is hit. Unlike python file objects, it's okay to mix calls to + C{next} and L{readline}. + + @raise StopIteration: when the end of the file is reached. + + @return: a line read from the file. + @rtype: str + """ + line = self.readline() + if not line: + raise StopIteration + return line def read(self, size=None): """ @@ -118,7 +135,7 @@ class BufferedFile (object): if (size is None) or (size < 0): # go for broke result = self._rbuffer - self._rbuffer = '' + self._rbuffer = bytes() self._pos += len(result) while True: try: @@ -130,12 +147,12 @@ class BufferedFile (object): result += new_data self._realpos += len(new_data) self._pos += len(new_data) - return result + return result if self._flags & self.FLAG_BINARY else u(result) if size <= len(self._rbuffer): result = self._rbuffer[:size] self._rbuffer = self._rbuffer[size:] self._pos += len(result) - return result + return result if self._flags & self.FLAG_BINARY else u(result) while len(self._rbuffer) < size: read_size = size - len(self._rbuffer) if self._flags & self.FLAG_BUFFERED: @@ -151,7 +168,7 @@ class BufferedFile (object): result = self._rbuffer[:size] self._rbuffer = self._rbuffer[size:] self._pos += len(result) - return result + return result if self._flags & self.FLAG_BINARY else u(result) def readline(self, size=None): """ @@ -181,11 +198,11 @@ class BufferedFile (object): if self._at_trailing_cr and (self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (len(line) > 0): # edge case: the newline may be '\r\n' and we may have read # only the first '\r' last time. - if line[0] == '\n': + if line[0] == linefeed_byte_value: line = line[1:] - self._record_newline('\r\n') + self._record_newline(crlf) else: - self._record_newline('\r') + self._record_newline(cr_byte) self._at_trailing_cr = False # check size before looking for a linefeed, in case we already have # enough. @@ -195,42 +212,42 @@ class BufferedFile (object): self._rbuffer = line[size:] line = line[:size] self._pos += len(line) - return line + return line if self._flags & self.FLAG_BINARY else u(line) n = size - len(line) else: n = self._bufsize - if ('\n' in line) or ((self._flags & self.FLAG_UNIVERSAL_NEWLINE) and ('\r' in line)): + if (linefeed_byte in line) or ((self._flags & self.FLAG_UNIVERSAL_NEWLINE) and (cr_byte in line)): break try: new_data = self._read(n) except EOFError: new_data = None if (new_data is None) or (len(new_data) == 0): - self._rbuffer = '' + self._rbuffer = bytes() self._pos += len(line) - return line + return line if self._flags & self.FLAG_BINARY else u(line) line += new_data self._realpos += len(new_data) # find the newline - pos = line.find('\n') + pos = line.find(linefeed_byte) if self._flags & self.FLAG_UNIVERSAL_NEWLINE: - rpos = line.find('\r') + rpos = line.find(cr_byte) if (rpos >= 0) and ((rpos < pos) or (pos < 0)): pos = rpos xpos = pos + 1 - if (line[pos] == '\r') and (xpos < len(line)) and (line[xpos] == '\n'): + if (line[pos] == cr_byte_value) and (xpos < len(line)) and (line[xpos] == linefeed_byte_value): xpos += 1 self._rbuffer = line[xpos:] lf = line[pos:xpos] - line = line[:pos] + '\n' - if (len(self._rbuffer) == 0) and (lf == '\r'): + line = line[:pos] + linefeed_byte + if (len(self._rbuffer) == 0) and (lf == cr_byte): # we could read the line up to a '\r' and there could still be a # '\n' following that we read next time. note that and eat it. self._at_trailing_cr = True else: self._record_newline(lf) self._pos += len(line) - return line + return line if self._flags & self.FLAG_BINARY else u(line) def readlines(self, sizehint=None): """ @@ -243,14 +260,14 @@ class BufferedFile (object): :return: `list` of lines read from the file. """ lines = [] - bytes = 0 + byte_count = 0 while True: line = self.readline() if len(line) == 0: break lines.append(line) - bytes += len(line) - if (sizehint is not None) and (bytes >= sizehint): + byte_count += len(line) + if (sizehint is not None) and (byte_count >= sizehint): break return lines @@ -292,6 +309,7 @@ class BufferedFile (object): :param str data: data to write """ + data = b(data) if self._closed: raise IOError('File is closed') if not (self._flags & self.FLAG_WRITE): @@ -302,12 +320,12 @@ class BufferedFile (object): self._wbuffer.write(data) if self._flags & self.FLAG_LINE_BUFFERED: # only scan the new data for linefeed, to avoid wasting time. - last_newline_pos = data.rfind('\n') + last_newline_pos = data.rfind(linefeed_byte) if last_newline_pos >= 0: wbuf = self._wbuffer.getvalue() last_newline_pos += len(wbuf) - len(data) self._write_all(wbuf[:last_newline_pos + 1]) - self._wbuffer = StringIO() + self._wbuffer = BytesIO() self._wbuffer.write(wbuf[last_newline_pos + 1:]) return # even if we're line buffering, if the buffer has grown past the @@ -436,7 +454,7 @@ class BufferedFile (object): return if self.newlines is None: self.newlines = newline - elif (type(self.newlines) is str) and (self.newlines != newline): + elif self.newlines != newline and isinstance(self.newlines, bytes_types): self.newlines = (self.newlines, newline) elif newline not in self.newlines: self.newlines += (newline,) |