From 217a5fa3c33ae58c1fe420f94eeb7e806961c3c1 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 26 Dec 1990 15:40:07 +0000 Subject: Initial revision --- Lib/dis.py | 176 ++++++++++++++++++++ Lib/grep.py | 32 ++++ Lib/lib-old/grep.py | 32 ++++ Lib/lib-old/packmail.py | 48 ++++++ Lib/lib-old/tb.py | 220 +++++++++++++++++++++++++ Lib/macpath.py | 70 ++++++++ Lib/packmail.py | 48 ++++++ Lib/sunaudio.py | 54 +++++++ Lib/tb.py | 220 +++++++++++++++++++++++++ Lib/test/testall.py | 416 ++++++++++++++++++++++++++++++++++++++++++++++++ Mac/Lib/maccache.py | 61 +++++++ 11 files changed, 1377 insertions(+) create mode 100644 Lib/dis.py create mode 100644 Lib/grep.py create mode 100644 Lib/lib-old/grep.py create mode 100644 Lib/lib-old/packmail.py create mode 100644 Lib/lib-old/tb.py create mode 100644 Lib/macpath.py create mode 100644 Lib/packmail.py create mode 100644 Lib/sunaudio.py create mode 100644 Lib/tb.py create mode 100644 Lib/test/testall.py create mode 100644 Mac/Lib/maccache.py diff --git a/Lib/dis.py b/Lib/dis.py new file mode 100644 index 0000000..fe57fb9 --- /dev/null +++ b/Lib/dis.py @@ -0,0 +1,176 @@ +# Disassembler + +import sys +import string + +def dis(): + tb = sys.last_traceback + while tb.tb_next: tb = tb.tb_next + distb(tb) + +def distb(tb): + disassemble(tb.tb_frame.f_code, tb.tb_lasti) + +def disco(co): + disassemble(co, -1) + +def disassemble(co, lasti): + code = co.co_code + labels = findlabels(code) + n = len(code) + i = 0 + while i < n: + c = code[i] + op = ord(c) + if op = SET_LINENO and i > 0: print # Extra blank line + if i = lasti: print '-->', + else: print ' ', + if i in labels: print '>>', + else: print ' ', + print string.rjust(`i`, 4), + print string.ljust(opname[op], 15), + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + print string.rjust(`oparg`, 5), + if op in hasconst: + print '(' + `co.co_consts[oparg]` + ')', + elif op in hasname: + print '(' + co.co_names[oparg] + ')', + elif op in hasjrel: + print '(to ' + `i + oparg` + ')', + print + +def findlabels(code): + labels = [] + n = len(code) + i = 0 + while i < n: + c = code[i] + op = ord(c) + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + label = -1 + if op in hasjrel: + label = i+oparg + elif op in hasjabs: + label = oparg + if label >= 0: + if label not in labels: + labels.append(label) + return labels + +hasconst = [] +hasname = [] +hasjrel = [] +hasjabs = [] + +opname = range(256) +for op in opname: opname[op] = '<' + `op` + '>' + +def def_op(name, op): + opname[op] = name + +def name_op(name, op): + opname[op] = name + hasname.append(op) + +def jrel_op(name, op): + opname[op] = name + hasjrel.append(op) + +def jabs_op(name, op): + opname[op] = name + hasjabs.append(op) + +# Instruction opcodes for compiled code + +def_op('STOP_CODE', 0) +def_op('POP_TOP', 1) +def_op('ROT_TWO', 2) +def_op('ROT_THREE', 3) +def_op('DUP_TOP', 4) + +def_op('UNARY_POSITIVE', 10) +def_op('UNARY_NEGATIVE', 11) +def_op('UNARY_NOT', 12) +def_op('UNARY_CONVERT', 13) +def_op('UNARY_CALL', 14) + +def_op('BINARY_MULTIPLY', 20) +def_op('BINARY_DIVIDE', 21) +def_op('BINARY_MODULO', 22) +def_op('BINARY_ADD', 23) +def_op('BINARY_SUBTRACT', 24) +def_op('BINARY_SUBSCR', 25) +def_op('BINARY_CALL', 26) + +def_op('SLICE+0', 30) +def_op('SLICE+1', 31) +def_op('SLICE+2', 32) +def_op('SLICE+3', 33) + +def_op('STORE_SLICE+0', 40) +def_op('STORE_SLICE+1', 41) +def_op('STORE_SLICE+2', 42) +def_op('STORE_SLICE+3', 43) + +def_op('DELETE_SLICE+0', 50) +def_op('DELETE_SLICE+1', 51) +def_op('DELETE_SLICE+2', 52) +def_op('DELETE_SLICE+3', 53) + +def_op('STORE_SUBSCR', 60) +def_op('DELETE_SUBSCR', 61) + +def_op('PRINT_EXPR', 70) +def_op('PRINT_ITEM', 71) +def_op('PRINT_NEWLINE', 72) + +def_op('BREAK_LOOP', 80) +def_op('RAISE_EXCEPTION', 81) +def_op('LOAD_LOCALS', 82) +def_op('RETURN_VALUE', 83) +def_op('REQUIRE_ARGS', 84) +def_op('REFUSE_ARGS', 85) +def_op('BUILD_FUNCTION', 86) +def_op('POP_BLOCK', 87) +def_op('END_FINALLY', 88) +def_op('BUILD_CLASS', 89) + +HAVE_ARGUMENT = 90 # Opcodes from here have an argument: + +name_op('STORE_NAME', 90) # Index in name list +name_op('DELETE_NAME', 91) # "" +def_op('UNPACK_TUPLE', 92) # Number of tuple items +def_op('UNPACK_LIST', 93) # Number of list items +# unused: 94 +name_op('STORE_ATTR', 95) # Index in name list +name_op('DELETE_ATTR', 96) # "" + +def_op('LOAD_CONST', 100) # Index in const list +hasconst.append(100) +name_op('LOAD_NAME', 101) # Index in name list +def_op('BUILD_TUPLE', 102) # Number of tuple items +def_op('BUILD_LIST', 103) # Number of list items +def_op('BUILD_MAP', 104) # Always zero for now +name_op('LOAD_ATTR', 105) # Index in name list +def_op('COMPARE_OP', 106) # Comparison operator +name_op('IMPORT_NAME', 107) # Index in name list +name_op('IMPORT_FROM', 108) # Index in name list + +jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip +jrel_op('JUMP_IF_FALSE', 111) # "" +jrel_op('JUMP_IF_TRUE', 112) # "" +jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code +jrel_op('FOR_LOOP', 114) # Number of bytes to skip + +jrel_op('SETUP_LOOP', 120) # Distance to target address +jrel_op('SETUP_EXCEPT', 121) # "" +jrel_op('SETUP_FINALLY', 122) # "" + +def_op('SET_LINENO', 127) # Current line number +SET_LINENO = 127 diff --git a/Lib/grep.py b/Lib/grep.py new file mode 100644 index 0000000..210f9f0 --- /dev/null +++ b/Lib/grep.py @@ -0,0 +1,32 @@ +# 'grep' + +import regexp +import string + +def grep(expr, filename): + prog = regexp.compile(expr) + fp = open(filename, 'r') + lineno = 0 + while 1: + line = fp.readline() + if not line: break + lineno = lineno + 1 + res = prog.exec(line) + if res: + #print res + start, end = res[0] + if line[-1:] = '\n': line = line[:-1] + prefix = string.rjust(`lineno`, 3) + ': ' + print prefix + line + if 0: + line = line[:start] + if '\t' not in line: + prefix = ' ' * (len(prefix) + start) + else: + prefix = ' ' * len(prefix) + for c in line: + if c <> '\t': c = ' ' + prefix = prefix + c + if start = end: prefix = prefix + '\\' + else: prefix = prefix + '^'*(end-start) + print prefix diff --git a/Lib/lib-old/grep.py b/Lib/lib-old/grep.py new file mode 100644 index 0000000..210f9f0 --- /dev/null +++ b/Lib/lib-old/grep.py @@ -0,0 +1,32 @@ +# 'grep' + +import regexp +import string + +def grep(expr, filename): + prog = regexp.compile(expr) + fp = open(filename, 'r') + lineno = 0 + while 1: + line = fp.readline() + if not line: break + lineno = lineno + 1 + res = prog.exec(line) + if res: + #print res + start, end = res[0] + if line[-1:] = '\n': line = line[:-1] + prefix = string.rjust(`lineno`, 3) + ': ' + print prefix + line + if 0: + line = line[:start] + if '\t' not in line: + prefix = ' ' * (len(prefix) + start) + else: + prefix = ' ' * len(prefix) + for c in line: + if c <> '\t': c = ' ' + prefix = prefix + c + if start = end: prefix = prefix + '\\' + else: prefix = prefix + '^'*(end-start) + print prefix diff --git a/Lib/lib-old/packmail.py b/Lib/lib-old/packmail.py new file mode 100644 index 0000000..c7bebe8 --- /dev/null +++ b/Lib/lib-old/packmail.py @@ -0,0 +1,48 @@ +# Module 'packmail' -- create a shell script out of some files. + +import mac +import macpath +from stat import ST_MTIME + +# Pack one file +def pack(outfp, file, name): + fp = open(file, 'r') + outfp.write('sed "s/^X//" >' + name + ' <<"!"\n') + while 1: + line = fp.readline() + if not line: break + if line[-1:] <> '\n': + line = line + '\n' + outfp.write('X' + line) + outfp.write('!\n') + +# Pack some files from a directory +def packsome(outfp, dirname, names): + for name in names: + print name + file = macpath.cat(dirname, name) + pack(outfp, file, name) + +# Pack all files from a directory +def packall(outfp, dirname): + names = mac.listdir(dirname) + names.sort() + packsome(outfp, dirname, names) + +# Pack all files from a directory that are not older than a give one +def packnotolder(outfp, dirname, oldest): + names = mac.listdir(dirname) + oldest = macpath.cat(dirname, oldest) + st = mac.stat(oldest) + mtime = st[ST_MTIME] + todo = [] + for name in names: + print name, '...', + st = mac.stat(macpath.cat(dirname, name)) + if st[ST_MTIME] >= mtime: + print 'Yes.' + todo.append(name) + else: + print 'No.' + todo.sort() + packsome(outfp, dirname, todo) diff --git a/Lib/lib-old/tb.py b/Lib/lib-old/tb.py new file mode 100644 index 0000000..e0f2748 --- /dev/null +++ b/Lib/lib-old/tb.py @@ -0,0 +1,220 @@ +# Print tracebacks, with a dump of local variables. +# Also an interactive stack trace browser. + +import sys +try: + import mac + os = mac +except NameError: + import posix + os = posix +from stat import * +import string + +def br(): browser(sys.last_traceback) + +def tb(): printtb(sys.last_traceback) + +def browser(tb): + if not tb: + print 'No traceback.' + return + tblist = [] + while tb: + tblist.append(tb) + tb = tb.tb_next + ptr = len(tblist)-1 + tb = tblist[ptr] + while 1: + if tb <> tblist[ptr]: + tb = tblist[ptr] + print `ptr` + ':', + printtbheader(tb) + try: + line = raw_input('TB: ') + except KeyboardInterrupt: + print '\n[Interrupted]' + break + except EOFError: + print '\n[EOF]' + break + cmd = string.strip(line) + if cmd: + if cmd = 'quit': + break + elif cmd = 'list': + browserlist(tb) + elif cmd = 'up': + if ptr-1 >= 0: ptr = ptr-1 + else: print 'Bottom of stack.' + elif cmd = 'down': + if ptr+1 < len(tblist): ptr = ptr+1 + else: print 'Top of stack.' + elif cmd = 'locals': + printsymbols(tb.tb_frame.f_locals) + elif cmd = 'globals': + printsymbols(tb.tb_frame.f_globals) + elif cmd in ('?', 'help'): + browserhelp() + else: + browserexec(tb, cmd) + +def browserlist(tb): + filename = tb.tb_frame.f_code.co_filename + lineno = tb.tb_lineno + last = lineno + first = max(1, last-10) + for i in range(first, last+1): + if i = lineno: prefix = '***' + string.rjust(`i`, 4) + ':' + else: prefix = string.rjust(`i`, 7) + ':' + line = readfileline(filename, i) + if line[-1:] = '\n': line = line[:-1] + print prefix + line + +def browserexec(tb, cmd): + locals = tb.tb_frame.f_locals + globals = tb.tb_frame.f_globals + try: + exec(cmd+'\n', globals, locals) + except: + print '*** Exception:', + print sys.exc_type, + if sys.exc_value <> None: + print ':', sys.exc_value, + print + print 'Type help to get help.' + +def browserhelp(): + print + print ' This is the traceback browser. Commands are:' + print ' up : move one level up in the call stack' + print ' down : move one level down in the call stack' + print ' locals : print all local variables at this level' + print ' globals : print all global variables at this level' + print ' list : list source code around the failure' + print ' help : print help (what you are reading now)' + print ' quit : back to command interpreter' + print ' Typing any other 1-line statement will execute it' + print ' using the current level\'s symbol tables' + print + +def printtb(tb): + while tb: + print1tb(tb) + tb = tb.tb_next + +def print1tb(tb): + printtbheader(tb) + if tb.tb_frame.f_locals is not tb.tb_frame.f_globals: + printsymbols(tb.tb_frame.f_locals) + +def printtbheader(tb): + filename = tb.tb_frame.f_code.co_filename + lineno = tb.tb_lineno + info = '"' + filename + '"(' + `lineno` + ')' + line = readfileline(filename, lineno) + if line: + info = info + ': ' + string.strip(line) + print info + +def printsymbols(d): + keys = d.keys() + keys.sort() + for name in keys: + print ' ' + string.ljust(name, 12) + ':', + printobject(d[name], 4) + print + +def printobject(v, maxlevel): + if v = None: + print 'None', + elif type(v) in (type(0), type(0.0)): + print v, + elif type(v) = type(''): + if len(v) > 20: + print `v[:17] + '...'`, + else: + print `v`, + elif type(v) = type(()): + print '(', + printlist(v, maxlevel) + print ')', + elif type(v) = type([]): + print '[', + printlist(v, maxlevel) + print ']', + elif type(v) = type({}): + print '{', + printdict(v, maxlevel) + print '}', + else: + print v, + +def printlist(v, maxlevel): + n = len(v) + if n = 0: return + if maxlevel <= 0: + print '...', + return + for i in range(min(6, n)): + printobject(v[i], maxlevel-1) + if i+1 < n: print ',', + if n > 6: print '...', + +def printdict(v, maxlevel): + keys = v.keys() + n = len(keys) + if n = 0: return + if maxlevel <= 0: + print '...', + return + keys.sort() + for i in range(min(6, n)): + key = keys[i] + print `key` + ':', + printobject(v[key], maxlevel-1) + if i+1 < n: print ',', + if n > 6: print '...', + +_filecache = {} + +def readfileline(filename, lineno): + try: + stat = os.stat(filename) + except os.error, msg: + print 'Cannot stat', filename, '--', msg + return '' + cache_ok = 0 + if _filecache.has_key(filename): + cached_stat, lines = _filecache[filename] + if stat[ST_SIZE] = cached_stat[ST_SIZE] and \ + stat[ST_MTIME] = cached_stat[ST_MTIME]: + cache_ok = 1 + else: + print 'Stale cache entry for', filename + del _filecache[filename] + if not cache_ok: + lines = readfilelines(filename) + if not lines: + return '' + _filecache[filename] = stat, lines + if 0 <= lineno-1 < len(lines): + return lines[lineno-1] + else: + print 'Line number out of range, last line is', len(lines) + return '' + +def readfilelines(filename): + try: + fp = open(filename, 'r') + except: + print 'Cannot open', filename + return [] + lines = [] + while 1: + line = fp.readline() + if not line: break + lines.append(line) + if not lines: + print 'Empty file', filename + return lines diff --git a/Lib/macpath.py b/Lib/macpath.py new file mode 100644 index 0000000..30d2f27 --- /dev/null +++ b/Lib/macpath.py @@ -0,0 +1,70 @@ +# module 'macpath' + +import mac + +import string + +from stat import * + +def isabs(s): + return ':' in s and s[0] <> ':' + +def cat(s, t): + if (not s) or isabs(t): return t + if t[:1] = ':': t = t[1:] + if ':' not in s: + s = ':' + s + if s[-1:] <> ':': + s = s + ':' + return s + t + +norm_error = 'path cannot be normalized' + +def norm(s): + if ':' not in s: + return ':' + s + f = string.splitfields(s, ':') + pre = [] + post = [] + if not f[0]: + pre = f[:1] + f = f[1:] + if not f[len(f)-1]: + post = f[-1:] + f = f[:-1] + res = [] + for seg in f: + if seg: + res.append(seg) + else: + if not res: raise norm_error # starts with '::' + del res[len(res)-1] + if not (pre or res): + raise norm_error # starts with 'vol::' + if pre: res = pre + res + if post: res = res + post + s = res[0] + for seg in res[1:]: + s = s + ':' + seg + return s + +def isdir(s): + try: + st = mac.stat(s) + except mac.error: + return 0 + return S_ISDIR(st[ST_MODE]) + +def isfile(s): + try: + st = mac.stat(s) + except mac.error: + return 0 + return S_ISREG(st[ST_MODE]) + +def exists(s): + try: + st = mac.stat(s) + except mac.error: + return 0 + return 1 diff --git a/Lib/packmail.py b/Lib/packmail.py new file mode 100644 index 0000000..c7bebe8 --- /dev/null +++ b/Lib/packmail.py @@ -0,0 +1,48 @@ +# Module 'packmail' -- create a shell script out of some files. + +import mac +import macpath +from stat import ST_MTIME + +# Pack one file +def pack(outfp, file, name): + fp = open(file, 'r') + outfp.write('sed "s/^X//" >' + name + ' <<"!"\n') + while 1: + line = fp.readline() + if not line: break + if line[-1:] <> '\n': + line = line + '\n' + outfp.write('X' + line) + outfp.write('!\n') + +# Pack some files from a directory +def packsome(outfp, dirname, names): + for name in names: + print name + file = macpath.cat(dirname, name) + pack(outfp, file, name) + +# Pack all files from a directory +def packall(outfp, dirname): + names = mac.listdir(dirname) + names.sort() + packsome(outfp, dirname, names) + +# Pack all files from a directory that are not older than a give one +def packnotolder(outfp, dirname, oldest): + names = mac.listdir(dirname) + oldest = macpath.cat(dirname, oldest) + st = mac.stat(oldest) + mtime = st[ST_MTIME] + todo = [] + for name in names: + print name, '...', + st = mac.stat(macpath.cat(dirname, name)) + if st[ST_MTIME] >= mtime: + print 'Yes.' + todo.append(name) + else: + print 'No.' + todo.sort() + packsome(outfp, dirname, todo) diff --git a/Lib/sunaudio.py b/Lib/sunaudio.py new file mode 100644 index 0000000..92a6203 --- /dev/null +++ b/Lib/sunaudio.py @@ -0,0 +1,54 @@ +# Module 'sunaudio' -- interpret sun audio headers + +import audio + +MAGIC = '.snd' + +error = 'sunaudio sound header conversion error' + + +# convert a 4-char value to integer + +def c2i(data): + if type(data) <> type('') or len(data) <> 4: + raise error, 'c2i: bad arg (not string[4])' + bytes = audio.chr2num(data) + for i in (1, 2, 3): + if bytes[i] < 0: + bytes[i] = bytes[i] + 256 + return ((bytes[0]*256 + bytes[1])*256 + bytes[2])*256 + bytes[3] + + +# read a sound header from an open file + +def gethdr(fp): + if fp.read(4) <> MAGIC: + raise error, 'gethdr: bad magic word' + hdr_size = c2i(fp.read(4)) + data_size = c2i(fp.read(4)) + encoding = c2i(fp.read(4)) + sample_rate = c2i(fp.read(4)) + channels = c2i(fp.read(4)) + excess = hdr_size - 24 + if excess < 0: + raise error, 'gethdr: bad hdr_size' + if excess > 0: + info = fp.read(excess) + else: + info = '' + return (data_size, encoding, sample_rate, channels, info) + + +# read and print the sound header of a named file + +def printhdr(file): + hdr = gethdr(open(file, 'r')) + data_size, encoding, sample_rate, channels, info = hdr + while info[-1:] = '\0': + info = info[:-1] + print 'File name: ', file + print 'Data size: ', data_size + print 'Encoding: ', encoding + print 'Sample rate:', sample_rate + print 'Channels: ', channels + print 'Info: ', `info` diff --git a/Lib/tb.py b/Lib/tb.py new file mode 100644 index 0000000..e0f2748 --- /dev/null +++ b/Lib/tb.py @@ -0,0 +1,220 @@ +# Print tracebacks, with a dump of local variables. +# Also an interactive stack trace browser. + +import sys +try: + import mac + os = mac +except NameError: + import posix + os = posix +from stat import * +import string + +def br(): browser(sys.last_traceback) + +def tb(): printtb(sys.last_traceback) + +def browser(tb): + if not tb: + print 'No traceback.' + return + tblist = [] + while tb: + tblist.append(tb) + tb = tb.tb_next + ptr = len(tblist)-1 + tb = tblist[ptr] + while 1: + if tb <> tblist[ptr]: + tb = tblist[ptr] + print `ptr` + ':', + printtbheader(tb) + try: + line = raw_input('TB: ') + except KeyboardInterrupt: + print '\n[Interrupted]' + break + except EOFError: + print '\n[EOF]' + break + cmd = string.strip(line) + if cmd: + if cmd = 'quit': + break + elif cmd = 'list': + browserlist(tb) + elif cmd = 'up': + if ptr-1 >= 0: ptr = ptr-1 + else: print 'Bottom of stack.' + elif cmd = 'down': + if ptr+1 < len(tblist): ptr = ptr+1 + else: print 'Top of stack.' + elif cmd = 'locals': + printsymbols(tb.tb_frame.f_locals) + elif cmd = 'globals': + printsymbols(tb.tb_frame.f_globals) + elif cmd in ('?', 'help'): + browserhelp() + else: + browserexec(tb, cmd) + +def browserlist(tb): + filename = tb.tb_frame.f_code.co_filename + lineno = tb.tb_lineno + last = lineno + first = max(1, last-10) + for i in range(first, last+1): + if i = lineno: prefix = '***' + string.rjust(`i`, 4) + ':' + else: prefix = string.rjust(`i`, 7) + ':' + line = readfileline(filename, i) + if line[-1:] = '\n': line = line[:-1] + print prefix + line + +def browserexec(tb, cmd): + locals = tb.tb_frame.f_locals + globals = tb.tb_frame.f_globals + try: + exec(cmd+'\n', globals, locals) + except: + print '*** Exception:', + print sys.exc_type, + if sys.exc_value <> None: + print ':', sys.exc_value, + print + print 'Type help to get help.' + +def browserhelp(): + print + print ' This is the traceback browser. Commands are:' + print ' up : move one level up in the call stack' + print ' down : move one level down in the call stack' + print ' locals : print all local variables at this level' + print ' globals : print all global variables at this level' + print ' list : list source code around the failure' + print ' help : print help (what you are reading now)' + print ' quit : back to command interpreter' + print ' Typing any other 1-line statement will execute it' + print ' using the current level\'s symbol tables' + print + +def printtb(tb): + while tb: + print1tb(tb) + tb = tb.tb_next + +def print1tb(tb): + printtbheader(tb) + if tb.tb_frame.f_locals is not tb.tb_frame.f_globals: + printsymbols(tb.tb_frame.f_locals) + +def printtbheader(tb): + filename = tb.tb_frame.f_code.co_filename + lineno = tb.tb_lineno + info = '"' + filename + '"(' + `lineno` + ')' + line = readfileline(filename, lineno) + if line: + info = info + ': ' + string.strip(line) + print info + +def printsymbols(d): + keys = d.keys() + keys.sort() + for name in keys: + print ' ' + string.ljust(name, 12) + ':', + printobject(d[name], 4) + print + +def printobject(v, maxlevel): + if v = None: + print 'None', + elif type(v) in (type(0), type(0.0)): + print v, + elif type(v) = type(''): + if len(v) > 20: + print `v[:17] + '...'`, + else: + print `v`, + elif type(v) = type(()): + print '(', + printlist(v, maxlevel) + print ')', + elif type(v) = type([]): + print '[', + printlist(v, maxlevel) + print ']', + elif type(v) = type({}): + print '{', + printdict(v, maxlevel) + print '}', + else: + print v, + +def printlist(v, maxlevel): + n = len(v) + if n = 0: return + if maxlevel <= 0: + print '...', + return + for i in range(min(6, n)): + printobject(v[i], maxlevel-1) + if i+1 < n: print ',', + if n > 6: print '...', + +def printdict(v, maxlevel): + keys = v.keys() + n = len(keys) + if n = 0: return + if maxlevel <= 0: + print '...', + return + keys.sort() + for i in range(min(6, n)): + key = keys[i] + print `key` + ':', + printobject(v[key], maxlevel-1) + if i+1 < n: print ',', + if n > 6: print '...', + +_filecache = {} + +def readfileline(filename, lineno): + try: + stat = os.stat(filename) + except os.error, msg: + print 'Cannot stat', filename, '--', msg + return '' + cache_ok = 0 + if _filecache.has_key(filename): + cached_stat, lines = _filecache[filename] + if stat[ST_SIZE] = cached_stat[ST_SIZE] and \ + stat[ST_MTIME] = cached_stat[ST_MTIME]: + cache_ok = 1 + else: + print 'Stale cache entry for', filename + del _filecache[filename] + if not cache_ok: + lines = readfilelines(filename) + if not lines: + return '' + _filecache[filename] = stat, lines + if 0 <= lineno-1 < len(lines): + return lines[lineno-1] + else: + print 'Line number out of range, last line is', len(lines) + return '' + +def readfilelines(filename): + try: + fp = open(filename, 'r') + except: + print 'Cannot open', filename + return [] + lines = [] + while 1: + line = fp.readline() + if not line: break + lines.append(line) + if not lines: + print 'Empty file', filename + return lines diff --git a/Lib/test/testall.py b/Lib/test/testall.py new file mode 100644 index 0000000..ef7cb13 --- /dev/null +++ b/Lib/test/testall.py @@ -0,0 +1,416 @@ +# Module 'testall' +# +# Python test set, should exercise: +# - all lexical and grammatical constructs +# - all opcodes from "opcode.h" +# - all operations on all object types +# - all builtin functions +# Ideally also: +# - all possible exception situations (Thank God we've got 'try') +# - all boundary cases + + +TestFailed = 'testall -- test failed' # Exception + + +######################################################### +# Part 1. Test all lexical and grammatical constructs. +# This just tests whether the parser accepts them all. +######################################################### + +print '1. Parser' + +print '1.1 Tokens' + +print '1.1.1 Backslashes' + +# Backslash means line continuation: +x = 1 \ ++ 1 +if x <> 2: raise TestFailed, 'backslash for line continuation' + +# Backslash does not means continuation in comments :\ +x = 0 +if x <> 0: raise TestFailed, 'backslash ending comment' + +print '1.1.2 Number formats' + +if 0xff <> 255: raise TestFailed, 'hex number' +if 0377 <> 255: raise TestFailed, 'octal number' +x = 3.14 +x = 0.314 +x = 3e14 +x = 3E14 +x = 3e-14 + +print '1.2 Grammar' + +print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE +# XXX can't test in a script -- this rule is only used when interactive + +print 'file_input' # (NEWLINE | stmt)* ENDMARKER +# Being tested as this very moment this very module + +print 'expr_input' # testlist NEWLINE +# XXX Hard to test -- used only in calls to input() + +print 'eval_input' # testlist ENDMARKER +x = eval('1, 0 or 1') + +print 'funcdef' # 'def' NAME parameters ':' suite +### parameters: '(' [fplist] ')' +### fplist: fpdef (',' fpdef)* +### fpdef: NAME | '(' fplist ')' +def f1(): pass +def f2(one_argument): pass +def f3(two, arguments): pass +def f4(two, (compound, (arguments))): pass + +### stmt: simple_stmt | compound_stmt +### simple_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt +# Tested below + +print 'expr_stmt' # (exprlist '=')* exprlist NEWLINE +1 +1, 2, 3 +x = 1 +x = 1, 2, 3 +x = y = z = 1, 2, 3 +x, y, z = 1, 2, 3 +abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) +# NB these variables are deleted below + +print 'print_stmt' # 'print' (test ',')* [test] NEWLINE +print 1, 2, 3 +print 1, 2, 3, +print +print 0 or 1, 0 or 1, +print 0 or 1 + +print 'del_stmt' # 'del' exprlist NEWLINE +del abc +del x, y, (z, xyz) + +print 'pass_stmt' # 'pass' NEWLINE +pass + +print 'flow_stmt' # break_stmt | return_stmt | raise_stmt +# Tested below + +print 'break_stmt' # 'break' NEWLINE +while 1: break + +print 'return_stmt' # 'return' [testlist] NEWLINE +def g1(): return +def g2(): return 1 +g1() +x = g2() + +print 'raise_stmt' # 'raise' expr [',' expr] NEWLINE +try: raise RuntimeError, 'just testing' +except RuntimeError: pass +try: raise KeyboardInterrupt +except KeyboardInterrupt: pass + +print 'import_stmt' # 'import' NAME (',' NAME)* NEWLINE | 'from' NAME 'import' ('*' | NAME (',' NAME)*) NEWLINE +[1] +import sys +[2] +import time, math +[3] +from time import sleep +[4] +from math import * +[5] +from sys import modules, ps1, ps2 +[6] + +### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef +# Tested below + +print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] +if 1: pass +if 1: pass +else: pass +if 0: pass +elif 0: pass +if 0: pass +elif 0: pass +elif 0: pass +elif 0: pass +else: pass + +print 'while_stmt' # 'while' test ':' suite ['else' ':' suite] +while 0: pass +while 0: pass +else: pass + +print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] +[1] +for i in 1, 2, 3: pass +[2] +for i, j, k in (): pass +else: pass +[3] + +print 'try_stmt' # 'try' ':' suite (except_clause ':' suite)* ['finally' ':' suite] +### except_clause: 'except' [expr [',' expr]] +try: pass +try: 1/0 +except RuntimeError: pass +try: 1/0 +except EOFError: pass +except TypeError, msg: pass +except RuntimeError, msg: pass +except: pass +try: pass +finally: pass +try: 1/0 +except: pass +finally: pass + +print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT +if 1: pass +if 1: + pass +if 1: + # + # + # + pass + pass + # + pass + # + +print 'test' # and_test ('or' and_test)* +### and_test: not_test ('and' not_test)* +### not_test: 'not' not_test | comparison +### comparison: expr (comp_op expr)* +### comp_op: '<'|'>'|'='|'>' '='|'<' '='|'<' '>'|'in'|'not' 'in'|'is'|'is' 'not' +if 1: pass +if 1 = 1: pass +if 1 < 1 > 1 = 1 >= 1 <= 1 <> 1 in 1 not in 1 is 1 is not 1: pass +if not 1 = 1 = 1: pass +if not 1 = 1 and 1 and 1: pass +if 1 and 1 or 1 and 1 and 1 or not 1 = 1 = 1 and 1: pass + +print 'expr' # term (('+'|'-') term)* +x = 1 +x = 1 + 1 +x = 1 - 1 - 1 +x = 1 - 1 + 1 - 1 + 1 + +print 'term' # factor (('*'|'/'|'%') factor)* +x = 1 * 1 +x = 1 / 1 +x = 1 % 1 +x = 1 / 1 * 1 % 1 + +print 'factor' # ('+'|'-') factor | atom trailer* +### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME +### subscript: expr | [expr] ':' [expr] +x = +1 +x = -1 +x = 1 +c = sys.ps1[0] +x = time.time() +x = sys.modules['time'].time() +a = '01234' +c = a[0] +c = a[0:5] +c = a[:5] +c = a[0:] +c = a[:] +c = a[-5:] +c = a[:-1] +c = a[-4:-3] + +print 'atom' # '(' [testlist] ')' | '[' [testlist] ']' | '{' '}' | '`' testlist '`' | NAME | NUMBER | STRING +x = (1) +x = (1 or 2 or 3) +x = (1 or 2 or 3, 2, 3) +x = [] +x = [1] +x = [1 or 2 or 3] +x = [1 or 2 or 3, 2, 3] +x = [] +x = {} +x = `x` +x = x +x = 'x' +x = 123 + +### exprlist: expr (',' expr)* [','] +### testlist: test (',' test)* [','] +# These have been exercised enough above + +print 'classdef' # 'class' NAME parameters ['=' baselist] ':' suite +### baselist: atom arguments (',' atom arguments)* +### arguments: '(' [testlist] ')' +class B(): pass +class C1() = B(): pass +class C2() = B(): pass +class D() = C1(), C2(), B(): pass +class C(): + def meth1(self): pass + def meth2(self, arg): pass + def meth3(self, (a1, a2)): pass + + +######################################################### +# Part 2. Test all opcodes from "opcode.h" +######################################################### + +print '2. Opcodes' +print 'XXX Not yet fully implemented' + +print '2.1 try inside for loop' +n = 0 +for i in range(10): + n = n+i + try: 1/0 + except NameError: pass + except RuntimeError: pass + except TypeError: pass + finally: pass + try: pass + except: pass + try: pass + finally: pass + n = n+i +if n <> 90: + raise TestFailed, 'try inside for' + + +######################################################### +# Part 3. Test all operations on all object types +######################################################### + +print '3. Object types' +print 'XXX Not yet implemented' + + +######################################################### +# Part 4. Test all built-in functions +######################################################### + +print '4. Built-in functions' + +print 'abs' +if abs(0) <> 0: raise TestFailed, 'abs(0)' +if abs(1234) <> 1234: raise TestFailed, 'abs(1234)' +if abs(-1234) <> 1234: raise TestFailed, 'abs(-1234)' +if abs(0.0) <> 0.0: raise TestFailed, 'abs(0.0)' +if abs(3.14) <> 3.14: raise TestFailed, 'abs(3.14)' +if abs(-3.14) <> 3.14: raise TestFailed, 'abs(-3.14)' + +print 'dir' +if 'x' not in dir(): raise TestFailed, 'dir()' +if 'modules' not in dir(sys): raise TestFailed, 'dir(sys)' + +print 'divmod' +if divmod(12, 7) <> (1, 5): raise TestFailed, 'divmod(12, 7)' +if divmod(-12, 7) <> (-2, 2): raise TestFailed, 'divmod(-12, 7)' +if divmod(12, -7) <> (-2, -2): raise TestFailed, 'divmod(12, -7)' +if divmod(-12, -7) <> (1, -5): raise TestFailed, 'divmod(-12, -7)' + +print 'eval' +if eval('1+1') <> 2: raise TestFailed, 'eval(\'1+1\')' + +print 'exec' +exec('z=1+1\n') +if z <> 2: raise TestFailed, 'exec(\'z=1+1\'\\n)' + +print 'float' +if float(3.14) <> 3.14: raise TestFailed, 'float(3.14)' +if float(314) <> 314.0: raise TestFailed, 'float(314)' + +print 'input' +# Can't test in a script + +print 'int' +if int(100) <> 100: raise TestFailed, 'int(100)' +if int(3.14) <> 3: raise TestFailed, 'int(3.14)' + +print 'len' +if len('123') <> 3: raise TestFailed, 'len(\'123\')' +if len(()) <> 0: raise TestFailed, 'len(())' +if len((1, 2, 3, 4)) <> 4: raise TestFailed, 'len((1, 2, 3, 4))' +if len([1, 2, 3, 4]) <> 4: raise TestFailed, 'len([1, 2, 3, 4])' +if len({}) <> 0: raise TestFailed, 'len({})' + +print 'min' +if min('123123') <> '1': raise TestFailed, 'min(\'123123\')' +if min(1, 2, 3) <> 1: raise TestFailed, 'min(1, 2, 3)' +if min((1, 2, 3, 1, 2, 3)) <> 1: raise TestFailed, 'min((1, 2, 3, 1, 2, 3))' +if min([1, 2, 3, 1, 2, 3]) <> 1: raise TestFailed, 'min([1, 2, 3, 1, 2, 3])' + +print 'max' +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, 1, 2, 3)) <> 3: raise TestFailed, 'max((1, 2, 3, 1, 2, 3))' +if max([1, 2, 3, 1, 2, 3]) <> 3: raise TestFailed, 'max([1, 2, 3, 1, 2, 3])' + +print 'open' +print 'NB! This test creates a file named "@test" in the current directory.' +fp = open('@test', 'w') +fp.write('The quick brown fox jumps over the lazy dog') +fp.write('.\n') +fp.write('Dear John\n') +fp.write('XXX'*100) +fp.write('YYY'*100) +fp.close() +del fp +fp = open('@test', 'r') +if fp.readline() <> 'The quick brown fox jumps over the lazy dog.\n': + raise TestFailed, 'readline()' +if fp.readline(4) <> 'Dear': raise TestFailed, 'readline(4) # short' +if fp.readline(100) <> ' John\n': raise TestFailed, 'readline(100)' +if fp.read(300) <> 'XXX'*100: raise TestFailed, 'read(300)' +if fp.read(1000) <> 'YYY'*100: raise TestFailed, 'read(1000) # truncate' +fp.close() +del fp + +print 'range' +if range(3) <> [0, 1, 2]: raise TestFailed, 'range(3)' +if range(1, 5) <> [1, 2, 3, 4]: raise TestFailed, 'range(1, 5)' +if range(0) <> []: raise TestFailed, 'range(0)' +if range(-3) <> []: raise TestFailed, 'range(-3)' +if range(1, 10, 3) <> [1, 4, 7]: raise TestFailed, 'range(1, 10, 3)' +if range(5, -5, -3) <> [5, 2, -1, -4]: raise TestFailed, 'range(5, -5, -3)' + +print 'raw_input' +savestdin = sys.stdin +try: + sys.stdin = open('@test', 'r') + if raw_input() <> 'The quick brown fox jumps over the lazy dog.': + raise TestFailed, 'raw_input()' + if raw_input('testing\n') <> 'Dear John': + raise TestFailed, 'raw_input(\'testing\\n\')' +finally: + sys.stdin = savestdin + +print 'reload' +import string +reload(string) + +print 'type' +if type('') <> type('123') or type('') = type(()): + raise TestFailed, 'type()' + + +print 'Passed all tests.' + +try: + import mac + unlink = mac.unlink +except NameError: + try: + import posix + unlink = posix.unlink + except NameError: + pass + +unlink('@test') +print 'Unlinked @test' diff --git a/Mac/Lib/maccache.py b/Mac/Lib/maccache.py new file mode 100644 index 0000000..dc6502b --- /dev/null +++ b/Mac/Lib/maccache.py @@ -0,0 +1,61 @@ +# Module 'maccache' +# +# Maintain a cache of listdir(), isdir(), isfile() or exists() outcomes. + +import mac +import macpath + + +# The cache. +# Keys are absolute pathnames; +# values are 0 (nothing), 1 (file) or [...] (dir). +# +cache = {} + + +# Current working directory. +# +cwd = mac.getcwd() + + +# Constants. +# +NONE = 0 +FILE = 1 +LISTTYPE = type([]) + +def _stat(name): + name = macpath.cat(cwd, name) + if cache.has_key(name): + return cache[name] + if macpath.isfile(name): + cache[name] = FILE + return FILE + try: + list = mac.listdir(name) + except: + cache[name] = NONE + return NONE + cache[name] = list + if name[-1:] = ':': cache[name[:-1]] = list + else: cache[name+':'] = list + return list + +def isdir(name): + st = _stat(name) + return type(st) = LISTTYPE + +def isfile(name): + st = _stat(name) + return st = FILE + +def exists(name): + st = _stat(name) + return st <> NONE + +def listdir(name): + st = _stat(name) + if type(st) = LISTTYPE: + return st + else: + raise RuntimeError, 'list non-directory' -- cgit v0.12