From e65cce5eec23812d77a54095209c923937cc3c92 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 8 Nov 1993 15:05:21 +0000 Subject: * string.py: added rindex(), rfind(); changed index() to interpret negative start indices starting from the right. * ftplib.py: debug() -> set_debuglevel(); change demo to use __init__(). * os.py: added execl, execlp, and execvp. * lambda.py: removed (now that we have built-in map, reduce, bagof, lambda) * test_b{1,2}.py, testall.out: added tests for bagof, lambda, map, reduce * commands.py: use os, not posix * test_grammar.py: make it easy to disable non-portable int overflow tests * dis.py: don't abuse range() --- Lib/commands.py | 8 ++++---- Lib/dis.py | 4 ++-- Lib/ftplib.py | 9 +++++---- Lib/os.py | 30 ++++++++++++++++++++++++++++++ Lib/string.py | 27 +++++++++++++++++++++++++++ Lib/stringold.py | 27 +++++++++++++++++++++++++++ Lib/test/test_b1.py | 39 +++++++++++++++++++++++++++++++++++++++ Lib/test/test_b2.py | 10 ++++++++++ Lib/test/test_grammar.py | 23 +++++++++++++---------- Lib/test/testall.out | 4 ++++ 10 files changed, 161 insertions(+), 20 deletions(-) diff --git a/Lib/commands.py b/Lib/commands.py index d8c6e65..428a830 100644 --- a/Lib/commands.py +++ b/Lib/commands.py @@ -23,8 +23,8 @@ def getoutput(cmd): # Returns a pair (sts, output) # def getstatusoutput(cmd): - import posix - pipe = posix.popen('{ ' + cmd + '; } 2>&1', 'r') + import os + pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') text = pipe.read() sts = pipe.close() if sts == None: sts = 0 @@ -35,8 +35,8 @@ def getstatusoutput(cmd): # Make command argument from directory and pathname (prefix space, add quotes). # def mk2arg(head, x): - import posixpath - return mkarg(posixpath.join(head, x)) + import os + return mkarg(os.path.join(head, x)) # Make a shell command argument from a string. diff --git a/Lib/dis.py b/Lib/dis.py index b79df47..cd62500 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -68,8 +68,8 @@ hasname = [] hasjrel = [] hasjabs = [] -opname = range(256) -for op in opname: opname[op] = '<' + `op` + '>' +opname = [''] * 256 +for op in range(256): opname[op] = '<' + `op` + '>' def def_op(name, op): opname[op] = name diff --git a/Lib/ftplib.py b/Lib/ftplib.py index 8342b09..dc66241 100644 --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -5,7 +5,7 @@ # Example: # # >>> from ftplib import FTP -# >>> ftp = FTP().init('ftp.cwi.nl') # connect to host, default port +# >>> ftp = FTP('ftp.cwi.nl') # connect to host, default port # >>> ftp.login() # default, i.e.: user anonymous, passwd user@hostname # >>> def handle_one_line(line): # callback for ftp.retrlines # ... print line @@ -109,8 +109,9 @@ class FTP: # 0: no debugging output (default) # 1: print commands and responses but not body text etc. # 2: also print raw lines read and sent before stripping CR/LF - def debug(self, level): + def set_debuglevel(self, level): self.debugging = level + debug = set_debuglevel # Internal: send one line to the server, appending CRLF def putline(self, line): @@ -405,8 +406,8 @@ def test(): debugging = debugging+1 del sys.argv[1] host = sys.argv[1] - ftp = FTP().init(host) - ftp.debug(debugging) + ftp = FTP(host) + ftp.set_debuglevel(debugging) ftp.login() def writeln(line): print line for file in sys.argv[2:]: diff --git a/Lib/os.py b/Lib/os.py index dc1ef5a..7322fa5 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -38,3 +38,33 @@ except ImportError: import macpath path = macpath del macpath + +def execl(file, *args): + execv(file, args) + +def execle(file, *args): + env = args[-1] + execve(file, args[:-1], env) + +def execlp(file, *args): + execvp(file, args) + +def execvp(file, args): + if '/' in file: + execv(file, args) + return + ENOENT = 2 + if environ.has_key('PATH'): + import string + PATH = string.splitfields(environ['PATH'], ':') + else: + PATH = ['', '/bin', '/usr/bin'] + exc, arg = (ENOENT, 'No such file or directory') + for dir in PATH: + fullname = path.join(dir, file) + try: + execv(fullname, args) + except error, (errno, msg): + if errno != ENOENT: + exc, arg = error, (errno, msg) + raise exc, arg diff --git a/Lib/string.py b/Lib/string.py index 764c396..afe5bec 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -100,6 +100,7 @@ def index(s, sub, *args): if len(args) > 1: raise TypeError, 'string.index(): too many args' i = args[0] + if i < 0: i = i + len(s) else: i = 0 n = len(sub) @@ -109,6 +110,25 @@ def index(s, sub, *args): i = i+1 raise index_error, (s, sub) + args +# Find last substring, raise exception if not found +def rindex(s, sub, *args): + if args: + if len(args) > 1: + raise TypeError, 'string.rindex(): too many args' + i = args[0] + if i < 0: i = i + len(s) + else: + i = 0 + n = len(sub) + m = len(s) + 1 - n + r = None + while i < m: + if sub == s[i:i+n]: r = i + i = i+1 + if r is None: + raise index_error, (s, sub) + args + return r + # Find substring, return -1 if not found def find(*args): try: @@ -116,6 +136,13 @@ def find(*args): except index_error: return -1 +# Find last substring, return -1 if not found +def rfind(*args): + try: + return apply(rindex, args) + except index_error: + return -1 + # Convert string to float atof_error = 'non-float argument to string.atof' def atof(str): diff --git a/Lib/stringold.py b/Lib/stringold.py index 764c396..afe5bec 100644 --- a/Lib/stringold.py +++ b/Lib/stringold.py @@ -100,6 +100,7 @@ def index(s, sub, *args): if len(args) > 1: raise TypeError, 'string.index(): too many args' i = args[0] + if i < 0: i = i + len(s) else: i = 0 n = len(sub) @@ -109,6 +110,25 @@ def index(s, sub, *args): i = i+1 raise index_error, (s, sub) + args +# Find last substring, raise exception if not found +def rindex(s, sub, *args): + if args: + if len(args) > 1: + raise TypeError, 'string.rindex(): too many args' + i = args[0] + if i < 0: i = i + len(s) + else: + i = 0 + n = len(sub) + m = len(s) + 1 - n + r = None + while i < m: + if sub == s[i:i+n]: r = i + i = i+1 + if r is None: + raise index_error, (s, sub) + args + return r + # Find substring, return -1 if not found def find(*args): try: @@ -116,6 +136,13 @@ def find(*args): except index_error: return -1 +# Find last substring, return -1 if not found +def rfind(*args): + try: + return apply(rindex, args) + except index_error: + return -1 + # Convert string to float atof_error = 'non-float argument to string.atof' def atof(str): diff --git a/Lib/test/test_b1.py b/Lib/test/test_b1.py index c258fd7..396c5c2 100644 --- a/Lib/test/test_b1.py +++ b/Lib/test/test_b1.py @@ -90,6 +90,14 @@ f.close() execfile(TESTFN) unlink(TESTFN) +print 'filter' +if filter("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]: + raise TestFailed, 'filter (keep positives)' + print 'float' if float(3.14) <> 3.14: raise TestFailed, 'float(3.14)' if float(314) <> 314.0: raise TestFailed, 'float(314)' @@ -112,6 +120,11 @@ 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(())' @@ -125,6 +138,32 @@ if long(314) <> 314L: raise TestFailed, 'long(314)' if long(3.14) <> 3L: raise TestFailed, 'long(3.14)' if long(314L) <> 314L: raise TestFailed, 'long(314L)' +print 'map' +if map(None, 'hello world') <> ['h','e','l','l','o',' ','w','o','r','l','d']: + raise TestFailed, 'map(None, \'hello world\')' +if map(None, 'abcd', 'efg') <> \ + [('a', 'e'), ('b', 'f'), ('c', 'g'), ('d', None)]: + 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))' +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])' +def plus(*v): + accu = 0 + for i in v: accu = accu + i + return accu +if map(plus, [1, 3, 7]) <> [1, 3, 7]: + raise TestFailed, 'map(plus, [1, 3, 7])' +if map(plus, [1, 3, 7], [4, 9, 2]) <> [1+4, 3+9, 7+2]: + raise TestFailed, 'map(plus, [1, 3, 7], [4, 9, 2])' +if map(plus, [1, 3, 7], [4, 9, 2], [1, 1, 0]) <> [1+4+1, 3+9+1, 7+2+0]: + raise TestFailed, 'map(plus, [1, 3, 7], [4, 9, 2], [1, 1, 0])' + print 'max' if max('123123') <> '3': raise TestFailed, 'max(\'123123\')' if max(1, 2, 3) <> 3: raise TestFailed, 'max(1, 2, 3)' diff --git a/Lib/test/test_b2.py b/Lib/test/test_b2.py index ca06049..037955e 100644 --- a/Lib/test/test_b2.py +++ b/Lib/test/test_b2.py @@ -111,6 +111,16 @@ finally: sys.stdin = savestdin fp.close() +print 'reduce' +if reduce('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']: + raise TestFailed, 'reduce(): append' +if reduce('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: + raise TestFailed, 'reduce(): compute 20!, use long' + print 'reload' import string reload(string) diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index f07f75b..4c9e7b0 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -24,16 +24,19 @@ print '1.1.2.1 Plain integers' if 0xff <> 255: raise TestFailed, 'hex int' if 0377 <> 255: raise TestFailed, 'octal int' if 2147483647 != 017777777777: raise TestFailed, 'max positive int' -if -2147483647-1 != 020000000000: raise TestFailed, 'max negative int' -# XXX -2147483648 -if 037777777777 != -1: raise TestFailed, 'oct -1' -if 0xffffffff != -1: raise TestFailed, 'hex -1' -for s in '2147483648', '040000000000', '0x100000000': - try: - x = eval(s) - except OverflowError: - continue - raise TestFailed, 'No OverflowError on huge integer literal ' + `s` +# Change the following line to "if 0:" if you have 64-bit integers +if 1: + if -2147483647-1 != 020000000000: raise TestFailed, 'max negative int' + # XXX -2147483648 + if 037777777777 != -1: raise TestFailed, 'oct -1' + if 0xffffffff != -1: raise TestFailed, 'hex -1' + for s in '2147483648', '040000000000', '0x100000000': + try: + x = eval(s) + except OverflowError: + continue + raise TestFailed, \ + 'No OverflowError on huge integer literal ' + `s` print '1.1.2.2 Long integers' x = 0L diff --git a/Lib/test/testall.out b/Lib/test/testall.out index e1ee9da..1dbb42a 100644 --- a/Lib/test/testall.out +++ b/Lib/test/testall.out @@ -73,12 +73,15 @@ dir divmod eval execfile +filter float getattr hex int +lambda len long +map max min test_b2 @@ -90,6 +93,7 @@ range input and raw_input testing testing +reduce reload repr round -- cgit v0.12