* 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()
This commit is contained in:
Guido van Rossum 1993-11-08 15:05:21 +00:00
parent db65a6ce55
commit e65cce5eec
10 changed files with 161 additions and 20 deletions

View File

@ -23,8 +23,8 @@ def getoutput(cmd):
# Returns a pair (sts, output) # Returns a pair (sts, output)
# #
def getstatusoutput(cmd): def getstatusoutput(cmd):
import posix import os
pipe = posix.popen('{ ' + cmd + '; } 2>&1', 'r') pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
text = pipe.read() text = pipe.read()
sts = pipe.close() sts = pipe.close()
if sts == None: sts = 0 if sts == None: sts = 0
@ -35,8 +35,8 @@ def getstatusoutput(cmd):
# Make command argument from directory and pathname (prefix space, add quotes). # Make command argument from directory and pathname (prefix space, add quotes).
# #
def mk2arg(head, x): def mk2arg(head, x):
import posixpath import os
return mkarg(posixpath.join(head, x)) return mkarg(os.path.join(head, x))
# Make a shell command argument from a string. # Make a shell command argument from a string.

View File

@ -68,8 +68,8 @@ hasname = []
hasjrel = [] hasjrel = []
hasjabs = [] hasjabs = []
opname = range(256) opname = [''] * 256
for op in opname: opname[op] = '<' + `op` + '>' for op in range(256): opname[op] = '<' + `op` + '>'
def def_op(name, op): def def_op(name, op):
opname[op] = name opname[op] = name

View File

@ -5,7 +5,7 @@
# Example: # Example:
# #
# >>> from ftplib import FTP # >>> 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 # >>> ftp.login() # default, i.e.: user anonymous, passwd user@hostname
# >>> def handle_one_line(line): # callback for ftp.retrlines # >>> def handle_one_line(line): # callback for ftp.retrlines
# ... print line # ... print line
@ -109,8 +109,9 @@ class FTP:
# 0: no debugging output (default) # 0: no debugging output (default)
# 1: print commands and responses but not body text etc. # 1: print commands and responses but not body text etc.
# 2: also print raw lines read and sent before stripping CR/LF # 2: also print raw lines read and sent before stripping CR/LF
def debug(self, level): def set_debuglevel(self, level):
self.debugging = level self.debugging = level
debug = set_debuglevel
# Internal: send one line to the server, appending CRLF # Internal: send one line to the server, appending CRLF
def putline(self, line): def putline(self, line):
@ -405,8 +406,8 @@ def test():
debugging = debugging+1 debugging = debugging+1
del sys.argv[1] del sys.argv[1]
host = sys.argv[1] host = sys.argv[1]
ftp = FTP().init(host) ftp = FTP(host)
ftp.debug(debugging) ftp.set_debuglevel(debugging)
ftp.login() ftp.login()
def writeln(line): print line def writeln(line): print line
for file in sys.argv[2:]: for file in sys.argv[2:]:

View File

@ -38,3 +38,33 @@ except ImportError:
import macpath import macpath
path = macpath path = macpath
del 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

View File

@ -100,6 +100,7 @@ def index(s, sub, *args):
if len(args) > 1: if len(args) > 1:
raise TypeError, 'string.index(): too many args' raise TypeError, 'string.index(): too many args'
i = args[0] i = args[0]
if i < 0: i = i + len(s)
else: else:
i = 0 i = 0
n = len(sub) n = len(sub)
@ -109,6 +110,25 @@ def index(s, sub, *args):
i = i+1 i = i+1
raise index_error, (s, sub) + args 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 # Find substring, return -1 if not found
def find(*args): def find(*args):
try: try:
@ -116,6 +136,13 @@ def find(*args):
except index_error: except index_error:
return -1 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 # Convert string to float
atof_error = 'non-float argument to string.atof' atof_error = 'non-float argument to string.atof'
def atof(str): def atof(str):

View File

