diff options
-rw-r--r-- | Lib/UserDict.py | 18 | ||||
-rw-r--r-- | Lib/UserList.py | 39 | ||||
-rw-r--r-- | Lib/ftplib.py | 54 | ||||
-rw-r--r-- | Lib/test/test_b1.py | 21 | ||||
-rw-r--r-- | Lib/test/test_b2.py | 9 | ||||
-rw-r--r-- | Lib/test/test_select.py | 2 | ||||
-rw-r--r-- | Lib/test/testall.out | 1 |
7 files changed, 112 insertions, 32 deletions
diff --git a/Lib/UserDict.py b/Lib/UserDict.py new file mode 100644 index 0000000..f6b2f82 --- /dev/null +++ b/Lib/UserDict.py @@ -0,0 +1,18 @@ +# A more or less complete user-defined wrapper around dictionary objects + +class UserDict: + def __init__(self): self.data = {} + def __repr__(self): return repr(self.data) + def __cmp__(self, dict): + if type(dict) == type(self.data): + return cmp(self.data, dict) + else: + return cmp(self.data, dict.data) + def __len__(self): return len(self.data) + def __getitem__(self, key): return self.data[key] + def __setitem__(self, key, item): self.data[key] = item + def __delitem__(self, key): del self.data[key] + def keys(self): return self.data.keys() + def items(self): return self.data.items() + def values(self): return self.data.values() + def has_key(self, key): return self.data.has_key(key) diff --git a/Lib/UserList.py b/Lib/UserList.py new file mode 100644 index 0000000..9fbcc02 --- /dev/null +++ b/Lib/UserList.py @@ -0,0 +1,39 @@ +# A more or less complete user-defined wrapper around list objects + +class UserList: + def __init__(self, *args): + if len(args) > 1: raise TypeError, 'too many args' + self.data = [] + if args: + list = args[0] + if type(list) == type(self.data): + self.data[:] = list + else: + self.data[:] = list.data[:] + def __repr__(self): return repr(self.data) + def __cmp__(self, list): + if type(list) == type(self.data): + return cmp(self.data, list) + else: + return cmp(self.data, list.data) + def __len__(self): return len(self.data) + def __getitem__(self, i): return self.data[i] + def __setitem__(self, i, item): self.data[i] = item + def __delitem__(self, i): del self.data[i] + def __getslice__(self, i, j): + userlist = UserList() + userlist.data[:] = self.data[i:j] + return userlist + def __setslice__(self, i, j, list): + if type(list) == type(self.data): + self.data[i:j] = list + else: + self.data[i:j] = list.data + def __delslice__(self, i, j): del self.data[i:j] + def append(self, item): self.data.append(item) + def insert(self, i, item): self.data.insert(i, item) + def remove(self, item): self.data.remove(item) + def count(self, item): return self.data.count(item) + def index(self, item): return self.data.index(item) + def reverse(self): self.data.reverse() + def sort(self, *args): apply(self.data.sort, args) diff --git a/Lib/ftplib.py b/Lib/ftplib.py index dc66241..22852bc 100644 --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -1,6 +1,8 @@ # An FTP client class. Based on RFC 959: File Transfer Protocol # (FTP), by J. Postel and J. Reynolds +# Changes and improvements suggested by Steve Majewski + # Example: # @@ -70,6 +72,8 @@ class FTP: # New initialization method (called by class instantiation) # Initialize host to localhost, port to standard ftp port + # Optional arguments are host (for connect()), + # and user, passwd, acct (for login()) def __init__(self, *args): # Initialize the instance to something mostly harmless self.debugging = 0 @@ -79,7 +83,9 @@ class FTP: self.file = None self.welcome = None if args: - apply(self.connect, args) + self.connect(args[0]) + if args[1:]: + apply(self.login, args[1:]) # Old init method (explicitly called by caller) def init(self, *args): @@ -89,7 +95,7 @@ class FTP: # Connect to host. Arguments: # - host: hostname to connect to (default previous host) # - port: port to connect to (default previous port) - def init(self, *args): + def connect(self, *args): if args: self.host = args[0] if args[1:]: self.port = args[1] if args[2:]: raise TypeError, 'too many args' @@ -97,7 +103,6 @@ class FTP: self.sock.connect(self.host, self.port) self.file = self.sock.makefile('r') self.welcome = self.getresp() - return self # Get the welcome message from the server # (this is read and squirreled away by init()) @@ -276,8 +281,14 @@ class FTP: # Retrieve data in line mode. # The argument is a RETR or LIST command. # The callback function is called for each line, with trailing - # CRLF stripped. This creates a new port for you - def retrlines(self, cmd, callback): + # CRLF stripped. This creates a new port for you. + # print_lines is the default callback + def retrlines(self, cmd, args): + callback = None + if args: + callback = args[0] + if args[1:]: raise TypeError, 'too many args' + if not callback: callback = print_line resp = self.sendcmd('TYPE A') conn = self.transfercmd(cmd) fp = conn.makefile('r') @@ -328,6 +339,20 @@ class FTP: self.retrlines(cmd, files.append) return files + # List a directory in long form. By default list current directory + # to stdout. Optional last argument is callback function; + # all non-empty arguments before it are concatenated to the + # LIST command. (This *should* only be used for a pathname.) + def dir(self, *args): + cmd = 'LIST' + func = None + if args[-1:] and type(args[-1]) != type(''): + args, func = args[:-1], args[-1] + for arg in args: + if arg: + cmd = cmd + (' ' + arg) + self.retrlines(cmd, func) + # Rename a file def rename(self, fromname, toname): resp = self.sendcmd('RNFR ' + fromname) @@ -338,9 +363,13 @@ class FTP: # Change to a directory def cwd(self, dirname): if dirname == '..': - cmd = 'CDUP' - else: - cmd = 'CWD ' + dirname + try: + self.voidcmd('CDUP') + return + except error_perm, msg: + if msg[:3] != '500': + raise error_perm, msg + cmd = 'CWD ' + dirname self.voidcmd(cmd) # Retrieve the size of a file @@ -390,6 +419,10 @@ def parse257(resp): dirname = dirname + c return dirname +# Default retrlines callback to print a line +def print_line(line): + print line + # Test program. # Usage: ftp [-d] host [-l[dir]] [-d[dir]] [file] ... @@ -409,12 +442,9 @@ def test(): ftp = FTP(host) ftp.set_debuglevel(debugging) ftp.login() - def writeln(line): print line for file in sys.argv[2:]: if file[:2] == '-l': - cmd = 'LIST' - if file[2:]: cmd = cmd + ' ' + file[2:] - ftp.retrlines(cmd, writeln) + ftp.dir(file[2:]) elif file[:2] == '-d': cmd = 'CWD' if file[2:]: cmd = cmd + ' ' + file[2:] diff --git a/Lib/test/test_b1.py b/Lib/test/test_b1.py index 396c5c2..434b379 100644 --- a/Lib/test/test_b1.py +++ b/Lib/test/test_b1.py @@ -91,11 +91,11 @@ execfile(TESTFN) unlink(TESTFN) print 'filter' -if filter("c: 'a' <= c <= 'z'", 'Hello World') <> 'elloorld': +if filter(lambda c: 'a' <= c <= 'z', 'Hello World') <> 'elloorld': raise TestFailed, 'filter (filter a string)' if filter(None, [1, 'hello', [], [3], '', None, 9, 0]) <> [1, 'hello', [3], 9]: raise TestFailed, 'filter (remove false values)' -if filter('x: x > 0', [1, -3, 9, 0, 2]) <> [1, 9, 2]: +if filter(lambda x: x > 0, [1, -3, 9, 0, 2]) <> [1, 9, 2]: raise TestFailed, 'filter (keep positives)' print 'float' @@ -120,11 +120,6 @@ if int(314) <> 314: raise TestFailed, 'int(314)' if int(3.14) <> 3: raise TestFailed, 'int(3.14)' if int(314L) <> 314: raise TestFailed, 'int(314L)' -print 'lambda' -binary_plus = lambda('x, y: x+y') -if binary_plus(2, 10) <> 12: - raise TestFailed, 'binary_plus(2, 10)' - print 'len' if len('123') <> 3: raise TestFailed, 'len(\'123\')' if len(()) <> 0: raise TestFailed, 'len(())' @@ -146,13 +141,13 @@ if map(None, 'abcd', 'efg') <> \ raise TestFailed, 'map(None, \'abcd\', \'efg\')' if map(None, range(10)) <> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]: raise TestFailed, 'map(None, range(10))' -if map('x: x*x', range(1,4)) <> [1, 4, 9]: - raise TestFailed, 'map(\'x: x*x\', range(1,4))' +if map(lambda x: x*x, range(1,4)) <> [1, 4, 9]: + raise TestFailed, 'map(lambda x: x*x, range(1,4))' from math import sqrt -if map('x: map(sqrt,x)', [[16, 4], [81, 9]]) <> [[4.0, 2.0], [9.0, 3.0]]: - raise TestFailed, map('x: map(sqrt,x)', [[16, 4], [81, 9]]) -if map('x,y: x+y', [1,3,2], [9,1,4]) <> [10, 4, 6]: - raise TestFailed, 'map(\'x,y: x+y\', [1,3,2], [9,1,4])' +if map(lambda x: map(sqrt,x), [[16, 4], [81, 9]]) <> [[4.0, 2.0], [9.0, 3.0]]: + raise TestFailed, 'map(lambda x: map(sqrt,x), [[16, 4], [81, 9]])' +if map(lambda x, y: x+y, [1,3,2], [9,1,4]) <> [10, 4, 6]: + raise TestFailed, 'map(lambda x,y: x+y, [1,3,2], [9,1,4])' def plus(*v): accu = 0 for i in v: accu = accu + i diff --git a/Lib/test/test_b2.py b/Lib/test/test_b2.py index 037955e..7118b08 100644 --- a/Lib/test/test_b2.py +++ b/Lib/test/test_b2.py @@ -112,13 +112,14 @@ finally: fp.close() print 'reduce' -if reduce('x,y:x+y', ['a', 'b', 'c'], '') <> 'abc': +if reduce(lambda x, y: x+y, ['a', 'b', 'c'], '') <> 'abc': raise TestFailed, 'reduce(): implode a string' -if reduce('x,y:x+y', [['a', 'c'], [], ['d', 'w']], []) <> ['a','c','d','w']: +if reduce(lambda x, y: x+y, + [['a', 'c'], [], ['d', 'w']], []) <> ['a','c','d','w']: raise TestFailed, 'reduce(): append' -if reduce('x,y: x*y', range(2,8), 1) <> 5040: +if reduce(lambda x, y: x*y, range(2,8), 1) <> 5040: raise TestFailed, 'reduce(): compute 7!' -if reduce('x,y:x*y', range(2,21), 1L) <> 2432902008176640000L: +if reduce(lambda x, y: x*y, range(2,21), 1L) <> 2432902008176640000L: raise TestFailed, 'reduce(): compute 20!, use long' print 'reload' diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py index 89088ef..f185308 100644 --- a/Lib/test/test_select.py +++ b/Lib/test/test_select.py @@ -1,7 +1,5 @@ # Testing select module -from test_support import * - def test(): import select import os diff --git a/Lib/test/testall.out b/Lib/test/testall.out index 90c1202..46a728e 100644 --- a/Lib/test/testall.out +++ b/Lib/test/testall.out @@ -79,7 +79,6 @@ float getattr hex int -lambda len long map |