Index: Lib/ftplib.py =================================================================== --- Lib/ftplib.py (révision 74555) +++ Lib/ftplib.py (copie de travail) @@ -473,9 +473,15 @@ while 1: buf = fp.readline() if not buf: break - if buf[-2:] != B_CRLF: - if buf[-1] in B_CRLF: buf = buf[:-1] - buf = buf + B_CRLF + if isinstance(buf, str): + if not buf.endswith(CRLF): + if buf[-1] in CRLF: buf = buf[:-1] + buf = buf + CRLF + buf = bytes(buf, self.encoding) + else: + if not buf.endswith(B_CRLF): + if buf[-1:] in B_CRLF: buf = buf[:-1] + buf = buf + B_CRLF conn.sendall(buf) if callback: callback(buf) conn.close() Index: Lib/test/test_ftplib.py =================================================================== --- Lib/test/test_ftplib.py (révision 74555) +++ Lib/test/test_ftplib.py (copie de travail) @@ -16,19 +16,20 @@ # the dummy data returned by server over the data channel when # RETR, LIST and NLST commands are issued RETR_DATA = 'abcde12345\r\n' * 1000 +RETR_TEXT = 'abcd\xe912345\r\n' * 1000 LIST_DATA = 'foo\r\nbar\r\n' NLST_DATA = 'foo\r\nbar\r\n' class DummyDTPHandler(asynchat.async_chat): - - def __init__(self, conn, baseclass): + def __init__(self, conn, baseclass, encoding='latin1'): asynchat.async_chat.__init__(self, conn) self.baseclass = baseclass self.baseclass.last_received_data = '' + self.encoding = encoding def handle_read(self): - self.baseclass.last_received_data += self.recv(1024).decode('ascii') + self.baseclass.last_received_data += self.recv(1024).decode(self.encoding) def handle_close(self): self.baseclass.push('226 transfer complete') @@ -334,7 +335,7 @@ self.client.storbinary('stor', f, callback=lambda x: flag.append(None)) self.assertTrue(flag) - def test_storlines(self): + def test_storlines_bytes(self): f = io.BytesIO(RETR_DATA.replace('\r\n', '\n').encode('ascii')) self.client.storlines('stor', f) self.assertEqual(self.server.handler.last_received_data, RETR_DATA) @@ -344,6 +345,16 @@ self.client.storlines('stor foo', f, callback=lambda x: flag.append(None)) self.assertTrue(flag) + def test_storlines_str(self): + f = io.StringIO(RETR_TEXT.replace('\r\n', '\n')) + self.client.storlines('stor', f) + self.assertEqual(self.server.handler.last_received_data, RETR_TEXT) + # test new callback arg + flag = [] + f.seek(0) + self.client.storlines('stor foo', f, callback=lambda x: flag.append(None)) + self.assertTrue(flag) + def test_nlst(self): self.client.nlst() self.assertEqual(self.client.nlst(), NLST_DATA.split('\r\n')[:-1])