Index: Lib/ftplib.py =================================================================== --- Lib/ftplib.py (revision 56404) +++ Lib/ftplib.py (working copy) @@ -68,7 +68,7 @@ # Line terminators (we always output CRLF, but accept any of CRLF, CR, LF) -CRLF = '\r\n' +CRLF = b'\r\n' # The class itself @@ -156,11 +156,11 @@ # Internal: "sanitize" a string for printing def sanitize(self, s): - if s[:5] == 'pass ' or s[:5] == 'PASS ': + if s[:5] == b'pass ' or s[:5] == b'PASS ': i = len(s) - while i > 5 and s[i-1] in '\r\n': + while i > 5 and s[i-1] in b'\r\n': i = i-1 - s = s[:5] + '*'*(i-5) + s[i:] + s = s[:5] + b'*'*(i-5) + s[i:] return repr(s) # Internal: send one line to the server, appending CRLF @@ -171,6 +171,7 @@ # Internal: send one command to the server (through putline()) def putcmd(self, line): + line = bytes(line) if self.debugging: print('*cmd*', self.sanitize(line)) self.putline(line) @@ -191,13 +192,13 @@ # these are separated by '\n' characters in the string def getmultiline(self): line = self.getline() - if line[3:4] == '-': + if line[3:4] == b'-': code = line[:3] while 1: nextline = self.getline() - line = line + ('\n' + nextline) + line = line + (b'\n' + nextline) if nextline[:3] == code and \ - nextline[3:4] != '-': + nextline[3:4] != b'-': break return line @@ -208,18 +209,18 @@ if self.debugging: print('*resp*', self.sanitize(resp)) self.lastresp = resp[:3] c = resp[:1] - if c in ('1', '2', '3'): + if c in (b'1', b'2', b'3'): return resp - if c == '4': + if c == b'4': raise error_temp, resp - if c == '5': + if c == b'5': raise error_perm, resp raise error_proto, resp def voidresp(self): """Expect a response beginning with '2'.""" resp = self.getresp() - if resp[0] != '2': + if resp[:1] != b'2': raise error_reply, resp return resp @@ -232,7 +233,7 @@ if self.debugging > 1: print('*put urgent*', self.sanitize(line)) self.sock.sendall(line, MSG_OOB) resp = self.getmultiline() - if resp[:3] not in ('426', '226'): + if resp[:3] not in (b'426', b'226'): raise error_proto, resp def sendcmd(self, cmd): @@ -329,9 +330,9 @@ # be in violation of the protocol (which only allows # 1xx or error messages for LIST), so we just discard # this response. - if resp[0] == '2': + if resp[:1] == b'2': resp = self.getresp() - if resp[0] != '1': + if resp[:1] != b'1': raise error_reply, resp else: sock = self.makeport() @@ -339,12 +340,12 @@ self.sendcmd("REST %s" % rest) resp = self.sendcmd(cmd) # See above. - if resp[0] == '2': + if resp[:1] == b'2': resp = self.getresp() - if resp[0] != '1': + if resp[:1] != b'1': raise error_reply, resp conn, sockaddr = sock.accept() - if resp[:3] == '150': + if resp[:3] == b'150': # this is conditional in case we received a 125 size = parse150(resp) return conn, size @@ -368,9 +369,9 @@ # host or country. passwd = passwd + 'anonymous@' resp = self.sendcmd('USER ' + user) - if resp[0] == '3': resp = self.sendcmd('PASS ' + passwd) - if resp[0] == '3': resp = self.sendcmd('ACCT ' + acct) - if resp[0] != '2': + if resp[:1] == b'3': resp = self.sendcmd('PASS ' + passwd) + if resp[:1] == b'3': resp = self.sendcmd('ACCT ' + acct) + if resp[:1] != b'2': raise error_reply, resp return resp @@ -411,7 +412,7 @@ break if line[-2:] == CRLF: line = line[:-2] - elif line[-1:] == '\n': + elif line[-1:] == b'\n': line = line[:-1] callback(line) fp.close() @@ -475,16 +476,16 @@ def rename(self, fromname, toname): '''Rename a file.''' resp = self.sendcmd('RNFR ' + fromname) - if resp[0] != '3': + if resp[:1] != b'3': raise error_reply, resp return self.voidcmd('RNTO ' + toname) def delete(self, filename): '''Delete a file.''' resp = self.sendcmd('DELE ' + filename) - if resp[:3] in ('250', '200'): + if resp[:3] in (b'250', b'200'): return resp - elif resp[:1] == '5': + elif resp[:1] == b'5': raise error_perm, resp else: raise error_reply, resp @@ -495,7 +496,7 @@ try: return self.voidcmd('CDUP') except error_perm as msg: - if msg.args[0][:3] != '500': + if msg.args[0][:3] != b'500': raise elif dirname == '': dirname = '.' # does nothing, but could return error @@ -506,8 +507,8 @@ '''Retrieve the size of a file.''' # Note that the RFC doesn't say anything about 'SIZE' resp = self.sendcmd('SIZE ' + filename) - if resp[:3] == '213': - s = resp[3:].strip() + if resp[:3] == b'213': + s = str(resp[3:]).strip() try: return int(s) except (OverflowError, ValueError): @@ -548,7 +549,7 @@ Returns the expected transfer size or None; size is not guaranteed to be present in the 150 message. ''' - if resp[:3] != '150': + if resp[:3] != b'150': raise error_reply, resp global _150_re if _150_re is None: @@ -571,7 +572,7 @@ Raises error_proto if it does not contain '(h1,h2,h3,h4,p1,p2)' Return ('host.addr.as.numbers', port#) tuple.''' - if resp[:3] != '227': + if resp[:3] != b'227': raise error_reply, resp global _227_re if _227_re is None: @@ -581,7 +582,7 @@ if not m: raise error_proto, resp numbers = m.groups() - host = '.'.join(numbers[:4]) + host = '.'.join(str(n) for n in numbers[:4]) port = (int(numbers[4]) << 8) + int(numbers[5]) return host, port @@ -591,11 +592,11 @@ Raises error_proto if it does not contain '(|||port|)' Return ('host.addr.as.numbers', port#) tuple.''' - if resp[:3] != '229': + if resp[:3] != b'229': raise error_reply, resp - left = resp.find('(') + left = resp.find(b'(') if left < 0: raise error_proto, resp - right = resp.find(')', left + 1) + right = resp.find(b')', left + 1) if right < 0: raise error_proto, resp # should contain '(|||port|)' if resp[left + 1] != resp[right - 1]: @@ -613,18 +614,18 @@ This is a response to a MKD or PWD request: a directory name. Returns the directoryname in the 257 reply.''' - if resp[:3] != '257': + if resp[:3] != b'257': raise error_reply, resp - if resp[3:5] != ' "': + if resp[3:5] != b' "': return '' # Not compliant to RFC 959, but UNIX ftpd does this dirname = '' i = 5 n = len(resp) while i < n: - c = resp[i] + c = chr(resp[i]) i = i+1 if c == '"': - if i >= n or resp[i] != '"': + if i >= n or chr(resp[i]) != '"': break i = i+1 dirname = dirname + c @@ -648,9 +649,9 @@ # transfer request. # So: STOR before RETR, because here the target is a "user". treply = target.sendcmd('STOR ' + targetname) - if treply[:3] not in ('125', '150'): raise error_proto # RFC 959 + if treply[:3] not in (b'125', b'150'): raise error_proto # RFC 959 sreply = source.sendcmd('RETR ' + sourcename) - if sreply[:3] not in ('125', '150'): raise error_proto # RFC 959 + if sreply[:3] not in (b'125', b'150'): raise error_proto # RFC 959 source.voidresp() target.voidresp()