@ -100,6 +100,7 @@ def index(s, sub, *args):
if len(args) > 1: if len(args) > 1:
raise TypeError, 'string.index(): too many args' raise TypeError, 'string.index(): too many args'
i = args[0] i = args[0]
if i < 0: i = i + len(s)
else: else:
i = 0 i = 0
n = len(sub) n = len(sub)
@ -109,6 +110,25 @@ def index(s, sub, *args):
i = i+1 i = i+1
raise index_error, (s, sub) + args 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 # Find substring, return -1 if not found
def find(*args): def find(*args):
try: try:
@ -116,6 +136,13 @@ def find(*args):
except index_error: except index_error:
return -1 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 # Convert string to float
atof_error = 'non-float argument to string.atof' atof_error = 'non-float argument to string.atof'
def atof(str): def atof(str):

View File

@ -90,6 +90,14 @@ f.close()
execfile(TESTFN) execfile(TESTFN)
unlink(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' print 'float'
if float(3.14) <> 3.14: raise TestFailed, 'float(3.14)' if float(3.14) <> 3.14: raise TestFailed, 'float(3.14)'
if float(314) <> 314.0: raise TestFailed, 'float(314)' 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(3.14) <> 3: raise TestFailed, 'int(3.14)'
if int(314L) <> 314: raise TestFailed, 'int(314L)' 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' print 'len'
if len('123') <> 3: raise TestFailed, 'len(\'123\')' if len('123') <> 3: raise TestFailed, 'len(\'123\')'
if len(()) <> 0: raise TestFailed, 'len(())' 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(3.14) <> 3L: raise TestFailed, 'long(3.14)'
if long(314L) <> 314L: raise TestFailed, 'long(314L)' 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' print 'max'
if max('123123') <> '3': raise TestFailed, 'max(\'123123\')' if max('123123') <> '3': raise TestFailed, 'max(\'123123\')'
if max(1, 2, 3) <> 3: raise TestFailed, 'max(1, 2, 3)' if max(1, 2, 3) <> 3: raise TestFailed, 'max(1, 2, 3)'

View File

@ -111,6 +111,16 @@ finally:
sys.stdin = savestdin sys.stdin = savestdin
fp.close() 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' print 'reload'
import string import string
reload(string) reload(string)

View File

@ -24,16 +24,19 @@ print '1.1.2.1 Plain integers'
if 0xff <> 255: raise TestFailed, 'hex int' if 0xff <> 255: raise TestFailed, 'hex int'
if 0377 <> 255: raise TestFailed, 'octal int' if 0377 <> 255: raise TestFailed, 'octal int'
if 2147483647 != 017777777777: raise TestFailed, 'max positive int' if 2147483647 != 017777777777: raise TestFailed, 'max positive int'
if -2147483647-1 != 020000000000: raise TestFailed, 'max negative int' # Change the following line to "if 0:" if you have 64-bit integers
# XXX -2147483648 if 1:
if 037777777777 != -1: raise TestFailed, 'oct -1' if -2147483647-1 != 020000000000: raise TestFailed, 'max negative int'
if 0xffffffff != -1: raise TestFailed, 'hex -1' # XXX -2147483648
for s in '2147483648', '040000000000', '0x100000000': if 037777777777 != -1: raise TestFailed, 'oct -1'
try: if 0xffffffff != -1: raise TestFailed, 'hex -1'
x = eval(s) for s in '2147483648', '040000000000', '0x100000000':
except OverflowError: try:
continue x = eval(s)
raise TestFailed, 'No OverflowError on huge integer literal ' + `s` except OverflowError:
continue
raise TestFailed, \
'No OverflowError on huge integer literal ' + `s`
print '1.1.2.2 Long integers' print '1.1.2.2 Long integers'
x = 0L x = 0L

View File

@ -73,12 +73,15 @@ dir
divmod divmod
eval eval
execfile execfile
filter
float float
getattr getattr
hex hex
int int
lambda
len len
long long
map
max max
min min
test_b2 test_b2
@ -90,6 +93,7 @@ range
input and raw_input input and raw_input
testing testing
testing testing
reduce
reload reload
repr repr
round round