Kaydet (Commit) 2f3941d7 authored tarafından Guido van Rossum's avatar Guido van Rossum

Return the error code from most commands, rather than swallowing it.

Adapted the example (lying slightly about the string printed by
login()).
üst ae590db3
...@@ -12,6 +12,7 @@ Example: ...@@ -12,6 +12,7 @@ Example:
>>> from ftplib import FTP >>> from ftplib import FTP
>>> ftp = FTP('ftp.python.org') # connect to host, default port >>> ftp = FTP('ftp.python.org') # connect to host, default port
>>> ftp.login() # default, i.e.: user anonymous, passwd user@hostname >>> ftp.login() # default, i.e.: user anonymous, passwd user@hostname
'230 Guest login ok, access restrictions apply.'
>>> ftp.retrlines('LIST') # list directory contents >>> ftp.retrlines('LIST') # list directory contents
total 9 total 9
drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .
...@@ -23,7 +24,9 @@ drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib ...@@ -23,7 +24,9 @@ drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib
drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub
drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr
-rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg
'226 Transfer complete.'
>>> ftp.quit() >>> ftp.quit()
'221 Goodbye.'
>>> >>>
A nice test that reveals some of the network dialogue would be: A nice test that reveals some of the network dialogue would be:
...@@ -98,9 +101,11 @@ class FTP: ...@@ -98,9 +101,11 @@ class FTP:
self.sock = None self.sock = None
self.file = None self.file = None
self.welcome = None self.welcome = None
resp = None
if host: if host:
self.connect(host) resp = self.connect(host)
if user: self.login(user, passwd, acct) if user: resp = self.login(user, passwd, acct)
return resp
def connect(self, host = '', port = 0): def connect(self, host = '', port = 0):
'''Connect to host. Arguments are: '''Connect to host. Arguments are:
...@@ -113,6 +118,7 @@ class FTP: ...@@ -113,6 +118,7 @@ class FTP:
self.sock.connect(self.host, self.port) self.sock.connect(self.host, self.port)
self.file = self.sock.makefile('rb') self.file = self.sock.makefile('rb')
self.welcome = self.getresp() self.welcome = self.getresp()
return self.welcome
def getwelcome(self): def getwelcome(self):
'''Get the welcome message from the server. '''Get the welcome message from the server.
...@@ -203,6 +209,7 @@ class FTP: ...@@ -203,6 +209,7 @@ class FTP:
resp = self.getresp() resp = self.getresp()
if resp[0] <> '2': if resp[0] <> '2':
raise error_reply, resp raise error_reply, resp
return resp
def abort(self): def abort(self):
'''Abort a file transfer. Uses out-of-band data. '''Abort a file transfer. Uses out-of-band data.
...@@ -224,7 +231,7 @@ class FTP: ...@@ -224,7 +231,7 @@ class FTP:
def voidcmd(self, cmd): def voidcmd(self, cmd):
"""Send a command and expect a response beginning with '2'.""" """Send a command and expect a response beginning with '2'."""
self.putcmd(cmd) self.putcmd(cmd)
self.voidresp() return self.voidresp()
def sendport(self, host, port): def sendport(self, host, port):
'''Send a PORT command with the current host and the given port number.''' '''Send a PORT command with the current host and the given port number.'''
...@@ -232,7 +239,7 @@ class FTP: ...@@ -232,7 +239,7 @@ class FTP:
pbytes = [`port/256`, `port%256`] pbytes = [`port/256`, `port%256`]
bytes = hbytes + pbytes bytes = hbytes + pbytes
cmd = 'PORT ' + string.joinfields(bytes, ',') cmd = 'PORT ' + string.joinfields(bytes, ',')
self.voidcmd(cmd) return self.voidcmd(cmd)
def makeport(self): def makeport(self):
'''Create a new socket and send a PORT command for it.''' '''Create a new socket and send a PORT command for it.'''
...@@ -309,6 +316,7 @@ class FTP: ...@@ -309,6 +316,7 @@ class FTP:
if resp[0] == '3': resp = self.sendcmd('ACCT ' + acct) if resp[0] == '3': resp = self.sendcmd('ACCT ' + acct)
if resp[0] <> '2': if resp[0] <> '2':
raise error_reply, resp raise error_reply, resp
return resp
def retrbinary(self, cmd, callback, blocksize): def retrbinary(self, cmd, callback, blocksize):
'''Retrieve data in binary mode. '''Retrieve data in binary mode.
...@@ -323,7 +331,7 @@ class FTP: ...@@ -323,7 +331,7 @@ class FTP:
break break
callback(data) callback(data)
conn.close() conn.close()
self.voidresp() return self.voidresp()
def retrlines(self, cmd, callback = None): def retrlines(self, cmd, callback = None):
'''Retrieve data in line mode. '''Retrieve data in line mode.
...@@ -347,7 +355,7 @@ class FTP: ...@@ -347,7 +355,7 @@ class FTP:
callback(line) callback(line)
fp.close() fp.close()
conn.close() conn.close()
self.voidresp() return self.voidresp()
def storbinary(self, cmd, fp, blocksize): def storbinary(self, cmd, fp, blocksize):
'''Store a file in binary mode.''' '''Store a file in binary mode.'''
...@@ -358,7 +366,7 @@ class FTP: ...@@ -358,7 +366,7 @@ class FTP:
if not buf: break if not buf: break
conn.send(buf) conn.send(buf)
conn.close() conn.close()
self.voidresp() return self.voidresp()
def storlines(self, cmd, fp): def storlines(self, cmd, fp):
'''Store a file in line mode.''' '''Store a file in line mode.'''
...@@ -372,12 +380,12 @@ class FTP: ...@@ -372,12 +380,12 @@ class FTP:
buf = buf + CRLF buf = buf + CRLF
conn.send(buf) conn.send(buf)
conn.close() conn.close()
self.voidresp() return self.voidresp()
def acct(self, password): def acct(self, password):
'''Send new account name.''' '''Send new account name.'''
cmd = 'ACCT ' + password cmd = 'ACCT ' + password
self.voidcmd(cmd) return self.voidcmd(cmd)
def nlst(self, *args): def nlst(self, *args):
'''Return a list of files in a given directory (default the current).''' '''Return a list of files in a given directory (default the current).'''
...@@ -408,13 +416,13 @@ class FTP: ...@@ -408,13 +416,13 @@ class FTP:
resp = self.sendcmd('RNFR ' + fromname) resp = self.sendcmd('RNFR ' + fromname)
if resp[0] <> '3': if resp[0] <> '3':
raise error_reply, resp raise error_reply, resp
self.voidcmd('RNTO ' + toname) return self.voidcmd('RNTO ' + toname)
def delete(self, filename): def delete(self, filename):
'''Delete a file.''' '''Delete a file.'''
resp = self.sendcmd('DELE ' + filename) resp = self.sendcmd('DELE ' + filename)
if resp[:3] == '250': if resp[:3] == '250':
return return resp
elif resp[:1] == '5': elif resp[:1] == '5':
raise error_perm, resp raise error_perm, resp
else: else:
...@@ -424,13 +432,12 @@ class FTP: ...@@ -424,13 +432,12 @@ class FTP:
'''Change to a directory.''' '''Change to a directory.'''
if dirname == '..': if dirname == '..':
try: try:
self.voidcmd('CDUP') return self.voidcmd('CDUP')
return
except error_perm, msg: except error_perm, msg:
if msg[:3] != '500': if msg[:3] != '500':
raise error_perm, msg raise error_perm, msg
cmd = 'CWD ' + dirname cmd = 'CWD ' + dirname
self.voidcmd(cmd) return self.voidcmd(cmd)
def size(self, filename): def size(self, filename):
'''Retrieve the size of a file.''' '''Retrieve the size of a file.'''
...@@ -451,8 +458,9 @@ class FTP: ...@@ -451,8 +458,9 @@ class FTP:
def quit(self): def quit(self):
'''Quit, and close the connection.''' '''Quit, and close the connection.'''
self.voidcmd('QUIT') resp = self.voidcmd('QUIT')
self.close() self.close()
return resp
def close(self): def close(self):
'''Close the connection without assuming anything about it.''' '''Close the connection without assuming anything about it.'''
...@@ -495,7 +503,6 @@ def parse227(resp): ...@@ -495,7 +503,6 @@ def parse227(resp):
host = string.join(numbers[:4], '.') host = string.join(numbers[:4], '.')
port = (string.atoi(numbers[4]) << 8) + string.atoi(numbers[5]) port = (string.atoi(numbers[4]) << 8) + string.atoi(numbers[5])
return host, port return host, port
# end parse227
def parse257(resp): def parse257(resp):
...@@ -520,10 +527,12 @@ def parse257(resp): ...@@ -520,10 +527,12 @@ def parse257(resp):
dirname = dirname + c dirname = dirname + c
return dirname return dirname
def print_line(line): def print_line(line):
'''Default retrlines callback to print a line.''' '''Default retrlines callback to print a line.'''
print line print line
def ftpcp(source, sourcename, target, targetname = '', type = 'I'): def ftpcp(source, sourcename, target, targetname = '', type = 'I'):
'''Copy file from one FTP-instance to another.''' '''Copy file from one FTP-instance to another.'''
if not targetname: targetname = sourcename if not targetname: targetname = sourcename
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment