summaryrefslogtreecommitdiff
path: root/paramiko/file.py
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2014-03-05 17:03:37 -0800
committerJeff Forcier <jeff@bitprophet.org>2014-03-05 17:03:37 -0800
commitb2be63ec623b5944f9b84cac8b8f41aeb2b42fb7 (patch)
tree389e17b0c08cd34872a2e3afbc34860ab44fb3ed /paramiko/file.py
parentbd61c7c0a9a4a2020d0acfb6a01e9ec85bb43b8e (diff)
parentae078f51d622931954e47e78029a889c4e721a05 (diff)
downloadparamiko-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.py72
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,)