[pypy-svn] r5369 - in pypy/trunk/src/pypy: scripttest scripttest/test tool
rocco at codespeak.net
rocco at codespeak.net
Sun Jun 27 22:53:28 CEST 2004
Author: rocco
Date: Sun Jun 27 22:53:28 2004
New Revision: 5369
Added:
pypy/trunk/src/pypy/scripttest/ (props changed)
pypy/trunk/src/pypy/scripttest/__init__.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/autopath.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/grammar.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/grammar.txt (contents, props changed)
pypy/trunk/src/pypy/scripttest/test/ (props changed)
pypy/trunk/src/pypy/scripttest/test/__init__.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/test/autopath.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/test/test_grammar.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/test/test_tutorial.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/tutorial.py (contents, props changed)
pypy/trunk/src/pypy/scripttest/tutorial.txt (contents, props changed)
pypy/trunk/src/pypy/tool/app_level_diff.py (contents, props changed)
Log:
* tool/app_level_diff.py
I hacked together a little tool for running a script at app level, and checking
its output against an expected output file. (Sort of like regrtest.py) I added
a feature where the files can be sectioned off into multiple parts, to reduce
disk clutter.
* scripttest directory
The start of using app_level_diff as a testing tool - I've converted the
CPython regression test test_grammar to it's use. Sectioning is incomplete -
the parts that are sectioned are mainly to isolate failures
I've also started to do a script made from the examples given in Guido's
tutorial. Incomplete as of now.
I've commented out the tests that fail - These have to do with lambdas,
the exec statement, exponentiation, and imaginary numbers.
Added: pypy/trunk/src/pypy/scripttest/__init__.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/__init__.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1 @@
+#
Added: pypy/trunk/src/pypy/scripttest/autopath.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/autopath.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1,80 @@
+"""
+self cloning, automatic path configuration
+
+copy this into any subdirectory of pypy from which scripts need
+to be run, typically all of the test subdirs.
+The idea is that any such script simply issues
+
+ import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path.
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory.
+
+This module always provides these attributes:
+
+ pypydir pypy root directory path
+ this_dir directory where this autopath.py resides
+
+"""
+
+
+def __dirinfo(part):
+ """ return (partdir, this_dir) and insert parent of partdir
+ into sys.path. If the parent directories dont have the part
+ an EnvironmentError is raised."""
+
+ import sys, os
+ try:
+ head = this_dir = os.path.abspath(os.path.dirname(__file__))
+ except NameError:
+ head = this_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
+
+ while head:
+ partdir = head
+ head, tail = os.path.split(head)
+ if tail == part:
+ try:
+ sys.path.remove(head)
+ except ValueError:
+ pass
+ sys.path.insert(0, head)
+ return partdir, this_dir
+
+ raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path)
+
+def __clone():
+ """ clone master version of autopath.py into all subdirs """
+ from os.path import join, walk
+ if not this_dir.endswith(join('pypy','tool')):
+ raise EnvironmentError("can only clone master version "
+ "'%s'" % join(pypydir, 'tool',_myname))
+
+
+ def sync_walker(arg, dirname, fnames):
+ if _myname in fnames:
+ fn = join(dirname, _myname)
+ f = open(fn, 'rwb+')
+ try:
+ if f.read() == arg:
+ print "checkok", fn
+ else:
+ print "syncing", fn
+ f = open(fn, 'w')
+ f.write(arg)
+ finally:
+ f.close()
+ s = open(join(pypydir, 'tool', _myname), 'rb').read()
+ walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+ __clone()
Added: pypy/trunk/src/pypy/scripttest/grammar.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/grammar.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1,788 @@
+# Python test set -- part 1, grammar.
+# This just tests whether the parser accepts them all.
+
+# NOTE: When you run this test as a script from the command line, you
+# get warnings about certain hex/oct constants. Since those are
+# issued by the parser, you can't suppress them by adding a
+# filterwarnings() call to this module.
+
+# This is a modified version of the file found in the CPython Regression tests
+# Not all subsections have been broken apart - only enough to isolate
+# failures. Some sections need to remain combined due to dependancies on
+# definitions in previous sections.
+
+
+import sys
+
+def verify(condition, reason='test failed'):
+ if not condition:
+ print 'TestFailed -', reason
+
+def check_syntax(statement):
+ try:
+ compile(statement, '<string>', 'exec')
+ except SyntaxError:
+ pass
+ else:
+ print 'Missing SyntaxError: "%s"' % statement
+
+##! Section 1.
+
+print '1. Parser'
+
+print '1.1 Tokens'
+
+print '1.1.1 Backslashes'
+
+# Backslash means line continuation:
+x = 1 \
++ 1
+if x != 2: print 'Test Failed -', 'backslash for line continuation'
+
+# Backslash does not means continuation in comments :\
+x = 0
+if x != 0: print 'Test Failed -', 'backslash ending comment'
+
+print '1.1.2 Numeric literals'
+
+print '1.1.2.1 Plain integers'
+if 0xff != 255: print 'Test Failed -', 'hex int'
+if 0377 != 255: print 'Test Failed -', 'octal int'
+if 2147483647 != 017777777777: print 'Test Failed -', 'large positive int'
+try:
+ from sys import maxint
+except ImportError:
+ maxint = 2147483647
+if maxint == 2147483647:
+ # The following test will start to fail in Python 2.4;
+ # change the 020000000000 to -020000000000
+ if -2147483647-1 != 020000000000: print 'Test Failed -', 'max negative int'
+ # XXX -2147483648
+ if 037777777777 != -1: print 'Test Failed -', 'oct -1'
+ if 0xffffffff != -1: print 'Test Failed -', 'hex -1'
+ for s in '2147483648', '040000000000', '0x100000000':
+ try:
+ x = eval(s)
+ except OverflowError:
+ print "OverflowError on huge integer literal " + `s`
+elif eval('maxint == 9223372036854775807'):
+ if eval('-9223372036854775807-1 != 01000000000000000000000'):
+ print 'Test Failed -', 'max negative int'
+ if eval('01777777777777777777777') != -1: print 'Test Failed -', 'oct -1'
+ if eval('0xffffffffffffffff') != -1: print 'Test Failed -', 'hex -1'
+ for s in '9223372036854775808', '02000000000000000000000', \
+ '0x10000000000000000':
+ try:
+ x = eval(s)
+ except OverflowError:
+ print "OverflowError on huge integer literal " + `s`
+else:
+ print 'Weird maxint value', maxint
+
+print '1.1.2.2 Long integers'
+x = 0L
+x = 0l
+x = 0xffffffffffffffffL
+x = 0xffffffffffffffffl
+x = 077777777777777777L
+x = 077777777777777777l
+x = 123456789012345678901234567890L
+x = 123456789012345678901234567890l
+
+print '1.1.2.3 Floating point'
+x = 3.14
+x = 314.
+x = 0.314
+# XXX x = 000.314
+x = .314
+x = 3e14
+x = 3E14
+x = 3e-14
+x = 3e+14
+x = 3.e14
+x = .3e14
+x = 3.1e4
+
+print '1.1.3 String literals'
+
+x = ''; y = ""; verify(len(x) == 0 and x == y)
+x = '\''; y = "'"; verify(len(x) == 1 and x == y and ord(x) == 39)
+x = '"'; y = "\""; verify(len(x) == 1 and x == y and ord(x) == 34)
+x = "doesn't \"shrink\" does it"
+y = 'doesn\'t "shrink" does it'
+verify(len(x) == 24 and x == y)
+x = "does \"shrink\" doesn't it"
+y = 'does "shrink" doesn\'t it'
+verify(len(x) == 24 and x == y)
+x = """
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+"""
+y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
+verify(x == y)
+y = '''
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+'''; verify(x == y)
+y = "\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the 'lazy' dog.\n\
+"; verify(x == y)
+y = '\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the \'lazy\' dog.\n\
+'; verify(x == y)
+
+
+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: '(' [varargslist] ')'
+### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
+### | ('**'|'*' '*') NAME)
+### | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+### fpdef: NAME | '(' fplist ')'
+### fplist: fpdef (',' fpdef)* [',']
+### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
+### argument: [test '='] test # Really [keyword '='] test
+def f1(): pass
+f1()
+f1(*())
+f1(*(), **{})
+def f2(one_argument): pass
+def f3(two, arguments): pass
+def f4(two, (compound, (argument, list))): pass
+def f5((compound, first), two): pass
+verify(f2.func_code.co_varnames == ('one_argument',))
+verify(f3.func_code.co_varnames == ('two', 'arguments'))
+if sys.platform.startswith('java'):
+ verify(f4.func_code.co_varnames ==
+ ('two', '(compound, (argument, list))', 'compound', 'argument',
+ 'list',))
+ verify(f5.func_code.co_varnames ==
+ ('(compound, first)', 'two', 'compound', 'first'))
+else:
+ verify(f4.func_code.co_varnames == ('two', '.2', 'compound',
+ 'argument', 'list'))
+ verify(f5.func_code.co_varnames == ('.0', 'two', 'compound', 'first'))
+def a1(one_arg,): pass
+def a2(two, args,): pass
+def v0(*rest): pass
+def v1(a, *rest): pass
+def v2(a, b, *rest): pass
+def v3(a, (b, c), *rest): return a, b, c, rest
+if sys.platform.startswith('java'):
+ verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c'))
+else:
+ verify(v3.func_code.co_varnames == ('a', '.2', 'rest', 'b', 'c'))
+verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,)))
+def d01(a=1): pass
+d01()
+d01(1)
+d01(*(1,))
+d01(**{'a':2})
+def d11(a, b=1): pass
+d11(1)
+d11(1, 2)
+d11(1, **{'b':2})
+def d21(a, b, c=1): pass
+d21(1, 2)
+d21(1, 2, 3)
+d21(*(1, 2, 3))
+d21(1, *(2, 3))
+d21(1, 2, *(3,))
+d21(1, 2, **{'c':3})
+def d02(a=1, b=2): pass
+d02()
+d02(1)
+d02(1, 2)
+d02(*(1, 2))
+d02(1, *(2,))
+d02(1, **{'b':2})
+d02(**{'a': 1, 'b': 2})
+def d12(a, b=1, c=2): pass
+d12(1)
+d12(1, 2)
+d12(1, 2, 3)
+def d22(a, b, c=1, d=2): pass
+d22(1, 2)
+d22(1, 2, 3)
+d22(1, 2, 3, 4)
+def d01v(a=1, *rest): pass
+d01v()
+d01v(1)
+d01v(1, 2)
+d01v(*(1, 2, 3, 4))
+d01v(*(1,))
+d01v(**{'a':2})
+def d11v(a, b=1, *rest): pass
+d11v(1)
+d11v(1, 2)
+d11v(1, 2, 3)
+def d21v(a, b, c=1, *rest): pass
+d21v(1, 2)
+d21v(1, 2, 3)
+d21v(1, 2, 3, 4)
+d21v(*(1, 2, 3, 4))
+d21v(1, 2, **{'c': 3})
+def d02v(a=1, b=2, *rest): pass
+d02v()
+d02v(1)
+d02v(1, 2)
+d02v(1, 2, 3)
+d02v(1, *(2, 3, 4))
+d02v(**{'a': 1, 'b': 2})
+def d12v(a, b=1, c=2, *rest): pass
+d12v(1)
+d12v(1, 2)
+d12v(1, 2, 3)
+d12v(1, 2, 3, 4)
+d12v(*(1, 2, 3, 4))
+d12v(1, 2, *(3, 4, 5))
+d12v(1, *(2,), **{'c': 3})
+def d22v(a, b, c=1, d=2, *rest): pass
+d22v(1, 2)
+d22v(1, 2, 3)
+d22v(1, 2, 3, 4)
+d22v(1, 2, 3, 4, 5)
+d22v(*(1, 2, 3, 4))
+d22v(1, 2, *(3, 4, 5))
+d22v(1, *(2, 3), **{'d': 4})
+
+print 'selectors'
+### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+### subscript: expr | [expr] ':' [expr]
+f1()
+f2(1)
+f2(1,)
+f3(1, 2)
+f3(1, 2,)
+f4(1, (2, (3, 4)))
+v0()
+v0(1)
+v0(1,)
+v0(1,2)
+v0(1,2,3,4,5,6,7,8,9,0)
+v1(1)
+v1(1,)
+v1(1,2)
+v1(1,2,3)
+v1(1,2,3,4,5,6,7,8,9,0)
+v2(1,2)
+v2(1,2,3)
+v2(1,2,3,4)
+v2(1,2,3,4,5,6,7,8,9,0)
+v3(1,(2,3))
+v3(1,(2,3),4)
+v3(1,(2,3),4,5,6,7,8,9,0)
+
+print
+##! Section lambdef
+
+### lambdef: 'lambda' [varargslist] ':' test
+print 'lambdef'
+l1 = lambda : 0
+verify(l1() == 0)
+l2 = lambda : a[d] # XXX just testing the expression
+l3 = lambda : [2 < x for x in [-1, 3, 0L]]
+verify(l3() == [0, 1, 0])
+l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
+verify(l4() == 1)
+l5 = lambda x, y, z=2: x + y + z
+verify(l5(1, 2) == 5)
+verify(l5(1, 2, 3) == 6)
+check_syntax("lambda x: x = 2")
+
+print
+##! Section simple_stmt
+
+### stmt: simple_stmt | compound_stmt
+# Tested below
+
+### simple_stmt: small_stmt (';' small_stmt)* [';']
+print 'simple_stmt'
+x = 1; pass; del x
+
+### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
+# Tested below
+
+print 'expr_stmt' # (exprlist '=')* exprlist
+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
+
+check_syntax("x + 1 = 1")
+check_syntax("a + 1 = b + 2")
+
+print 'del_stmt' # 'del' exprlist
+del abc
+del x, y, (z, xyz)
+
+print 'print_stmt' # 'print' (test ',')* [test]
+print 1, 2, 3
+print 1, 2, 3,
+print
+print 0 or 1, 0 or 1,
+print 0 or 1
+
+
+print
+##! Section extended print_stmt
+
+print 'extended print_stmt' # 'print' '>>' test ','
+import sys
+print >> sys.stdout, 1, 2, 3
+print >> sys.stdout, 1, 2, 3,
+print >> sys.stdout
+print >> sys.stdout, 0 or 1, 0 or 1,
+print >> sys.stdout, 0 or 1
+
+# test printing to an instance
+class Gulp:
+ def write(self, msg): pass
+
+gulp = Gulp()
+print >> gulp, 1, 2, 3
+print >> gulp, 1, 2, 3,
+print >> gulp
+print >> gulp, 0 or 1, 0 or 1,
+print >> gulp, 0 or 1
+
+# test print >> None
+def driver():
+ oldstdout = sys.stdout
+ sys.stdout = Gulp()
+ try:
+ tellme(Gulp())
+ tellme()
+ finally:
+ sys.stdout = oldstdout
+
+# we should see this once
+def tellme(file=sys.stdout):
+ print >> file, 'hello world'
+
+driver()
+
+# we should not see this at all
+def tellme(file=None):
+ print >> file, 'goodbye universe'
+
+driver()
+
+# syntax errors
+check_syntax('print ,')
+check_syntax('print >> x,')
+
+print
+##! Section pass_stmt
+print 'pass_stmt' # 'pass'
+pass
+
+print 'flow_stmt' # break_stmt | continue_stmt | return_stmt | raise_stmt
+# Tested below
+
+print 'break_stmt' # 'break'
+while 1: break
+
+print
+##! Section continue_stmt
+print 'continue_stmt' # 'continue'
+i = 1
+while i: i = 0; continue
+
+msg = ""
+while not msg:
+ msg = "continue + try/except ok"
+ try:
+ continue
+ msg = "continue failed to continue inside try"
+ except:
+ msg = "continue inside try called except block"
+print msg
+
+msg = ""
+while not msg:
+ msg = "finally block not called"
+ try:
+ continue
+ finally:
+ msg = "continue + try/finally ok"
+print msg
+
+
+# This test warrants an explanation. It is a test specifically for SF bugs
+# #463359 and #462937. The bug is that a 'break' statement executed or
+# exception raised inside a try/except inside a loop, *after* a continue
+# statement has been executed in that loop, will cause the wrong number of
+# arguments to be popped off the stack and the instruction pointer reset to
+# a very small number (usually 0.) Because of this, the following test
+# *must* written as a function, and the tracking vars *must* be function
+# arguments with default values. Otherwise, the test will loop and loop.
+
+print "testing continue and break in try/except in loop"
+def test_break_continue_loop(extra_burning_oil = 1, count=0):
+ big_hippo = 2
+ while big_hippo:
+ count += 1
+ try:
+ if extra_burning_oil and big_hippo == 1:
+ extra_burning_oil -= 1
+ break
+ big_hippo -= 1
+ continue
+ except:
+ raise
+ if count > 2 or big_hippo <> 1:
+ print "continue then break in try/except in loop broken!"
+test_break_continue_loop()
+
+print
+##! Section return_stmt
+
+print 'return_stmt' # 'return' [testlist]
+def g1(): return
+def g2(): return 1
+g1()
+x = g2()
+
+print 'raise_stmt' # 'raise' test [',' test]
+try: raise RuntimeError, 'just testing'
+except RuntimeError: pass
+try: raise KeyboardInterrupt
+except KeyboardInterrupt: pass
+
+print 'import_stmt' # 'import' NAME (',' NAME)* | 'from' NAME 'import' ('*' | NAME (',' NAME)*)
+import sys
+import time, sys
+from time import time
+from sys import *
+from sys import path, argv
+
+
+print
+##! Section global_stmt
+
+print 'global_stmt' # 'global' NAME (',' NAME)*
+def f():
+ global a
+ global a, b
+ global one, two, three, four, five, six, seven, eight, nine, ten
+
+print
+##! Section exec_stmt
+
+print 'exec_stmt' # 'exec' expr ['in' expr [',' expr]]
+def f():
+ z = None
+ del z
+ exec 'z=1+1\n'
+ if z != 2: print 'Test Failed -', 'exec \'z=1+1\'\\n'
+ del z
+ exec 'z=1+1'
+ if z != 2: print 'Test Failed -', 'exec \'z=1+1\''
+ z = None
+ del z
+ import types
+ if hasattr(types, "UnicodeType"):
+ exec r"""if 1:
+ exec u'z=1+1\n'
+ if z != 2: print 'Test Failed -', 'exec u\'z=1+1\'\\n'
+ del z
+ exec u'z=1+1'
+ if z != 2: print 'Test Failed -', 'exec u\'z=1+1\''
+"""
+f()
+g = {}
+exec 'z = 1' in g
+if g.has_key('__builtins__'): del g['__builtins__']
+if g != {'z': 1}: print 'Test Failed -', 'exec \'z = 1\' in g'
+g = {}
+l = {}
+
+import warnings
+warnings.filterwarnings("ignore", "global statement", module="<string>")
+exec 'global a; a = 1; b = 2' in g, l
+if g.has_key('__builtins__'): del g['__builtins__']
+if l.has_key('__builtins__'): del l['__builtins__']
+if (g, l) != ({'a':1}, {'b':2}): print 'Test Failed -', 'exec ... in g (%s), l (%s)' %(g,l)
+
+print
+##! Section assert_stmt
+
+print "assert_stmt" # assert_stmt: 'assert' test [',' test]
+assert 1
+assert 1, 1
+assert lambda x:x
+assert 1, lambda x:x+1
+
+### 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]
+for i in 1, 2, 3: pass
+for i, j, k in (): pass
+else: pass
+class Squares:
+ def __init__(self, max):
+ self.max = max
+ self.sofar = []
+ def __len__(self): return len(self.sofar)
+ def __getitem__(self, i):
+ if not 0 <= i < self.max: raise IndexError
+ n = len(self.sofar)
+ while n <= i:
+ self.sofar.append(n*n)
+ n = n+1
+ return self.sofar[i]
+n = 0
+for x in Squares(10): n = n+x
+if n != 285: print 'Test Failed -', 'for over growing sequence'
+
+print 'try_stmt'
+### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+### | 'try' ':' suite 'finally' ':' suite
+### except_clause: 'except' [expr [',' expr]]
+try:
+ 1/0
+except ZeroDivisionError:
+ pass
+else:
+ pass
+try: 1/0
+except EOFError: pass
+except TypeError, msg: pass
+except RuntimeError, msg: pass
+except: pass
+else: pass
+try: 1/0
+except (EOFError, TypeError, ZeroDivisionError): pass
+try: 1/0
+except (EOFError, TypeError, ZeroDivisionError), msg: pass
+try: 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
+if not 1: pass
+if 1 and 1: pass
+if 1 or 1: pass
+if not not not 1: pass
+if not 1 and 1 and 1: pass
+if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
+
+print 'comparison'
+### comparison: expr (comp_op expr)*
+### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+if 1: pass
+x = (1 == 1)
+if 1 == 1: pass
+if 1 != 1: pass
+if 1 <> 1: pass
+if 1 < 1: pass
+if 1 > 1: pass
+if 1 <= 1: pass
+if 1 >= 1: pass
+if 1 is 1: pass
+if 1 is not 1: pass
+if 1 in (): pass
+if 1 not in (): pass
+if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass
+
+print 'binary mask ops'
+x = 1 & 1
+x = 1 ^ 1
+x = 1 | 1
+
+print 'shift ops'
+x = 1 << 1
+x = 1 >> 1
+x = 1 << 1 >> 1
+
+print 'additive ops'
+x = 1
+x = 1 + 1
+x = 1 - 1 - 1
+x = 1 - 1 + 1 - 1 + 1
+
+print 'multiplicative ops'
+x = 1 * 1
+x = 1 / 1
+x = 1 % 1
+x = 1 / 1 * 1 % 1
+
+print 'unary ops'
+x = +1
+x = -1
+x = ~1
+x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
+x = -1*1/1 + 1*1 - ---1*1
+
+print
+import sys, time
+c = sys.path[0]
+x = time.time()
+x = sys.modules['time'].time()
+a = '01234'
+c = a[0]
+c = a[-1]
+s = a[0:5]
+s = a[:5]
+s = a[0:]
+s = a[:]
+s = a[-5:]
+s = a[:-1]
+s = a[-4:-3]
+
+print 'atoms'
+### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING
+### dictmaker: test ':' test (',' test ':' test)* [',']
+
+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 = {'one': 1}
+x = {'one': 1,}
+x = {'one' or 'two': 1 or 2}
+x = {'one': 1, 'two': 2}
+x = {'one': 1, 'two': 2,}
+x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
+
+x = `x`
+x = `1 or 2 or 3`
+x = x
+x = 'x'
+x = 123
+
+### exprlist: expr (',' expr)* [',']
+### testlist: test (',' test)* [',']
+# These have been exercised enough above
+
+print 'classdef' # 'class' NAME ['(' testlist ')'] ':' suite
+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
+
+print
+##! Section list_comps
+
+# list comprehension tests
+nums = [1, 2, 3, 4, 5]
+strs = ["Apple", "Banana", "Coconut"]
+spcs = [" Apple", " Banana ", "Coco nut "]
+
+print [s.strip() for s in spcs]
+print [3 * x for x in nums]
+print [x for x in nums if x > 2]
+print [(i, s) for i in nums for s in strs]
+print [(i, s) for i in nums for s in [f for f in strs if "n" in f]]
+print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)]
+
+def test_in_func(l):
+ return [None < x < 3 for x in l if x > 2]
+
+print test_in_func(nums)
+
+def test_nested_front():
+ print [[y for y in [x, x + 1]] for x in [1,3,5]]
+
+test_nested_front()
+
+check_syntax("[i, s for i in nums for s in strs]")
+check_syntax("[x if y]")
+
+suppliers = [
+ (1, "Boeing"),
+ (2, "Ford"),
+ (3, "Macdonalds")
+]
+
+parts = [
+ (10, "Airliner"),
+ (20, "Engine"),
+ (30, "Cheeseburger")
+]
+
+suppart = [
+ (1, 10), (1, 20), (2, 20), (3, 30)
+]
+
+print [
+ (sname, pname)
+ for (sno, sname) in suppliers
+ for (pno, pname) in parts
+ for (sp_sno, sp_pno) in suppart
+ if sno == sp_sno and pno == sp_pno
+]
Added: pypy/trunk/src/pypy/scripttest/grammar.txt
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/grammar.txt Sun Jun 27 22:53:28 2004
@@ -0,0 +1,86 @@
+##! Section 1.
+1. Parser
+1.1 Tokens
+1.1.1 Backslashes
+1.1.2 Numeric literals
+1.1.2.1 Plain integers
+1.1.2.2 Long integers
+1.1.2.3 Floating point
+1.1.3 String literals
+1.2 Grammar
+single_input
+file_input
+expr_input
+eval_input
+funcdef
+selectors
+
+##! Section lambdef
+lambdef
+
+##! Section simple_stmt
+simple_stmt
+expr_stmt
+del_stmt
+print_stmt
+1 2 3
+1 2 3
+1 1 1
+
+##! Section extended print_stmt
+extended print_stmt
+1 2 3
+1 2 3
+1 1 1
+hello world
+
+##! Section pass_stmt
+pass_stmt
+flow_stmt
+break_stmt
+
+##! Section continue_stmt
+continue_stmt
+continue + try/except ok
+continue + try/finally ok
+testing continue and break in try/except in loop
+
+##! Section return_stmt
+return_stmt
+raise_stmt
+import_stmt
+
+##! Section global_stmt
+global_stmt
+
+##! Section exec_stmt
+exec_stmt
+
+##! Section assert_stmt
+assert_stmt
+if_stmt
+while_stmt
+for_stmt
+try_stmt
+suite
+test
+comparison
+binary mask ops
+shift ops
+additive ops
+multiplicative ops
+unary ops
+
+atoms
+classdef
+
+##! Section list_comps
+['Apple', 'Banana', 'Coco nut']
+[3, 6, 9, 12, 15]
+[3, 4, 5]
+[(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]
+[(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')]
+[[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]
+[False, False, False]
+[[1, 2], [3, 4], [5, 6]]
+[('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]
\ No newline at end of file
Added: pypy/trunk/src/pypy/scripttest/test/__init__.py
==============================================================================
Added: pypy/trunk/src/pypy/scripttest/test/autopath.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/test/autopath.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1,80 @@
+"""
+self cloning, automatic path configuration
+
+copy this into any subdirectory of pypy from which scripts need
+to be run, typically all of the test subdirs.
+The idea is that any such script simply issues
+
+ import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path.
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py)
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory.
+
+This module always provides these attributes:
+
+ pypydir pypy root directory path
+ this_dir directory where this autopath.py resides
+
+"""
+
+
+def __dirinfo(part):
+ """ return (partdir, this_dir) and insert parent of partdir
+ into sys.path. If the parent directories dont have the part
+ an EnvironmentError is raised."""
+
+ import sys, os
+ try:
+ head = this_dir = os.path.abspath(os.path.dirname(__file__))
+ except NameError:
+ head = this_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
+
+ while head:
+ partdir = head
+ head, tail = os.path.split(head)
+ if tail == part:
+ try:
+ sys.path.remove(head)
+ except ValueError:
+ pass
+ sys.path.insert(0, head)
+ return partdir, this_dir
+
+ raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path)
+
+def __clone():
+ """ clone master version of autopath.py into all subdirs """
+ from os.path import join, walk
+ if not this_dir.endswith(join('pypy','tool')):
+ raise EnvironmentError("can only clone master version "
+ "'%s'" % join(pypydir, 'tool',_myname))
+
+
+ def sync_walker(arg, dirname, fnames):
+ if _myname in fnames:
+ fn = join(dirname, _myname)
+ f = open(fn, 'rwb+')
+ try:
+ if f.read() == arg:
+ print "checkok", fn
+ else:
+ print "syncing", fn
+ f = open(fn, 'w')
+ f.write(arg)
+ finally:
+ f.close()
+ s = open(join(pypydir, 'tool', _myname), 'rb').read()
+ walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+ __clone()
Added: pypy/trunk/src/pypy/scripttest/test/test_grammar.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/test/test_grammar.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1,46 @@
+import autopath
+import os, os.path
+from pypy.tool import testit, app_level_diff
+
+filename = os.path.join(os.path.dirname(__file__), os.pardir, 'grammar.py')
+
+# Test the functionallity of the CPython test_grammar.py regression test
+
+class TestGrammar(testit.IntTestCase):
+ def setUp(self):
+ self.space = testit.objspace()
+ def _section_test(self, section):
+ diff = app_level_diff.compare(self.space, filename, section)
+ if diff:
+ raise AssertionError('Tutorial test failed - ' \
+ "run test_grammar.details('%s')" % section)
+ def test_Section_1(self):
+ self._section_test('Section 1.')
+## def xxx_test_Section_lambdef(self):
+## self._section_test('Section lambdef')
+ def test_Section_simple_stmt(self):
+ self._section_test('Section simple_stmt')
+ def test_Section_extended_print_stmt(self):
+ self._section_test('Section extended print_stmt')
+ def test_Section_pass_stmt(self):
+ self._section_test('Section pass_stmt')
+ def test_Section_continue_stmt(self):
+ self._section_test('Section continue_stmt')
+ def test_Section_return_stmt(self):
+ self._section_test('Section return_stmt')
+ def test_Section_global_stmt(self):
+ self._section_test('Section global_stmt')
+## def xxx_test_Section_exec_stmt(self):
+## self._section_test('Section exec_stmt')
+ def test_Section_assert_stmt(self):
+ self._section_test('Section assert_stmt')
+## def xxx_test_Section_list_comps(self):
+## self._section_test('Section list_comps')
+
+
+def details(section):
+ diff = app_level_diff.compare(testit.objspace(), filename, section)
+ print diff
+
+if __name__ == '__main__':
+ testit.main()
Added: pypy/trunk/src/pypy/scripttest/test/test_tutorial.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/test/test_tutorial.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1,34 @@
+import autopath
+import os, os.path
+from pypy.tool import testit, app_level_diff
+
+filename = os.path.join(os.path.dirname(__file__), os.pardir, 'tutorial.py')
+
+# Test the functionallity of Guido's tutorial
+
+class TestTutorial(testit.IntTestCase):
+ def setUp(self):
+ self.space = testit.objspace()
+ def _section_test(self, section):
+ diff = app_level_diff.compare(self.space, filename, section)
+ if diff:
+ raise AssertionError('Tutorial test failed - ' \
+ "run test_tutorial.details('%s')" % section)
+ def test_Section_2_1_2(self):
+ self._section_test('Section 2.1.2')
+ def test_Section_3_1_1a(self):
+ self._section_test('Section 3.1.1a')
+## def xxx_test_Section_3_1_1b(self):
+## self._section_test('Section 3.1.1b')
+## def xxx_test_Section_3_1_1c(self):
+## self._section_test('Section 3.1.1c')
+ def test_Section_3_1_2(self):
+ self._section_test('Section 3.1.2')
+
+
+def details(section):
+ diff = app_level_diff.compare(testit.objspace(), filename, section)
+ print diff
+
+if __name__ == '__main__':
+ testit.main()
Added: pypy/trunk/src/pypy/scripttest/tutorial.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/tutorial.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1,137 @@
+"""Run code from Guido's Tutorial, to make sure it works under PyPy.
+
+Note that as a script, we have to explicitly print stuff to see it.
+"""
+
+##! Section 2.1.2
+
+the_world_is_flat = 1
+
+if the_world_is_flat:
+ print "Be careful not to fall off!"
+
+print
+##! Section 3.1.1a
+
+print repr(2+2)
+print repr((50-5*6)/4)
+print repr(7/3)
+print repr(7/-3)
+
+width = 20
+height = 5*9
+print repr(width * height)
+
+x = y = z = 0 # Zero x, y and z
+print repr(x)
+print repr(y)
+print repr(z)
+
+
+print repr(3 * 3.75 / 1.5)
+print repr(7.0 / 2)
+
+print
+##! Section 3.1.1b
+
+print repr(1j * 1J)
+
+print repr(1j * complex(0,1))
+print repr(3+1j*3)
+print repr((3+1j)*3)
+print repr((1+2j)/(1+1j))
+
+a=1.5+0.5j
+print repr(a.real)
+print repr(a.imag)
+
+a=3.0+4.0j
+try:
+ print repr(float(a))
+except TypeError:
+ print "Got TypeError for repr(float(a))"
+print repr(a.real)
+print repr(a.imag)
+print repr(abs(a))
+
+print
+##! Section 3.1.1c
+
+#Mock up '_' variable use
+tax = 12.5 / 100
+price = 100.50
+print repr(price * tax)
+_ = price * tax
+print repr(price + _)
+_ = price + _
+print repr(round(_, 2))
+
+print
+##! Section 3.1.2
+
+print repr('spam eggs')
+print repr('doesn\'t')
+print repr("doesn't")
+print repr('"Yes," he said.')
+print repr("\"Yes,\" he said.")
+print repr('"Isn\'t," she said.')
+
+hello = "This is a rather long string containing\n\
+several lines of text just as you would do in C.\n\
+ Note that whitespace at the beginning of the line is\
+ significant."
+print hello
+hello = r"This is a rather long string containing\n\
+several lines of text much as you would do in C."
+print hello
+print """
+Usage: thingy [OPTIONS]
+ -h Display this usage message
+ -H hostname Hostname to connect to
+"""
+
+word = 'Help' + 'A'
+print repr(word)
+print repr('<' + word*5 + '>')
+print repr('str' 'ing')
+print repr('str'.strip() + 'ing')
+print repr(word[4])
+print repr(word[0:2])
+print repr(word[2:4])
+print repr(word[:2])
+print repr(word[2:])
+
+try:
+ word[0] = 'x'
+except TypeError:
+ print "Got a TypeError with word[0] = 'x'"
+try:
+ word[:1] = 'Splat'
+except TypeError:
+ print "Got a TypeError with word[:1] = 'Splat'"
+print repr('x' + word[1:])
+print repr('Splat' + word[4])
+print repr(word[:2] + word[2:])
+print repr(word[:3] + word[3:])
+
+print repr(word[1:100])
+print repr(word[10:])
+print repr(word[2:1])
+print repr(word[-1])
+print repr(word[-2])
+print repr(word[-2:])
+print repr(word[:-2])
+print repr(word[-0])
+
+print repr(word[-100:])
+try:
+ print repr(word[-10])
+except IndexError:
+ print "Got IndexError with word[-10]"
+
+s = 'supercalifragilisticexpialidocious'
+print repr(len(s))
+
+print
+##! Section 3.1.3
+
Added: pypy/trunk/src/pypy/scripttest/tutorial.txt
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/scripttest/tutorial.txt Sun Jun 27 22:53:28 2004
@@ -0,0 +1,78 @@
+##! Section 2.1.2
+Be careful not to fall off!
+
+##! Section 3.1.1a
+4
+5
+2
+-3
+900
+0
+0
+0
+7.5
+3.5
+
+##! Section 3.1.1b
+(-1+0j)
+(-1+0j)
+(3+3j)
+(9+3j)
+(1.5+0.5j)
+1.5
+0.5
+Got TypeError for repr(float(a))
+3.0
+4.0
+5.0
+
+##! Section 3.1.1c
+12.5625
+113.0625
+113.06
+
+##! Section 3.1.2
+'spam eggs'
+"doesn't"
+"doesn't"
+'"Yes," he said.'
+'"Yes," he said.'
+'"Isn\'t," she said.'
+This is a rather long string containing
+several lines of text just as you would do in C.
+ Note that whitespace at the beginning of the line is significant.
+This is a rather long string containing\n\
+several lines of text much as you would do in C.
+
+Usage: thingy [OPTIONS]
+ -h Display this usage message
+ -H hostname Hostname to connect to
+
+'HelpA'
+'<HelpAHelpAHelpAHelpAHelpA>'
+'string'
+'string'
+'A'
+'He'
+'lp'
+'He'
+'lpA'
+Got a TypeError with word[0] = 'x'
+Got a TypeError with word[:1] = 'Splat'
+'xelpA'
+'SplatA'
+'HelpA'
+'HelpA'
+'elpA'
+''
+''
+'A'
+'p'
+'pA'
+'Hel'
+'H'
+'HelpA'
+Got IndexError with word[-10]
+34
+
+##! Section 3.1.3
Added: pypy/trunk/src/pypy/tool/app_level_diff.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/tool/app_level_diff.py Sun Jun 27 22:53:28 2004
@@ -0,0 +1,123 @@
+import autopath
+import difflib
+
+leadincode = """
+import sys
+
+class PseudoOut:
+ def __init__(self):
+ self.out = []
+ def flush(self):
+ pass
+ def write(self, item):
+ self.out.append(str(item))
+ def writelines(self, items):
+ for item in items:
+ self.out.append(str(item))
+ def getoutput(self):
+ '''Not part of the output stream interface.'''
+ return ''.join(self.out)
+
+out = PseudoOut()
+
+oldout, sys.stdout = sys.stdout, out
+olderr, sys.stderr = sys.stderr, out
+"""
+
+cleanupcode = """
+sys.stdout = oldout
+sys.stderr = olderr
+
+retval = out.getoutput()
+"""
+
+def runcode(space, source, filename, w_glob):
+ w = space.wrap
+ w_compile = space.getitem(space.builtin.w_dict, w('compile'))
+ w_code = space.call_function(w_compile, w(source), w(filename), w('exec'))
+ pycode = space.unwrap(w_code)
+ pycode.exec_code(space, w_glob, w_glob)
+
+def getoutput(space, source, filename):
+ w_bookendglobals = space.newdict([])
+ runcode(space, leadincode, '<str>', w_bookendglobals)
+ w_scratchglobals = space.newdict([])
+ runcode(space, source, filename, w_scratchglobals)
+ runcode(space, cleanupcode, '<str>', w_bookendglobals)
+ #Get 'retval' from the bookendglobals - contains output
+ return space.unwrap(space.getitem(w_bookendglobals, space.wrap('retval')))
+
+def getsection(linelist, section_name = None, savelineno = False):
+ #Strips out all '##!' line delimiters.
+ #If section_name is None, return just the leadin code.
+ #If section_name is not present in the linelist, raise an error.
+ #If savelineno is true, add fake lines to keep the absolute line
+ # numbers the same as in the original file.
+
+ #Leadin code is run by all sections
+ save = True
+ seen = False
+ accumulator = []
+ for line in linelist:
+ if line[:3] == '##!':
+ if line[3:].strip() == section_name or section_name is None:
+ save = True
+ seen = True
+ else:
+ save = False
+ if savelineno:
+ accumulator.append('\n')
+ elif save:
+ accumulator.append(line)
+ elif savelineno:
+ accumulator.append('\n')
+ if not seen:
+ raise KeyError('Section "'+section_name+'" not found in file.')
+ return accumulator
+
+def compare(space, filename, section = None):
+ """Compare an application level script to expected output.
+
+ The output of 'filename' when run at application level as a script
+ is compared to the appropriate '.txt' file (e.g. test.py -> test.txt).
+ If no difference is seen, the function returns an empty string (False).
+ If a difference is seen, the diffenrence in the form of a unified diff is
+ returned as a multiline string (True).
+
+ The optional section argument allows selective execution of portions of
+ the code. It looks for blocks delimited by '##! <section_name>' lines,
+ where <section_name> is the string passed to the section argument. None
+ executes the entire script. The output file should also be delimited by
+ the same section markers.
+ """
+ f = file(filename, 'r')
+ try:
+ sourcelines = f.readlines()
+ finally:
+ f.close()
+ source = ''.join(getsection(sourcelines, section, savelineno = True))
+ output = getoutput(space, source, filename).splitlines(True)
+
+ outfilename = '.'.join(filename.split('.')[:-1]+['txt'])
+ try:
+ f = file(outfilename, 'r')
+ try:
+ outfilelines = f.readlines()
+ finally:
+ f.close()
+ except KeyboardInterrupt:
+ pass
+ except:
+ #If there are problems loading outfile, assume null output
+ outfilelines = ['']
+
+ outfile = getsection(outfilelines, section)
+ if not outfile and not output: #Catch degenerate case where both are empty
+ return ''
+ diff = list(difflib.unified_diff(outfile, output,
+ fromfile=outfilename, tofile=filename))
+
+ if diff:
+ return ''.join(diff)
+ else:
+ return ''
More information about the Pypy-commit
mailing list