From arigo at codespeak.net Thu Jul 1 18:31:05 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 1 Jul 2004 18:31:05 +0200 (MEST) Subject: [pypy-svn] r5415 - in pypy/trunk/src/pypy: appspace module Message-ID: <20040701163105.9237D5AC7F@thoth.codespeak.net> Author: arigo Date: Thu Jul 1 18:31:05 2004 New Revision: 5415 Added: pypy/trunk/src/pypy/appspace/cStringIO.py (contents, props changed) Modified: pypy/trunk/src/pypy/module/sysinterp.py Log: Implements cStringIO by using StringIO. Added: pypy/trunk/src/pypy/appspace/cStringIO.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/cStringIO.py Thu Jul 1 18:31:05 2004 @@ -0,0 +1,5 @@ +# +# One-liner implementation of cStringIO +# + +from StringIO import * Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Thu Jul 1 18:31:05 2004 @@ -38,7 +38,7 @@ # The following built-in modules are not written in PyPy, so we # steal them from Python. for fn in ['posix', 'nt', 'os2', 'mac', 'ce', 'riscos', - 'cStringIO', 'itertools', 'math', + 'itertools', 'math', '_random', '_sre', 'time', '_socket', 'errno', 'marshal', 'struct', 'binascii', 'parser']: if fn not in builtin_modules: From lac at codespeak.net Thu Jul 1 19:23:11 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Thu, 1 Jul 2004 19:23:11 +0200 (MEST) Subject: [pypy-svn] r5416 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040701172311.05C4F5AC7F@thoth.codespeak.net> Author: lac Date: Thu Jul 1 19:23:08 2004 New Revision: 5416 Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py Log: So much smaller now. :-) And, now handles every unittest in the suite, producing a correct result. Well, I need to write some more unittests to check this, but, at any rate it passes all of its current unittests, and it handles every function call. It doesn't try to rewrite lines, so if it was on 3 lines in the original, it will be in 3 lines now, even if there is enough room now to shrink it to 2 lines ... Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/utestconvert.py (original) +++ pypy/branch/src-new-utest/pypy/tool/utestconvert.py Thu Jul 1 19:23:08 2004 @@ -6,92 +6,49 @@ d={} # d is the dictionary of unittest changes, keyed to the old name -# used by unittest. d['new'] is the new replacement function, and -# d['change'] is one of the following functions -# namechange_only e.g. assertRaises becomes raises -# fail_special e.g. fail() becomes raise AssertionError -# strip_parens e.g. assert_(expr) becomes assert expr -# comma_to_op e.g. assertEquals(l, r) becomes assert l == r -# rounding e.g. assertAlmostEqual(l, r) becomes -# assert round(l - r, 7) == 0 -# Finally, 'op' is the operator you will substitute, if applicable. -# Got to define the dispatch functions first .... - -def namechange_only(old, new, block, op): - '''rename a function. dictionary dispatched.''' - return re.sub('self.'+old, new, block) - -def fail_special(old, new, block, op): - '''change fail function to raise AssertionError. dictionary dispatched. ''' - indent, expr, trailer = common_setup(old, block) - - if expr == '': # fail() --> raise AssertionError - return indent + new + trailer - else: # fail('Problem') --> raise AssertionError, 'Problem' - return indent + new + ', ' + expr + trailer - -def comma_to_op(old, new, block, op): - '''change comma to appropriate op. dictionary dispatched. ''' -p indent, expr, trailer = common_setup(old, block) - new = new + ' ' - op = ' ' + op - left, right = get_expr(expr, ',') +# used by unittest. d['new'] is the new replacement function. +# arg_nums is the possible number of arguments to the unittest +# function. The last argument to the arg_nums list is the position the +# optional 'message' to print when the unittest fails should occur. +# assertRaises and failUnlessRaises, unlike all the other functions +# cannot have an special message to print, and can be passed any +# number of arguments, so their arg_nums is [None] (in the absense of +# [Any]. - try: - parser.expr(left.lstrip()) # that paren came off easily - except SyntaxError: - left = re.sub(linesep, '\\'+linesep, left) - - right = process_args(right) - - if right.startswith(linesep): - op = op + '\\' - - return indent + new + left + op + right + trailer - -def strip_parens(old, new, block, op): - '''remove one set of parens. dictionary dispatched. ''' - indent, args, trailer = common_setup(old, block) - new = new + ' ' +# 'op' is the operator you will substitute, if applicable. - args = process_args(args) - return indent + new + args + trailer -def rounding(): - pass - -# Now the dictionary of unittests. There sure are enough of them! - -d['assertRaises'] = {'new': 'raises', 'change': namechange_only, 'op': None} +d['assertRaises'] = {'new': 'raises', 'op': '', 'arg_nums':[None]} d['failUnlessRaises'] = d['assertRaises'] -d['fail'] = {'new': 'raise AssertionError', 'change': fail_special, 'op': None} +d['fail'] = {'new': 'raise AssertionError', 'op': '', 'arg_nums':[0,1]} -d['assertEqual'] = {'new': 'assert', 'change': comma_to_op, 'op': '=='} +d['assert_'] = {'new': 'assert', 'op': '', 'arg_nums':[1,2]} +d['failIf'] = {'new': 'assert not','op': '', 'arg_nums':[1,2]} +d['failUnless'] = d['assert_'] + +d['assertEqual'] = {'new': 'assert', 'op': ' ==', 'arg_nums':[2,3]} d['assertEquals'] = d['assertEqual'] -d['assertNotEqual'] = {'new': 'assert', 'change':comma_to_op, 'op': '!='} +d['assertNotEqual'] = {'new': 'assert', 'op': ' !=', 'arg_nums':[2,3]} d['assertNotEquals'] = d['assertNotEqual'] -d['failUnlessEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '!='} +d['failUnlessEqual'] = {'new': 'assert not', 'op': ' !=', 'arg_nums':[2,3]} -d['failIfEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '=='} +d['failIfEqual'] = {'new': 'assert not', 'op': ' ==', 'arg_nums':[2,3]} -d['assert_'] = {'new': 'assert','change': strip_parens, 'op': None} -d['failUnless'] = d['assert_'] - -d['failIf'] = {'new': 'assert not', 'change': strip_parens, 'op': None} - -d['assertAlmostEqual'] = {'new': 'assert round', 'change': rounding, 'op':'=='} +d['assertAlmostEqual'] = {'new': 'assert round', 'op':' ==','arg_nums':[2,3,4]} d['assertAlmostEquals'] = d['assertAlmostEqual'] -d['assertNotAlmostEqual'] = {'new':'assert round','change':rounding, 'op':'!='} +d['assertNotAlmostEqual'] = {'new':'assert round','op': ' !=', + 'arg_nums':[2,3,4]} d['assertNotAlmostEquals'] = d['assertNotAlmostEqual'] -d['failIfAlmostEqual'] = {'new': 'assert not round', - 'change': rounding, 'op': '=='} -d['failUnlessAlmostEquals'] = {'new': 'assert not round', - 'change': rounding, 'op': '!='} +d['failIfAlmostEqual'] = {'new': 'assert not round', 'op': ' ==', + 'arg_nums':[2,3,4]} + +d['failUnlessAlmostEquals'] = {'new': 'assert not round', 'op': ' !=', + 'arg_nums':[2,3,4]} leading_spaces = re.compile(r'^(\s*)') # this never fails @@ -120,51 +77,104 @@ blocklist.append(blockstring) return blocklist -def dispatch(s): - '''do a dictionary dispatch based on the change key in the dict d ''' - f = old_names.match(s) - if f: - key = f.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' - return d[key]['change'](key, d[key]['new'], s, d[key] ['op']) +def rewrite_utest(block): + utest = old_names.match(block) + if utest: + old = utest.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' + new = d[old]['new'] + op = d[old]['op'] + possible_args = d[old]['arg_nums'] + message_position = possible_args[-1] + + if not message_position: # just rename assertRaises + return re.sub('self.'+old, new, block) + + indent, args, message, trailer = decompose_unittest( + old, block, message_position) + + key = len(args) + if message: + key += 1 + + if key is 0: # fail() + return indent + new + trailer + + elif key is 1 and key is message_position: # fail('unhappy message') + return new + ', ' + message + trailer + + elif message_position is 4: #assertAlmostEqual and freinds + try: + pos = args[2].lstrip() + except IndexError: + pos = 7 + string = '(' + args[0] + ' -' + args[1] + ', ' + pos + ')' + string += op + ' 0' + if message: + string = string + ',' + message + return indent + new + string + trailer + + else: + string = op.join(args) + if message: + string = string + ',' + message + + return indent + new + ' ' + string + trailer else: # just copy uninteresting lines - return s + return block + +def decompose_unittest(old, block, message_position): + '''decompose the block into its component parts''' -def common_setup(old, block): - '''split the block into component parts''' + ''' returns indent, arglist, message, trailer + indent -- the indentation + arglist -- the arguments to the unittest function + message -- the optional message to print when it fails, and + trailer -- any extra junk after the closing paren, such as #commment + ''' + + message = None indent = re.search(r'^(\s*)', block).group() pat = re.search('self.' + old + r'\(', block) - expr, trailer = get_expr(block[pat.end():], ')') - return indent, expr, trailer - -def find_first_expr(args): - '''find the first expression, return it, and the rest if it exists''' - sep = ',' try: - left, right = get_expr(args, sep) - left = re.sub(linesep, '\\'+linesep, left) - - # only repair the lhs. The rhs may be a multiline string that - # can take care of itself. - - if right.startswith(linesep):# that needs a slash too ... - sep = sep + '\\' - - return left + sep, right - except SyntaxError: # just a regular old multiline expression - return re.sub(linesep, '\\'+linesep, args), None + args, trailer = get_expr(block[pat.end():], ')') + except SyntaxError: # this wasn't an expression. ick. + return indent, [block], message, None + + arglist = break_args(args, []) + if arglist == ['']: # there weren't any + return indent, [], message, trailer + else: + newl = [] + if len(arglist) == message_position: + message = arglist[-1] + arglist = arglist[:-1] + if message.lstrip('\t ').startswith(linesep): + message = '(' + message + ')' + + if arglist: + for arg in arglist: + try: + parser.expr(arg.lstrip('\t ')) + # remove tab and space, but keep newline. + except SyntaxError: + arg = '(' + arg + ')' + + newl.append(arg) + arglist = newl + + return indent, arglist, message, trailer -def process_args(args): +def break_args(args, arglist): + '''recursively break a string into a list of arguments''' try: - parser.expr(args.lstrip()) # the parens come off easily - return args - except SyntaxError: - # paste continuation backslashes on our multiline constructs. - left, right = find_first_expr(args) - if right: - return left + right + first, rest = get_expr(args, ',') + if not rest: + return arglist + [first] else: - return left + return [first] + break_args(rest, arglist) + except SyntaxError: + return arglist + [args] def get_expr(s, char): '''split a string into an expression, and the rest of the string''' @@ -188,16 +198,16 @@ class Testit(unittest.TestCase): def test(self): - self.assertEquals(dispatch("badger badger badger"), + self.assertEquals(rewrite_utest("badger badger badger"), "badger badger badger") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( "self.assertRaises(excClass, callableObj, *args, **kwargs)" ), "raises(excClass, callableObj, *args, **kwargs)" ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( """ self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) """ @@ -206,7 +216,7 @@ raises(TypeError, func, 42, **{'arg1': 23}) """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( """ self.assertRaises(TypeError, func, @@ -219,76 +229,79 @@ mushroom) """ ) - self.assertEquals(dispatch("self.fail()"), "raise AssertionError") - self.assertEquals(dispatch("self.fail('mushroom, mushroom')"), + self.assertEquals(rewrite_utest("self.fail()"), "raise AssertionError") + self.assertEquals(rewrite_utest("self.fail('mushroom, mushroom')"), "raise AssertionError, 'mushroom, mushroom'") - self.assertEquals(dispatch("self.assert_(x)"), "assert x") - self.assertEquals(dispatch("self.failUnless(func(x)) # XXX"), + self.assertEquals(rewrite_utest("self.assert_(x)"), "assert x") + self.assertEquals(rewrite_utest("self.failUnless(func(x)) # XXX"), "assert func(x) # XXX") - self.assertEquals(dispatch( - """ + self.assertEquals(rewrite_utest( + r""" self.assert_(1 + f(y) - + z) # multiline, add continuation backslash + + z) # multiline, keep parentheses """ ), r""" - assert 1 + f(y)\ - + z # multiline, add continuation backslash + assert (1 + f(y) + + z) # multiline, keep parentheses """ ) - self.assertEquals(dispatch("self.assert_(0, 'badger badger')"), + self.assertEquals(rewrite_utest("self.assert_(0, 'badger badger')"), "assert 0, 'badger badger'") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest("self.assert_(0, '''badger badger''')"), + "assert 0, '''badger badger'''") + + self.assertEquals(rewrite_utest( r""" self.assert_(0, 'Meet the badger.\n') """ ), r""" - assert 0,\ - 'Meet the badger.\n' + assert 0,( + 'Meet the badger.\n') """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.failIf(0 + 0 + len('badger\n') + 0, '''badger badger badger badger mushroom mushroom Snake! Ooh a snake! - ''') # multiline, must remove the parens + ''') # multiline, must move the parens """ ), r""" - assert not 0 + 0\ - + len('badger\n')\ - + 0, '''badger badger badger badger + assert not (0 + 0 + + len('badger\n') + + 0), '''badger badger badger badger mushroom mushroom Snake! Ooh a snake! - ''' # multiline, must remove the parens + ''' # multiline, must move the parens """ ) - self.assertEquals(dispatch("self.assertEquals(0, 0)"), + self.assertEquals(rewrite_utest("self.assertEquals(0, 0)"), "assert 0 == 0") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.assertEquals(0, 'Run away from the snake.\n') """ ), r""" - assert 0 ==\ - 'Run away from the snake.\n' + assert 0 ==( + 'Run away from the snake.\n') """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.assertEquals(badger + 0 + mushroom @@ -296,13 +309,13 @@ """ ), r""" - assert badger + 0\ - + mushroom\ - + snake == 0 + assert (badger + 0 + + mushroom + + snake) == 0 """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.assertNotEquals(badger + 0 + mushroom @@ -312,15 +325,15 @@ """ ), r""" - assert badger + 0\ - + mushroom\ - + snake !=\ - mushroom\ - - badger + assert (badger + 0 + + mushroom + + snake) !=( + mushroom + - badger) """ ) - self.assertEqual(dispatch( + self.assertEqual(rewrite_utest( r""" self.assertEquals(badger(), mushroom() @@ -329,50 +342,80 @@ """ ), r""" - assert badger() ==\ - mushroom()\ - + snake(mushroom)\ - - badger() + assert badger() ==( + mushroom() + + snake(mushroom) + - badger()) """ ) - self.assertEquals(dispatch("self.failIfEqual(0, 0)"), + self.assertEquals(rewrite_utest("self.failIfEqual(0, 0)"), "assert not 0 == 0") - self.assertEquals(dispatch("self.failUnlessEqual(0, 0)"), + self.assertEquals(rewrite_utest("self.failUnlessEqual(0, 0)"), "assert not 0 != 0") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.failUnlessEqual(mushroom() + mushroom() - + mushroom(), '''badger badger badger badger + + mushroom(), '''badger badger badger badger badger badger badger badger badger badger badger - ''') # multiline, must remove the parens + ''') # multiline, must move the parens """ ), r""" - assert not mushroom()\ - + mushroom()\ - + mushroom() != '''badger badger badger badger + assert not (mushroom() + + mushroom() + + mushroom()) != '''badger badger badger badger badger badger badger badger badger badger badger - ''' # multiline, must remove the parens + ''' # multiline, must move the parens """ ) - - self.assertEquals(dispatch( + + + self.assertEquals(rewrite_utest( + r""" + self.assertEquals('''snake snake snake + snake snake snake''', mushroom) + """ + ), + r""" + assert '''snake snake snake + snake snake snake''' == mushroom + """ + ) + + self.assertEquals(rewrite_utest( r""" self.assertEquals(badger(), snake(), 'BAD BADGER') """ ), r""" - assert badger() ==\ - snake(), 'BAD BADGER' + assert badger() ==( + snake()), 'BAD BADGER' """ ) - self.assertEquals(dispatch( + + self.assertEquals(rewrite_utest( + r""" + self.assertNotEquals(badger(), + snake()+ + snake(), 'POISONOUS MUSHROOM!\ + Ai! I ate a POISONOUS MUSHROOM!!') + """ + ), + r""" + assert badger() !=( + snake()+ + snake()), 'POISONOUS MUSHROOM!\ + Ai! I ate a POISONOUS MUSHROOM!!' + """ + ) + + self.assertEquals(rewrite_utest( r""" self.assertEquals(badger(), snake(), '''BAD BADGER @@ -382,31 +425,26 @@ """ ), r""" - assert badger() ==\ - snake(), '''BAD BADGER + assert badger() ==( + snake()), '''BAD BADGER BAD BADGER BAD BADGER''' """ - ) - self.assertEquals(dispatch( + ) + self.assertEquals(rewrite_utest( r""" - self.assertNotEquals(badger(), - snake()+ - snake(), 'POISONOUS MUSHROOM!\ - Ai! I ate a POISONOUS MUSHROOM!!') + self.assertAlmostEquals(first, second, 5, 'A Snake!') """ ), r""" - assert badger() !=\ - snake()+\ - snake(), 'POISONOUS MUSHROOM!\ - Ai! I ate a POISONOUS MUSHROOM!!' + assert round(first - second, 5) == 0, 'A Snake!' """ ) - + + if __name__ == '__main__': unittest.main() - #for block in blocksplitter('xxx.py'): print dispatch(block) + #for block in blocksplitter('xxx.py'): print rewrite_utest(block) From lac at codespeak.net Thu Jul 1 21:09:03 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Thu, 1 Jul 2004 21:09:03 +0200 (MEST) Subject: [pypy-svn] r5417 - pypy/trunk/src/pypy/tool Message-ID: <20040701190903.4A7755AC7F@thoth.codespeak.net> Author: lac Date: Thu Jul 1 21:09:02 2004 New Revision: 5417 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: Decided to move it over here, since people might want to check it out for considering converting their unittests ... Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Thu Jul 1 21:09:02 2004 @@ -6,109 +6,49 @@ d={} # d is the dictionary of unittest changes, keyed to the old name -# used by unittest. d['new'] is the new replacement function, and -# d['change'] is one of the following functions -# namechange_only e.g. assertRaises becomes raises -# fail_special e.g. fail() becomes raise AssertionError -# strip_parens e.g. assert_(expr) becomes assert expr -# comma_to_op e.g. assertEquals(l, r) becomes assert l == r -# rounding e.g. assertAlmostEqual(l, r) becomes -# assert round(l - r, 7) == 0 -# Finally, 'op' is the operator you will substitute, if applicable. -# Got to define the dispatch functions first .... - -def namechange_only(old, new, block, op): - '''rename a function. dictionary dispatched.''' - return re.sub('self.'+old, new, block) - -def fail_special(old, new, block, op): - '''change fail function to raise AssertionError. dictionary dispatched. ''' - indent, expr, trailer = common_setup(old, block) - - if expr == '': # fail() --> raise AssertionError - return indent + new + trailer - else: # fail('Problem') --> raise AssertionError, 'Problem' - return indent + new + ', ' + expr + trailer - -def comma_to_op(old, new, block, op): - '''change comma to appropriate op. dictionary dispatched. ''' - indent, expr, trailer = common_setup(old, block) - new = new + ' ' - op = ' ' + op - left, right = get_expr(expr, ',') +# used by unittest. d['new'] is the new replacement function. +# arg_nums is the possible number of arguments to the unittest +# function. The last argument to the arg_nums list is the position the +# optional 'message' to print when the unittest fails should occur. +# assertRaises and failUnlessRaises, unlike all the other functions +# cannot have an special message to print, and can be passed any +# number of arguments, so their arg_nums is [None] (in the absense of +# [Any]. - try: - parser.expr(left.lstrip()) # that paren came off easily - except SyntaxError: - left = re.sub(linesep, '\\'+linesep, left) - - right = process_args(right) +# 'op' is the operator you will substitute, if applicable. - if right.startswith(linesep): - op = op + '\\' - return indent + new + left + op + right + trailer - -def strip_parens(old, new, block, op): - '''remove one set of parens. dictionary dispatched. ''' - indent, args, trailer = common_setup(old, block) - new = new + ' ' - - args = process_args(args) - return indent + new + args + trailer - -def rounding(old, new, block, op): - '''special for assertAlmostEqual and freinds. dictionary dispatched. ''' - indent, args, trailer = common_setup(old, block) - op = ' ' + op + ' ' - - first, rest = get_expr(args.lstrip()) - second, rest = find_first_expr(rest.lstrip()) - try: - places, msg = find_first_expr(rest.lstrip()) - if msg: - places = places.rstrip()[:-1] - return indent + new + '(' + first + ' - ' + second + ' ' + \ - places + ')' + op + '0,' + msg - else: - return indent + new + '(' + first + ' - ' + second + ' ' + \ - places + ')' + op + '0' - - except AttributeError: - return indent + new + '(' + first + ' - ' + second + ', 7)' + op + '0' - -# Now the dictionary of unittests. There sure are enough of them! - -d['assertRaises'] = {'new': 'raises', 'change': namechange_only, 'op': None} +d['assertRaises'] = {'new': 'raises', 'op': '', 'arg_nums':[None]} d['failUnlessRaises'] = d['assertRaises'] -d['fail'] = {'new': 'raise AssertionError', 'change': fail_special, 'op': None} +d['fail'] = {'new': 'raise AssertionError', 'op': '', 'arg_nums':[0,1]} -d['assertEqual'] = {'new': 'assert', 'change': comma_to_op, 'op': '=='} +d['assert_'] = {'new': 'assert', 'op': '', 'arg_nums':[1,2]} +d['failIf'] = {'new': 'assert not','op': '', 'arg_nums':[1,2]} +d['failUnless'] = d['assert_'] + +d['assertEqual'] = {'new': 'assert', 'op': ' ==', 'arg_nums':[2,3]} d['assertEquals'] = d['assertEqual'] -d['assertNotEqual'] = {'new': 'assert', 'change':comma_to_op, 'op': '!='} +d['assertNotEqual'] = {'new': 'assert', 'op': ' !=', 'arg_nums':[2,3]} d['assertNotEquals'] = d['assertNotEqual'] -d['failUnlessEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '!='} +d['failUnlessEqual'] = {'new': 'assert not', 'op': ' !=', 'arg_nums':[2,3]} -d['failIfEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '=='} +d['failIfEqual'] = {'new': 'assert not', 'op': ' ==', 'arg_nums':[2,3]} -d['assert_'] = {'new': 'assert','change': strip_parens, 'op': None} -d['failUnless'] = d['assert_'] - -d['failIf'] = {'new': 'assert not', 'change': strip_parens, 'op': None} - -d['assertAlmostEqual'] = {'new': 'assert round', 'change': rounding, 'op':'=='} +d['assertAlmostEqual'] = {'new': 'assert round', 'op':' ==','arg_nums':[2,3,4]} d['assertAlmostEquals'] = d['assertAlmostEqual'] -d['assertNotAlmostEqual'] = {'new':'assert round','change':rounding, 'op':'!='} +d['assertNotAlmostEqual'] = {'new':'assert round','op': ' !=', + 'arg_nums':[2,3,4]} d['assertNotAlmostEquals'] = d['assertNotAlmostEqual'] -d['failIfAlmostEqual'] = {'new': 'assert not round', - 'change': rounding, 'op': '=='} -d['failUnlessAlmostEqual'] = {'new': 'assert not round', - 'change': rounding, 'op': '!='} +d['failIfAlmostEqual'] = {'new': 'assert not round', 'op': ' ==', + 'arg_nums':[2,3,4]} + +d['failUnlessAlmostEquals'] = {'new': 'assert not round', 'op': ' !=', + 'arg_nums':[2,3,4]} leading_spaces = re.compile(r'^(\s*)') # this never fails @@ -137,54 +77,108 @@ blocklist.append(blockstring) return blocklist -def dispatch(s): - '''do a dictionary dispatch based on the change key in the dict d ''' - f = old_names.match(s) - if f: - key = f.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' - return d[key]['change'](key, d[key]['new'], s, d[key] ['op']) +def rewrite_utest(block): + utest = old_names.match(block) + if utest: + old = utest.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' + new = d[old]['new'] + op = d[old]['op'] + possible_args = d[old]['arg_nums'] + message_position = possible_args[-1] + + if not message_position: # just rename assertRaises + return re.sub('self.'+old, new, block) + + indent, args, message, trailer = decompose_unittest( + old, block, message_position) + + key = len(args) + if message: + key += 1 + + if key is 0: # fail() + return indent + new + trailer + + elif key is 1 and key is message_position: # fail('unhappy message') + return new + ', ' + message + trailer + + elif message_position is 4: #assertAlmostEqual and freinds + try: + pos = args[2].lstrip() + except IndexError: + pos = 7 + string = '(' + args[0] + ' -' + args[1] + ', ' + pos + ')' + string += op + ' 0' + if message: + string = string + ',' + message + return indent + new + string + trailer + + else: + string = op.join(args) + if message: + string = string + ',' + message + + return indent + new + ' ' + string + trailer else: # just copy uninteresting lines - return s + return block + +def decompose_unittest(old, block, message_position): + '''decompose the block into its component parts''' + + ''' returns indent, arglist, message, trailer + indent -- the indentation + arglist -- the arguments to the unittest function + message -- the optional message to print when it fails, and + trailer -- any extra junk after the closing paren, such as #commment + ''' + + message = None -def common_setup(old, block): - '''split the block into component parts''' indent = re.search(r'^(\s*)', block).group() pat = re.search('self.' + old + r'\(', block) - expr, trailer = get_expr(block[pat.end():], ')') - return indent, expr, trailer - -def find_first_expr(args): - '''find the first expression, return it, and the rest if it exists''' - sep = ',' try: - left, right = get_expr(args, sep) - left = re.sub(linesep, '\\'+linesep, left) - - # only repair the lhs. The rhs may be a multiline string that - # can take care of itself. - - if right.startswith(linesep):# that needs a slash too ... - sep = sep + '\\' - - return left + sep, right - except SyntaxError: # just a regular old multiline expression - return re.sub(linesep, '\\'+linesep, args), None + args, trailer = get_expr(block[pat.end():], ')') + except SyntaxError: # this wasn't an expression. ick. + return indent, [block], message, None + + arglist = break_args(args, []) + if arglist == ['']: # there weren't any + return indent, [], message, trailer + else: + newl = [] + if len(arglist) == message_position: + message = arglist[-1] + arglist = arglist[:-1] + if message.lstrip('\t ').startswith(linesep): + message = '(' + message + ')' + + if arglist: + for arg in arglist: + try: + parser.expr(arg.lstrip('\t ')) + # remove tab and space, but keep newline. + except SyntaxError: + arg = '(' + arg + ')' + + newl.append(arg) + arglist = newl + + return indent, arglist, message, trailer -def process_args(args): - '''start the process whereby lines that need backslashes get them''' +def break_args(args, arglist): + '''recursively break a string into a list of arguments''' try: - parser.expr(args.lstrip()) # the parens come off easily - return args - except SyntaxError: - # paste continuation backslashes on our multiline constructs. - left, right = find_first_expr(args) - if right: - return left + right + first, rest = get_expr(args, ',') + if not rest: + return arglist + [first] else: - return left + return [first] + break_args(rest, arglist) + except SyntaxError: + return arglist + [args] -def get_expr(s, char=','): +def get_expr(s, char): '''split a string into an expression, and the rest of the string''' + pos=[] for i in range(len(s)): if s[i] == char: @@ -204,16 +198,16 @@ class Testit(unittest.TestCase): def test(self): - self.assertEquals(dispatch("badger badger badger"), + self.assertEquals(rewrite_utest("badger badger badger"), "badger badger badger") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( "self.assertRaises(excClass, callableObj, *args, **kwargs)" ), "raises(excClass, callableObj, *args, **kwargs)" ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( """ self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) """ @@ -222,7 +216,7 @@ raises(TypeError, func, 42, **{'arg1': 23}) """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( """ self.assertRaises(TypeError, func, @@ -235,76 +229,79 @@ mushroom) """ ) - self.assertEquals(dispatch("self.fail()"), "raise AssertionError") - self.assertEquals(dispatch("self.fail('mushroom, mushroom')"), + self.assertEquals(rewrite_utest("self.fail()"), "raise AssertionError") + self.assertEquals(rewrite_utest("self.fail('mushroom, mushroom')"), "raise AssertionError, 'mushroom, mushroom'") - self.assertEquals(dispatch("self.assert_(x)"), "assert x") - self.assertEquals(dispatch("self.failUnless(func(x)) # XXX"), + self.assertEquals(rewrite_utest("self.assert_(x)"), "assert x") + self.assertEquals(rewrite_utest("self.failUnless(func(x)) # XXX"), "assert func(x) # XXX") - self.assertEquals(dispatch( - """ + self.assertEquals(rewrite_utest( + r""" self.assert_(1 + f(y) - + z) # multiline, add continuation backslash + + z) # multiline, keep parentheses """ ), r""" - assert 1 + f(y)\ - + z # multiline, add continuation backslash + assert (1 + f(y) + + z) # multiline, keep parentheses """ ) - self.assertEquals(dispatch("self.assert_(0, 'badger badger')"), + self.assertEquals(rewrite_utest("self.assert_(0, 'badger badger')"), "assert 0, 'badger badger'") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest("self.assert_(0, '''badger badger''')"), + "assert 0, '''badger badger'''") + + self.assertEquals(rewrite_utest( r""" self.assert_(0, 'Meet the badger.\n') """ ), r""" - assert 0,\ - 'Meet the badger.\n' + assert 0,( + 'Meet the badger.\n') """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.failIf(0 + 0 + len('badger\n') + 0, '''badger badger badger badger mushroom mushroom Snake! Ooh a snake! - ''') # multiline, must remove the parens + ''') # multiline, must move the parens """ ), r""" - assert not 0 + 0\ - + len('badger\n')\ - + 0, '''badger badger badger badger + assert not (0 + 0 + + len('badger\n') + + 0), '''badger badger badger badger mushroom mushroom Snake! Ooh a snake! - ''' # multiline, must remove the parens + ''' # multiline, must move the parens """ ) - self.assertEquals(dispatch("self.assertEquals(0, 0)"), + self.assertEquals(rewrite_utest("self.assertEquals(0, 0)"), "assert 0 == 0") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.assertEquals(0, 'Run away from the snake.\n') """ ), r""" - assert 0 ==\ - 'Run away from the snake.\n' + assert 0 ==( + 'Run away from the snake.\n') """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.assertEquals(badger + 0 + mushroom @@ -312,13 +309,13 @@ """ ), r""" - assert badger + 0\ - + mushroom\ - + snake == 0 + assert (badger + 0 + + mushroom + + snake) == 0 """ ) - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.assertNotEquals(badger + 0 + mushroom @@ -328,15 +325,15 @@ """ ), r""" - assert badger + 0\ - + mushroom\ - + snake !=\ - mushroom\ - - badger + assert (badger + 0 + + mushroom + + snake) !=( + mushroom + - badger) """ ) - self.assertEqual(dispatch( + self.assertEqual(rewrite_utest( r""" self.assertEquals(badger(), mushroom() @@ -345,67 +342,64 @@ """ ), r""" - assert badger() ==\ - mushroom()\ - + snake(mushroom)\ - - badger() + assert badger() ==( + mushroom() + + snake(mushroom) + - badger()) """ ) - self.assertEquals(dispatch("self.failIfEqual(0, 0)"), + self.assertEquals(rewrite_utest("self.failIfEqual(0, 0)"), "assert not 0 == 0") - self.assertEquals(dispatch("self.failUnlessEqual(0, 0)"), + self.assertEquals(rewrite_utest("self.failUnlessEqual(0, 0)"), "assert not 0 != 0") - self.assertEquals(dispatch( + self.assertEquals(rewrite_utest( r""" self.failUnlessEqual(mushroom() + mushroom() - + mushroom(), '''badger badger badger badger + + mushroom(), '''badger badger badger badger badger badger badger badger badger badger badger - ''') # multiline, must remove the parens + ''') # multiline, must move the parens """ ), r""" - assert not mushroom()\ - + mushroom()\ - + mushroom() != '''badger badger badger badger + assert not (mushroom() + + mushroom() + + mushroom()) != '''badger badger badger badger badger badger badger badger badger badger badger - ''' # multiline, must remove the parens + ''' # multiline, must move the parens """ ) - - self.assertEquals(dispatch( + + + self.assertEquals(rewrite_utest( r""" - self.assertEquals(badger(), - snake(), 'BAD BADGER') + self.assertEquals('''snake snake snake + snake snake snake''', mushroom) """ ), r""" - assert badger() ==\ - snake(), 'BAD BADGER' + assert '''snake snake snake + snake snake snake''' == mushroom """ ) - self.assertEquals(dispatch( + + self.assertEquals(rewrite_utest( r""" self.assertEquals(badger(), - snake(), '''BAD BADGER - BAD BADGER - BAD BADGER''' - ) + snake(), 'BAD BADGER') """ ), r""" - assert badger() ==\ - snake(), '''BAD BADGER - BAD BADGER - BAD BADGER''' - + assert badger() ==( + snake()), 'BAD BADGER' """ ) - self.assertEquals(dispatch( + + self.assertEquals(rewrite_utest( r""" self.assertNotEquals(badger(), snake()+ @@ -414,37 +408,43 @@ """ ), r""" - assert badger() !=\ - snake()+\ - snake(), 'POISONOUS MUSHROOM!\ + assert badger() !=( + snake()+ + snake()), 'POISONOUS MUSHROOM!\ Ai! I ate a POISONOUS MUSHROOM!!' """ ) - self.assertEquals(dispatch("self.assertAlmostEqual(f, s, 4, 'ow')"), - "assert round(f - s, 4) == 0, 'ow'" - ) - self.assertEquals(dispatch("self.assertAlmostEquals(b, m, 200)"), - "assert round(b - m, 200) == 0" - ) - self.assertEquals(dispatch("self.failUnlessAlmostEqual(l, q)"), - "assert not round(l - q, 7) != 0" - ) - self.assertEquals(dispatch( + + self.assertEquals(rewrite_utest( + r""" + self.assertEquals(badger(), + snake(), '''BAD BADGER + BAD BADGER + BAD BADGER''' + ) + """ + ), r""" - self.failIfAlmostEqual(badger(), - snake(), - 6, 'POISONOUS SNAKE!\ - Ai! I was bit by a POISONOUS SNAKE!!') + assert badger() ==( + snake()), '''BAD BADGER + BAD BADGER + BAD BADGER''' + + """ + ) + self.assertEquals(rewrite_utest( + r""" + self.assertAlmostEquals(first, second, 5, 'A Snake!') """ ), r""" - assert not round(badger() - snake(),\ - 6) == 0, 'POISONOUS SNAKE!\ - Ai! I was bit by a POISONOUS SNAKE!!' + assert round(first - second, 5) == 0, 'A Snake!' """ - ) - + ) + + if __name__ == '__main__': unittest.main() - #for block in blocksplitter('xxx.py'): print dispatch(block) + #for block in blocksplitter('xxx.py'): print rewrite_utest(block) + From lac at codespeak.net Fri Jul 2 16:39:33 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Fri, 2 Jul 2004 16:39:33 +0200 (MEST) Subject: [pypy-svn] r5418 - pypy/trunk/src/pypy/tool Message-ID: <20040702143933.2C2495B3DF@thoth.codespeak.net> Author: lac Date: Fri Jul 2 16:39:31 2004 New Revision: 5418 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: Found a bug. If you make a triple quoted comment, and you happen to start a line with self.someunittest, the program will try to parse it. :-) ''' talking talking talking self.assertEquals( ... whatever the results are .... more talking more talking ''' Its better to just copy those lines as is. Some comments will end up with the wrong syntax, but that is better than second-guessing, or failing due to a Syntax Error. Also moved some tests around, so that the ifs are if : return else: do a huge amount of work rather than upside down as I had them. Just a tiny bit of improved readability ... Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Fri Jul 2 16:39:31 2004 @@ -13,9 +13,11 @@ # assertRaises and failUnlessRaises, unlike all the other functions # cannot have an special message to print, and can be passed any # number of arguments, so their arg_nums is [None] (in the absense of -# [Any]. +# [Any]. But we don't process those arguments in any case, since +# all we need is a name change, so we don't care ... -# 'op' is the operator you will substitute, if applicable. +# 'op' is the operator you will substitute, if applicable. '' if there +# none. d['assertRaises'] = {'new': 'raises', 'op': '', 'arg_nums':[None]} @@ -37,7 +39,7 @@ d['failIfEqual'] = {'new': 'assert not', 'op': ' ==', 'arg_nums':[2,3]} -d['assertAlmostEqual'] = {'new': 'assert round', 'op':' ==','arg_nums':[2,3,4]} +d['assertAlmostEqual'] = {'new':'assert round', 'op':' ==', 'arg_nums':[2,3,4]} d['assertAlmostEquals'] = d['assertAlmostEqual'] d['assertNotAlmostEqual'] = {'new':'assert round','op': ' !=', @@ -78,20 +80,40 @@ return blocklist def rewrite_utest(block): + '''rewrite every block to use the new utest functions''' + + '''This is the code that actually knows the format of the old + and new unittests. The rewriting rules are picky with when + to add spaces, and commas, so there are unfortunately 7 exit + paths, all some form of 'return indent + new + string + trailer' + + ''' utest = old_names.match(block) - if utest: - old = utest.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' + + if not utest: # just copy uninteresting blocks that don't begin a utest + return block + + else: # we have an interesting block + + old = utest.group(0).lstrip()[5:-1] # ' self.blah(' -> 'blah' new = d[old]['new'] op = d[old]['op'] possible_args = d[old]['arg_nums'] message_position = possible_args[-1] - if not message_position: # just rename assertRaises + if not message_position: # just rename assertRaises & friends return re.sub('self.'+old, new, block) - indent, args, message, trailer = decompose_unittest( - old, block, message_position) - + try: + indent, args, message, trailer = decompose_unittest( + old, block, message_position) + except SyntaxError: # but we couldn't parse it! Either it is + # malformed, or possibly deeply embedded inside + # a triple quoted string, which happens to + # start 'self.someunitttest(blah blah blah + return block + + # otherwise, we have a real one that we can parse. key = len(args) if message: key += 1 @@ -102,11 +124,11 @@ elif key is 1 and key is message_position: # fail('unhappy message') return new + ', ' + message + trailer - elif message_position is 4: #assertAlmostEqual and freinds + elif message_position is 4: # assertAlmostEqual and friends try: pos = args[2].lstrip() except IndexError: - pos = 7 + pos = '7' # default if none is specified string = '(' + args[0] + ' -' + args[1] + ', ' + pos + ')' string += op + ' 0' if message: @@ -119,8 +141,6 @@ string = string + ',' + message return indent + new + ' ' + string + trailer - else: # just copy uninteresting lines - return block def decompose_unittest(old, block, message_position): '''decompose the block into its component parts''' @@ -131,37 +151,40 @@ message -- the optional message to print when it fails, and trailer -- any extra junk after the closing paren, such as #commment ''' - - message = None - + indent = re.search(r'^(\s*)', block).group() pat = re.search('self.' + old + r'\(', block) - try: - args, trailer = get_expr(block[pat.end():], ')') - except SyntaxError: # this wasn't an expression. ick. - return indent, [block], message, None + args, trailer = get_expr(block[pat.end():], ')') arglist = break_args(args, []) + if arglist == ['']: # there weren't any - return indent, [], message, trailer + return indent, [], [], trailer + + if len(arglist) != message_position: + message = None else: - newl = [] - if len(arglist) == message_position: - message = arglist[-1] - arglist = arglist[:-1] - if message.lstrip('\t ').startswith(linesep): - message = '(' + message + ')' - - if arglist: - for arg in arglist: - try: - parser.expr(arg.lstrip('\t ')) - # remove tab and space, but keep newline. - except SyntaxError: - arg = '(' + arg + ')' + message = arglist[-1] + arglist = arglist[:-1] + if message.lstrip('\t ').startswith(linesep): + message = '(' + message + ')' + # In proper input, message is required to be a string. + # Thus we can assume that however the string handled its + # line continuations in the original unittest will also work + # here. But if the line happens to break before the quoting + # begins, you will need another set of parens, (or a backslash). - newl.append(arg) - arglist = newl + if arglist: + newl = [] + for arg in arglist: + try: + parser.expr(arg.lstrip('\t ')) + # Again we want to enclose things that happen to have + # a linebreak just before the new arg. + except SyntaxError: + arg = '(' + arg + ')' + newl.append(arg) + arglist = newl return indent, arglist, message, trailer @@ -432,6 +455,7 @@ """ ) + self.assertEquals(rewrite_utest( r""" self.assertAlmostEquals(first, second, 5, 'A Snake!') @@ -441,6 +465,96 @@ assert round(first - second, 5) == 0, 'A Snake!' """ ) + + self.assertEquals(rewrite_utest( + r""" + self.assertAlmostEquals(first, second, 120) + """ + ), + r""" + assert round(first - second, 120) == 0 + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.assertAlmostEquals(first, second) + """ + ), + r""" + assert round(first - second, 7) == 0 + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.assertAlmostEqual(first, second, 5, '''A Snake! + Ohh A Snake! A Snake!! + ''') + """ + ), + r""" + assert round(first - second, 5) == 0, '''A Snake! + Ohh A Snake! A Snake!! + ''' + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.assertNotAlmostEqual(first, second, 5, 'A Snake!') + """ + ), + r""" + assert round(first - second, 5) != 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.failIfAlmostEqual(first, second, 5, 'A Snake!') + """ + ), + r""" + assert not round(first - second, 5) == 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.failIfAlmostEqual(first, second, 5, 'A Snake!') + """ + ), + r""" + assert not round(first - second, 5) == 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.failUnlessAlmostEquals(first, second, 5, 'A Snake!') + """ + ), + r""" + assert not round(first - second, 5) != 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.assertAlmostEquals(now do something reasonable ..() + oops, I am inside a comment as a ''' string, and the fname was + mentioned in passing, leaving us with something that isn't an + expression ... will this blow up? + """ + ), + r""" + self.assertAlmostEquals(now do something reasonable ..() + oops, I am inside a comment as a ''' string, and the fname was + mentioned in passing, leaving us with something that isn't an + expression ... will this blow up? + """ + ) if __name__ == '__main__': From lac at codespeak.net Fri Jul 2 19:06:32 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Fri, 2 Jul 2004 19:06:32 +0200 (MEST) Subject: [pypy-svn] r5419 - pypy/trunk/src/pypy/tool Message-ID: <20040702170632.D02715B3DF@thoth.codespeak.net> Author: lac Date: Fri Jul 2 19:06:24 2004 New Revision: 5419 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: Added a few unittests, but think they just showed that things worked. Changed the dictionary of unittests to be a dictionary of lists, not a dictionary of dictionaries. They only were used for assignment once, and this way we can make them print as a neat table. Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Fri Jul 2 19:06:24 2004 @@ -1,57 +1,39 @@ import re import unittest import parser -import os d={} # d is the dictionary of unittest changes, keyed to the old name -# used by unittest. d['new'] is the new replacement function. -# arg_nums is the possible number of arguments to the unittest -# function. The last argument to the arg_nums list is the position the -# optional 'message' to print when the unittest fails should occur. -# assertRaises and failUnlessRaises, unlike all the other functions -# cannot have an special message to print, and can be passed any -# number of arguments, so their arg_nums is [None] (in the absense of -# [Any]. But we don't process those arguments in any case, since -# all we need is a name change, so we don't care ... - -# 'op' is the operator you will substitute, if applicable. '' if there -# none. - - -d['assertRaises'] = {'new': 'raises', 'op': '', 'arg_nums':[None]} -d['failUnlessRaises'] = d['assertRaises'] - -d['fail'] = {'new': 'raise AssertionError', 'op': '', 'arg_nums':[0,1]} - -d['assert_'] = {'new': 'assert', 'op': '', 'arg_nums':[1,2]} -d['failIf'] = {'new': 'assert not','op': '', 'arg_nums':[1,2]} -d['failUnless'] = d['assert_'] - -d['assertEqual'] = {'new': 'assert', 'op': ' ==', 'arg_nums':[2,3]} -d['assertEquals'] = d['assertEqual'] - -d['assertNotEqual'] = {'new': 'assert', 'op': ' !=', 'arg_nums':[2,3]} -d['assertNotEquals'] = d['assertNotEqual'] - -d['failUnlessEqual'] = {'new': 'assert not', 'op': ' !=', 'arg_nums':[2,3]} - -d['failIfEqual'] = {'new': 'assert not', 'op': ' ==', 'arg_nums':[2,3]} - -d['assertAlmostEqual'] = {'new':'assert round', 'op':' ==', 'arg_nums':[2,3,4]} -d['assertAlmostEquals'] = d['assertAlmostEqual'] - -d['assertNotAlmostEqual'] = {'new':'assert round','op': ' !=', - 'arg_nums':[2,3,4]} +# used by unittest. +# d[old][0] is the new replacement function. +# d[old][1] is the operator you will substitute, or '' if there is none. +# d[old][2] is the possible number of arguments to the unittest +# function. + +# Old Unittest Name new name operator # of args +d['assertRaises'] = ('raises', '', ['Any']) +d['fail'] = ('raise AssertionError', '', [0,1]) +d['assert_'] = ('assert', '', [1,2]) +d['failIf'] = ('assert not', '', [1,2]) +d['assertEqual'] = ('assert', ' ==', [2,3]) +d['failIfEqual'] = ('assert not', ' ==', [2,3]) +d['assertNotEqual'] = ('assert', ' !=', [2,3]) +d['failUnlessEqual'] = ('assert not', ' !=', [2,3]) +d['assertAlmostEqual'] = ('assert round', ' ==', [2,3,4]) +d['failIfAlmostEqual'] = ('assert not round', ' ==', [2,3,4]) +d['assertNotAlmostEqual'] = ('assert round', ' !=', [2,3,4]) +d['failUnlessAlmostEquals'] = ('assert not round', ' !=', [2,3,4]) + +# the list of synonyms +d['failUnlessRaises'] = d['assertRaises'] +d['failUnless'] = d['assert_'] +d['assertEquals'] = d['assertEqual'] +d['assertNotEquals'] = d['assertNotEqual'] +d['assertAlmostEquals'] = d['assertAlmostEqual'] d['assertNotAlmostEquals'] = d['assertNotAlmostEqual'] -d['failIfAlmostEqual'] = {'new': 'assert not round', 'op': ' ==', - 'arg_nums':[2,3,4]} - -d['failUnlessAlmostEquals'] = {'new': 'assert not round', 'op': ' !=', - 'arg_nums':[2,3,4]} - +# set up the regular expressions we will need leading_spaces = re.compile(r'^(\s*)') # this never fails pat = '' @@ -59,7 +41,9 @@ pat += '|' + r'^(\s*)' + 'self.' + k + r'\(' # \tself.whatever( old_names = re.compile(pat[1:]) -linesep=os.linesep +linesep='\n' # nobody will really try to convert files not read + # in text mode, will they? + def blocksplitter(filename): '''split a file into blocks that are headed by functions to rename''' @@ -84,7 +68,7 @@ '''This is the code that actually knows the format of the old and new unittests. The rewriting rules are picky with when - to add spaces, and commas, so there are unfortunately 7 exit + to add spaces, and commas, so there are unfortunately 8 exit paths, all some form of 'return indent + new + string + trailer' ''' @@ -94,37 +78,51 @@ return block else: # we have an interesting block + old = utest.group(0).lstrip()[5:-1] + # old - the name we want to replace -- between the 'self.' and the '(' - old = utest.group(0).lstrip()[5:-1] # ' self.blah(' -> 'blah' - new = d[old]['new'] - op = d[old]['op'] - possible_args = d[old]['arg_nums'] - message_position = possible_args[-1] - - if not message_position: # just rename assertRaises & friends + # d is the dictionary of unittest changes, keyed to the old name + # used by unittest. + # d[old][0] is the new replacement function. + # d[old][1] is the operator you will use , or '' if there is none. + # d[old][2] is the possible number of arguments to the unittest + # function. + + new = d[old][0] + op = d[old][1] + possible_args = d[old][2] + + if new == 'raises': # just rename assertRaises & friends return re.sub('self.'+old, new, block) + else: + message_pos = possible_args[-1] + # the remaining unittests can have an optional message to + # print when they fail. It is always the last argument to + # the function. try: indent, args, message, trailer = decompose_unittest( - old, block, message_position) - except SyntaxError: # but we couldn't parse it! Either it is - # malformed, or possibly deeply embedded inside - # a triple quoted string, which happens to - # start 'self.someunitttest(blah blah blah - return block + old, block, message_pos) + except SyntaxError: # but we couldn't parse it! + return block + + # otherwise, we have a real one that we could parse. - # otherwise, we have a real one that we can parse. - key = len(args) + argnum = len(args) if message: - key += 1 - - if key is 0: # fail() + argnum += 1 + + if argnum not in possible_args: + # sanity check - this one isn't real either + return block + + if argnum is 0: # fail() return indent + new + trailer - elif key is 1 and key is message_position: # fail('unhappy message') - return new + ', ' + message + trailer + elif argnum is 1 and argnum is message_pos: # fail('unhappy message') + return indent + new + ', ' + message + trailer - elif message_position is 4: # assertAlmostEqual and friends + elif message_pos is 4: # assertAlmostEqual and friends try: pos = args[2].lstrip() except IndexError: @@ -135,14 +133,14 @@ string = string + ',' + message return indent + new + string + trailer - else: + else: #assert_, assertEquals and all the rest string = op.join(args) if message: string = string + ',' + message return indent + new + ' ' + string + trailer -def decompose_unittest(old, block, message_position): +def decompose_unittest(old, block, message_pos): '''decompose the block into its component parts''' ''' returns indent, arglist, message, trailer @@ -161,7 +159,7 @@ if arglist == ['']: # there weren't any return indent, [], [], trailer - if len(arglist) != message_position: + if len(arglist) != message_pos: message = None else: message = arglist[-1] @@ -185,7 +183,7 @@ arg = '(' + arg + ')' newl.append(arg) arglist = newl - + return indent, arglist, message, trailer def break_args(args, arglist): @@ -458,6 +456,50 @@ self.assertEquals(rewrite_utest( r""" + self.assertEquals('''BAD BADGER + BAD BADGER + BAD BADGER''', '''BAD BADGER + BAD BADGER + BAD BADGER''') + """ + ), + r""" + assert '''BAD BADGER + BAD BADGER + BAD BADGER''' == '''BAD BADGER + BAD BADGER + BAD BADGER''' + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.assertEquals('''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''', + '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''', + ''' FAILURE + FAILURE + FAILURE''') + """ + ), + r""" + assert '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''' ==( + '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM'''),( + ''' FAILURE + FAILURE + FAILURE''') + """ + ) + + self.assertEquals(rewrite_utest( + r""" self.assertAlmostEquals(first, second, 5, 'A Snake!') """ ), @@ -522,11 +564,11 @@ self.assertEquals(rewrite_utest( r""" - self.failIfAlmostEqual(first, second, 5, 'A Snake!') + self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ ), r""" - assert not round(first - second, 5) == 0, 'A Snake!' + self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ ) From hpk at codespeak.net Fri Jul 2 20:38:15 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Jul 2004 20:38:15 +0200 (MEST) Subject: [pypy-svn] r5420 - pypy/trunk/src/pypy/appspace Message-ID: <20040702183815.548E75B3DF@thoth.codespeak.net> Author: hpk Date: Fri Jul 2 20:38:14 2004 New Revision: 5420 Removed: pypy/trunk/src/pypy/appspace/complexobject.py Log: removed old complexobject file Deleted: /pypy/trunk/src/pypy/appspace/complexobject.py ============================================================================== --- /pypy/trunk/src/pypy/appspace/complexobject.py Fri Jul 2 20:38:14 2004 +++ (empty file) @@ -1,356 +0,0 @@ -class complex(object): - """complex(real[, imag]) -> complex number - - Create a complex number from a real part and an optional imaginary part. - This is equivalent to (real + imag*1j) where imag defaults to 0.""" - PREC_REPR = 0 # 17 - PREC_STR = 0 # 12 - - def __init__(self, real=0.0, imag=None): - if isinstance(real, str) and imag is not None: - msg = "complex() can't take second arg if first is a string" - raise TypeError, msg - - if isinstance(imag, str): - msg = "complex() second arg can't be a string" - raise TypeError, msg - - if isinstance(real, str): - real, imag = self._makeComplexFromString(real) - self.__dict__['real'] = real - self.__dict__['imag'] = imag - else: - if imag is None: - imag = 0. - self.__dict__['real'] = float(real) - self.__dict__['imag'] = float(imag) - - - def __setattr__(self, name, value): - if name in ('real', 'imag'): - raise TypeError, "readonly attribute" - else: - raise TypeError, "'complex' object has no attribute %s" % name - - def _makeComplexFromString(self, string): - import re - pat = re.compile(" *([\+\-]?\d*\.?\d*)([\+\-]?\d*\.?\d*)[jJ] *") - m = pat.match(string) - x, y = m.groups() - if len(y) == 1 and y in '+-': - y = y + '1.0' - x, y = map(float, [x, y]) - return x, y - - - def __description(self, precision): - sign = '+' - if self.imag < 0.: - sign = '' - if self.real != 0.: - format = "(%%%02dg%%s%%%02dgj)" % (precision, precision) - args = (self.real, sign, self.imag) - else: - format = "%%%02dgj" % precision - args = self.imag - return format % args - - - def __repr__(self): - return self.__description(self.PREC_REPR) - - - def __str__(self): - return self.__description(self.PREC_STR) - - - def __hash__(self): - hashreal = hash(self.real) - hashimag = hash(self.imag) - - # Note: if the imaginary part is 0, hashimag is 0 now, - # so the following returns hashreal unchanged. This is - # important because numbers of different types that - # compare equal must have the same hash value, so that - # hash(x + 0*j) must equal hash(x). - - combined = hashreal + 1000003 * hashimag - if combined == -1: - combined = -2 - - return combined - - - def __add__(self, other): - self, other = self.__coerce__(other) - real = self.real + other.real - imag = self.imag + other.imag - return complex(real, imag) - - - def __sub__(self, other): - self, other = self.__coerce__(other) - real = self.real - other.real - imag = self.imag - other.imag - return complex(real, imag) - - - def __mul__(self, other): - if other.__class__ != complex: - return complex(other*self.real, other*self.imag) - - real = self.real*other.real - self.imag*other.imag - imag = self.real*other.imag + self.imag*other.real - return complex(real, imag) - - - def __div__(self, other): - if other.__class__ != complex: - return complex(self.real/other, self.imag/other) - - if other.real < 0: - abs_breal = -other.real - else: - abs_breal = other.real - - if other.imag < 0: - abs_bimag = -other.imag - else: - abs_bimag = other.imag - - if abs_breal >= abs_bimag: - # divide tops and bottom by other.real - if abs_breal == 0.0: - real = imag = 0.0 - else: - ratio = other.imag / other.real - denom = other.real + other.imag * ratio - real = (self.real + self.imag * ratio) / denom - imag = (self.imag - self.real * ratio) / denom - else: - # divide tops and bottom by other.imag - ratio = other.real / other.imag - denom = other.real * ratio + other.imag - assert other.imag != 0.0 - real = (self.real * ratio + self.imag) / denom - imag = (self.imag * ratio - self.real) / denom - - return complex(real, imag) - - - def __floordiv__(self, other): - return self / other - - - def __truediv__(self, other): - return self / other - - - def __mod__(self, other): - import warnings, math - warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning) - - if other.real == 0. and other.imag == 0.: - raise ZeroDivisionError, "complex remainder" - - div = self/other # The raw divisor value. - div = complex(math.floor(div.real), 0.0) - mod = self - div*other - - if mod.__class__ == complex: - return mod - else: - return complex(mod) - - - def __divmod__(self, other): - import warnings, math - warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning) - - if other.real == 0. and other.imag == 0.: - raise ZeroDivisionError, "complex remainder" - - div = self/other # The raw divisor value. - div = complex(math.floor(div.real), 0.0) - mod = self - div*other - return div, mod - - - def __pow__(self, other): - import math - if other.__class__ != complex: - other = complex(other, 0) - - a, b = self, other - - if b.real == 0. and b.imag == 0.: - real = 1. - imag = 0. - elif a.real == 0. and a.imag == 0.: - real = 0. - imag = 0. - else: - vabs = math.hypot(a.real,a.imag) - len = math.pow(vabs,b.real) - at = math.atan2(a.imag, a.real) - phase = at*b.real - if b.imag != 0.0: - len /= math.exp(at*b.imag) - phase += b.imag*math.log(vabs) - real = len*math.cos(phase) - imag = len*math.sin(phase) - - return complex(real, imag) - - - def __neg__(self): - return complex(-self.real, -self.imag) - - - def __pos__(self): - return complex(self.real, self.imag) - - - def __abs__(self): - import math - result = math.hypot(self.real, self.imag) - return float(result) - - - def __nonzero__(self): - return self.real != 0.0 or self.imag != 0.0 - - - def __coerce__(self, other): - typ = type(other) - - if typ is int: - return self, complex(float(other)) - elif typ is long: - return self, complex(float(other)) - elif typ is float: - return self, complex(other) - elif other.__class__ == complex: - return self, other - elif typ is complex: - return self, complex(other.real, other.imag) - - raise TypeError, "number %r coercion failed" % typ - - - def conjugate(self): - return complex(self.real, -self.imag) - - def __eq__(self, other): - self, other = self.__coerce__(other) - return self.real == other.real and self.imag == other.imag - - def __ne__(self, other): - self, other = self.__coerce__(other) - return self.real != other.real or self.imag != other.imag - - - # unsupported operations - - def __lt__(self, other): - raise TypeError, "cannot compare complex numbers using <, <=, >, >=" - - - def __le__(self, other): - raise TypeError, "cannot compare complex numbers using <, <=, >, >=" - - - def __gt__(self, other): - raise TypeError, "cannot compare complex numbers using <, <=, >, >=" - - - def __ge__(self, other): - raise TypeError, "cannot compare complex numbers using <, <=, >, >=" - - - def __int__(self): - raise TypeError, "can't convert complex to int; use e.g. int(abs(z))" - - - def __long__(self): - raise TypeError, "can't convert complex to long; use e.g. long(abs(z))" - - - def __float__(self): - raise TypeError, "can't convert complex to float; use e.g. float(abs(z))" - - - def _unsupportedOp(self, other, op): - selfTypeName = type(self).__name__ - otherTypeName = type(other).__name__ - args = (op, selfTypeName, otherTypeName) - msg = "unsupported operand type(s) for %s: '%s' and '%s'" % args - raise TypeError, msg - - - def __and__(self, other): - self._unsupportedOp(self, other, "&") - - - def __or__(self, other): - self._unsupportedOp(self, other, "|") - - - def __xor__(self, other): - self._unsupportedOp(self, other, "^") - - - def __rshift__(self, other): - self._unsupportedOp(self, other, ">>") - - - def __lshift__(self, other): - self._unsupportedOp(self, other, "<<") - - - def __iand__(self, other): - self._unsupportedOp(self, other, "&=") - - - def __ior__(self, other): - self._unsupportedOp(self, other, "|=") - - - def __ixor__(self, other): - self._unsupportedOp(self, other, "^=") - - - def __irshift__(self, other): - self._unsupportedOp(self, other, ">>=") - - - def __ilshift__(self, other): - self._unsupportedOp(self, other, "<<=") - - - # augmented assignment operations - - def __iadd__(self, other): - return self + other - - - def __isub__(self, other): - return self - other - - - def __imul__(self, other): - return self * other - - - def __idiv__(self, other): - return self / other - - -# def __new__(self, ...): -# pass - - -# test mod, divmod - -# add radd, rsub, rmul, rdiv... - From hpk at codespeak.net Fri Jul 2 20:44:05 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Jul 2004 20:44:05 +0200 (MEST) Subject: [pypy-svn] r5421 - pypy/trunk/doc Message-ID: <20040702184405.C79035B3DF@thoth.codespeak.net> Author: hpk Date: Fri Jul 2 20:44:04 2004 New Revision: 5421 Modified: pypy/trunk/doc/developers.txt Log: small fix Modified: pypy/trunk/doc/developers.txt ============================================================================== --- pypy/trunk/doc/developers.txt (original) +++ pypy/trunk/doc/developers.txt Fri Jul 2 20:44:04 2004 @@ -1,6 +1,6 @@ -pypy project developers:: +pypy project developers and contributors:: Armin Rigo Holger Krekel Samuele Pedroni Christian Tismer From hpk at codespeak.net Fri Jul 2 21:14:26 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Jul 2004 21:14:26 +0200 (MEST) Subject: [pypy-svn] r5423 - pypy/trunk/doc/sprintinfo Message-ID: <20040702191426.F0C165B3DF@thoth.codespeak.net> Author: hpk Date: Fri Jul 2 21:14:26 2004 New Revision: 5423 Added: pypy/trunk/doc/sprintinfo/AmsterdamReport.txt Removed: pypy/trunk/doc/sprintinfo/AmsterdamAnnouncement.txt Log: removed AmsterdamAnnouncement in favour of the Report about this sprint. Deleted: /pypy/trunk/doc/sprintinfo/AmsterdamAnnouncement.txt ============================================================================== --- /pypy/trunk/doc/sprintinfo/AmsterdamAnnouncement.txt Fri Jul 2 21:14:26 2004 +++ (empty file) @@ -1,124 +0,0 @@ -PyPy Sprint announcement & news from the project -================================================ - -We are coming close to a first experimental release of PyPy, -a more flexible Python implementation written in Python. -The sprint to make this happen will take place in Amsterdam, -a city known to be reachable by cheap flights :-) - -This is 1) the announcement for the sprint; - 2) news about the current state of PyPy; - 3) some words about a proposal we recently submitted - to the European Union. - - -Amsterdam Sprint Details ------------------------- - -The Sprint will take place from - - the 14th of December to the 21st of December at the - - "Vrije Universiteit in Amsterdam", 14th-21th Dec 2003. - -thanks to Etienne Posthumus, who helps us to organize the event. The -main goal will be a complete C translation of PyPy, probably still using -a hacked Pyrex-variant as an intermediate layer and using CPython's -runtime. We also plan to work on some fun frontends to PyPy like one -based on pygame or a web browser to visualize interactions between -interpreter and objectspace. - -If you want to participate on the sprint, please subscribe here - - http://codespeak.net/mailman/listinfo/pypy-sprint - -and list yourself on this wiki page - - http://codespeak.net/moin/pypy/moin.cgi/AmsterdamSprint - -where you will also find more information as the sprint date -approaches. If you are just interested but don't know if you -come then only subscribe to the mailing list. - - -State of the PyPy project --------------------------- - -PyPy works pretty well but still on top of CPython. The double -interpretation penalty makes it - as expected - incredibly slow :-) In -the Berlin sprint we have thus started to work on the "translation" -part, i.e. how this code should be translated into C. We can now -translate simple functions to C-like code including some type -annotations. For convenience, we are reusing a modified subset of Pyrex -to generate the low-level C code. Thanks to Seo (who joined the project -from South-Korea) we also have a lisp-backend to fuel the endless c.l.py -threads about python versus lisp :-) - -The goal of the next sprint is to complete this work so that we can -translate the complete PyPy source into a huge Pyrex module, and then a -big CPython extension module. True, the result is not independent from -CPython, as it runs reusing its runtime environment. But it's probably -an interesting enough state to make a public release from. - -The translation is done by generating a control flow of functions by -means of abstract interpretation. IOW, we run the PyPy interpreter with -a custom object space ("flowobjspace") which generates a control flow -graph (including the elementary operations) which is then used to -generate low-level code for backends. We also have preliminary type -inference on the graphs, which can be used by the Pyrex generator to -emit some C type declarations. - -Writing transformations and analysis of these graphs and displaying them -with GraphViz's 'dot' is great fun! We certainly have a greater need -than ever for graphical interactive tools to see, understand and debug -all these graph manipulations and run tests of them. Currently it is a -bit difficult to write a test that checks that a transformed graph -"looks right"! - -What we expect from the Amsterdam sprint is thus: - -- a big not-too-slow "cpypy.so" extension module for CPython, where at - least integer arithmetic is done efficiently - -- interactive tools to display and debug and test PyPy, visualizing - control flow, call-graphs and state models. - -- improving and rewriting our testing tools to give us more control over - the testing process, and to allow more interactive testing sessions. - - -Other interesting News ----------------------- - -Before mid October, we also had a quite different Sprint. It was an -approximately 10-day effort towards submitting a proposal to the EU. If -it is accepted we will have resources to fund some developers working -full- or parttime on the project. However, our "sprint driven -development" will continue to play the central role for development of -PyPy. - -There are especially two technical sections of the proposal which you -might find interesting to read: - - "Scientific and technological objectives": - http://codespeak.net/pypy/index.cgi?doc/funding/B1.0 - - "Detailed implementation plan" - http://codespeak.net/pypy/index.cgi?doc/funding/B6.0 - -Maybe you want to read the whole proposal for other reasons, too, like -making a EU project of your own or competing with us. Actually, -with our sprints there is usually a lot of room for cooperation :-) -Anyway, here is the PDF-url: - - http://codespeak.net/svn/pypy/trunk/doc/funding/proposal/part_b.pdf - -Everybody who thinks that he/she could help on the project is -invited to join! Btw, the latest discussions about our sprint -goals usually take place on the pypy-dev list: - - http://codespeak.net/mailman/listinfo/pypy-dev - -have fun, - - Armin & Holger Added: pypy/trunk/doc/sprintinfo/AmsterdamReport.txt ============================================================================== --- (empty file) +++ pypy/trunk/doc/sprintinfo/AmsterdamReport.txt Fri Jul 2 21:14:26 2004 @@ -0,0 +1,226 @@ + +Amsterdam Sprint 14-21 Dec. 2004 +-------------------------------- + +Here is a mail-report from Holger Krekel sent to pypy-dev. + +Hello PyPy, + +the Amsterdam sprint has just finished and here is a report and some +surrounding and outlook information. As usual please comment/add/correct +me - especially the sprinters. I also wouldn't mind some discussion of +what and how we could do things better at the next sprint. First of +all, big thanks to *Etienne Posthumus* who patiently helped organizing +this sprint even though he had to deal with various other problems at +the same time. + +Before i start with details i recommend reading through the new +Architecture document at + + http://codespeak.net/pypy/index.cgi?doc/architecture.html + +in case you don't know what i am talking about regarding the Amsterdam +sprint results :-) + +Originally, we intended to go rather directly for translation and thus +for a first release of PyPy. But before the sprint we decided to +go differently about the sprint not only because Michael Hudson and +Christian Tismer had to cancel their participation but we also wanted to +give a smooth introduction for the new developers attending the sprint. +Therefore we didn't press very hard at translation and type inference +and major suprises were awaiting us anyway ... + + +fixing lots and lots of bugs, adding more builtins and more introspection +------------------------------------------------------------------------- + +On this front mainly Alex Martelli, Patrick Maupin, Laura Creighton and +Jacob Hallen added and fixed a lot of builtins and modules and made it +possible to run - among other modules - the pystone benchmark: on most machines +we have more than one pystone with PyPy already :-) While trying to +get 'long' objects working Armin and Samuele realized that the StdObjSpace +multimethod mechanism now desparately needs refactoring. Thus the current +"long" support is just another hack (TM) which nevertheless allows to execute +more of CPython's regression tests. + +In a releated effort, Samuele and yours truly made introspection of +frames, functions and code objects compatible to CPython so that the +"dis.dis(dis.dis)" goal finally works i.e can be run through +PyPy/StdObjSpace. This is done by the so called pypy\_ protocol which +an object space uses to delegate operations on core execution objects +(functions, frames, code ...) back to the interpreter. + +redefining our standard type system at application level +-------------------------------------------------------- + +Originally we thought that we could more or less easily redefine the python +type objects at application level and let them access interpreter level +objects and implementations via some hook. This turned out to be a +bootstrapping nightmare (e.g. in order to instantiate classes you need +type objects already but actually we want our first classes to define +exactly those). While each particular problem could be worked around +somehow Armin and Samuele realized they were opening a big can of worms ... +and couldn't close it in due time. + +The good news is that after lots of discussions and tossing ideas around +we managed to develop a new approach (see the end of the report) which +raised our hopes we can finally define the types at application level +and thus get rid of the ugly and hard to understand interpreter level +implementation. + +Improving tracing and debugging of PyPy +--------------------------------------- + +With PyPy you often get long tracebacks and other problems which make +it hard to debug sometimes. Richard Emslie, Tomek Meka and me implemented +a new Object Space called "TraceObjSpace" which can wrap the Trivial and +Standard Object Space and will trace all objectspace operations as well as +frame creation into a long list of events. Richard then in a nightly hotel +session wrote "tool/traceinteractive.py" which will nicely reveal +what is going on if you execute python statements: which frames are created +which bytecodes are executed and what object space operations are involved. +Just execute traceinteractive.py (with python 2.3) and type some random function +definition and see PyPy's internals at work ... It only works with python 2.3 +because we had to rewrite python's dis-module module to allow programmatic access +to dissassembling byte codes. And this module has considerably changed +from python 2.2 to 2.3 (thanks, Michael :-) + +"finishing" the Annotation refactoring +-------------------------------------- + +That should be easy, right? Actually Guido van Rossum and Armin had +started doing type inference/annotation in Belgium just before +EuroPython and we have since refactored it already at the Berlin sprint +and in between the sprints several times. But it turned out that +Annotations as we did them are *utterly broken* in that we try to do a +too general system (we had been talking about general inference engines +and such) thus making "merging" of two annotations very hard to do in +a meaningful way. But after beeing completly crushed on one afternoon, Samuele +and Armin came up with a new *simpler* approach that ... worked and +promises to not have the same flaws. It got integrated into the +translator already and appears to work nicely. + +I think this is the fourth refactoring of just "three files" and, of course, we +already have the 'XXX' virus spreading again :-) + +refactoring/rewriting the test framework +---------------------------------------- + +PyPy has an ever increasing test-suite which requires a lot of flexibility +that the standard unittest.py module just doesn't provide. Currently, we have +in tool/test.py and interpreter/unittest_w.py a collection of more or less +weird hacks to make our (now over 500) tests run either at interpreter level +or at application level which means they are actually interpreted by PyPy. +Tests from both levels can moreover be run with different object spaces. +Thus Stefan Schwarzer and me came up with a rewrite of unittest.py which +is currently in 'newtest.py'. During my train ride back to germany i +experimentally used our new approach which let our tests run +around 30% faster (!) as a side effect. More about this in separate mails +as this is - as almost every other area of PyPy - refactoring-in-progress. + +Documentation afternoon +----------------------- + +We (apart from Richard who had a good excuse :-) also managed on Friday +to devote a full afternoon to documentation. There is now an emerging +"architecture" document, a "howtopypy" (getting started) and a "goals" +document here: + + http://codespeak.net/pypy/index.cgi?doc + +Moreover, we deleted misleading or redundant wiki-pages. In case you miss +one of them you can still access them through the web by following +"Info on this page" and "revision history". + +We also had a small lecture from Theo de Ridder who dived into +our flowgraph and came up with some traditional descriptions from +compiler theory to describe what we are doing. He also inspired us with +some other nice ideas and we certainly hope he revisits the projects +and continues to try to use it for his own purposes. + +There of course is no question that we still need more higher +level documentation. Please don't use the wiki for serious +documentation but make ReST-files in the doc-subtree. I guess +that we will make the "documentation afternoon" a permanent +event on our sprints. + +Towards more applevel code ... +------------------------------ + +As mentioned before the approach of defining the python types at +application level didn't work out as easy as hoped for. But luckily, we +had - again in some pub - the rescuing idea: a general mechanism that +lets us trigger "exec/eval" of arbitrary interpreter level code given +as a string. Of course this by itself is far too dynamic to be +translatable but remember: we can perform *arbitrarily dynamic* pythonic +tricks while still *initializing* object spaces and the interpreter. +Translation will start with executing the initialized interpreter/objspace +through another interpreter/flowobjspace instance. + +Some hacking on the last day showed that this new approach makes the +definition of "builtin" modules a lot more pythonic: modules are not +complicated class instances anymore but really look like a normal module +with some "interpreter level escapes". It appears now that in combination +with some other considerations we will finally get to "types.py" defining +the python types thus getting rid of the cumbersome 10-12 type.py files +in objspace/std. There are still some XXX's to fight, though. + +Participants +------------ + + Patrick Maupin + + Richard Emslie + + Stefan Schwarzer + + Theo de Ridder + + Alex Martelli + + Laura Creighton + + Jacob Hallen + + Tomek Meka + + Armin Rigo + + Guenter Jantzen + + Samuele Pedronis + + Holger Krekel + +and Etienne Posthumus who made our Amsterdam Sprint possible. + +outlook, what comes next? +------------------------- + +On the Amsterdam sprint maybe more than ever we realized how strongly +refactoring is the key development activity in PyPy. Watch those "XXX" :-) +Some would argue that we should instead think more about what we are doing +but then you wouldn't call that extreme programming, would you? + +However, we haven't fixed a site and date for the next sprint, yet. We would +like to do it sometime February in Suitzerland on some nice mountain but there hasn't +emerged a nice facility, yet. Later in the year we might be able to do a +sprint in Dublin and of course one right before EuroPython in Sweden. +Btw, if someone want to offer helping to organize a sprint feel free +to contact us. + +Also there was some talk on IRC that we might do a "virtual sprint" so +that our non-european developers can more easily participate. This would +probably mean doing screen-sessions and using some Voice-over-IP +technology ... we'll see what will eventually evolve. After all, we +might also soon get information from the EU regarding our recent +proposal which should make sprint planning easier in the long run. +We'll see. + +For now i wish everyone some nice last days of the year which has +been a fun one regarding our ongoing pypy adventure ... + +cheers, + + holger (who hopes he hasn't forgotten someone or something ...) + From hpk at codespeak.net Fri Jul 2 21:17:41 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Jul 2004 21:17:41 +0200 (MEST) Subject: [pypy-svn] r5424 - pypy/trunk/doc Message-ID: <20040702191741.7459F5B3DF@thoth.codespeak.net> Author: hpk Date: Fri Jul 2 21:17:40 2004 New Revision: 5424 Modified: pypy/trunk/doc/index.txt Log: small fix to trigger rebuilding the rest-files Modified: pypy/trunk/doc/index.txt ============================================================================== --- pypy/trunk/doc/index.txt (original) +++ pypy/trunk/doc/index.txt Fri Jul 2 21:17:40 2004 @@ -1,7 +1,12 @@ Pypy Documentation ================== -We have a fair amount of documentation for the Pypy project. The files are available from the website as html (view them along the left side of the pypy doc web-page). They are also available from the repository, under the *doc/* directory or under the *doc/devel* sub-directory. Or, to catch up on what we've been up to lately, just peek at the recently-modified_ documents page. +We have a fair amount of documentation for the Pypy project. The files +are available from the website as html (view them along the left side of +the pypy-doc webpage). They are also available from the repository, +under the *doc/* directory or under the *doc/devel* sub-directory. Or, +to catch up on what we've been up to lately, just peek at the +recently-modified_ documents page. Overview -------- @@ -103,4 +108,4 @@ .. _PyPy-IronPython: http://codespeak.net/pipermail/pypy-dev/2003q4/002474.html .. _IronPython: http://www.python.org/pycon/dc2004/papers/9/ .. _pliant: http://codespeak.net/pipermail/pypy-dev/2003q4/002395.html -.. _recently-modified: http://codespeak.net/pypy/index.cgi?doc/recent \ No newline at end of file +.. _recently-modified: http://codespeak.net/pypy/index.cgi?doc/recent From hpk at codespeak.net Fri Jul 2 21:21:58 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 2 Jul 2004 21:21:58 +0200 (MEST) Subject: [pypy-svn] r5425 - pypy/trunk/doc/sprintinfo Message-ID: <20040702192158.52FA25B3DF@thoth.codespeak.net> Author: hpk Date: Fri Jul 2 21:21:57 2004 New Revision: 5425 Modified: pypy/trunk/doc/sprintinfo/AmsterdamReport.txt Log: fix the year Modified: pypy/trunk/doc/sprintinfo/AmsterdamReport.txt ============================================================================== --- pypy/trunk/doc/sprintinfo/AmsterdamReport.txt (original) +++ pypy/trunk/doc/sprintinfo/AmsterdamReport.txt Fri Jul 2 21:21:57 2004 @@ -1,5 +1,5 @@ -Amsterdam Sprint 14-21 Dec. 2004 +Amsterdam Sprint 14-21 Dec. 2003 -------------------------------- Here is a mail-report from Holger Krekel sent to pypy-dev. From lac at codespeak.net Sat Jul 3 13:36:50 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 3 Jul 2004 13:36:50 +0200 (MEST) Subject: [pypy-svn] r5426 - pypy/trunk/src/pypy/tool Message-ID: <20040703113650.D2C145A183@thoth.codespeak.net> Author: lac Date: Sat Jul 3 13:36:49 2004 New Revision: 5426 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: 8 retunr locations for a function that almost fits on one screen is too many. I knew I could get it down to something a little more reasonable... Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Sat Jul 3 13:36:49 2004 @@ -66,79 +66,60 @@ def rewrite_utest(block): '''rewrite every block to use the new utest functions''' - '''This is the code that actually knows the format of the old - and new unittests. The rewriting rules are picky with when - to add spaces, and commas, so there are unfortunately 8 exit - paths, all some form of 'return indent + new + string + trailer' - + '''returns the rewritten unittest, unless it ran into problems, + in which case it just returns the block unchanged. ''' utest = old_names.match(block) - if not utest: # just copy uninteresting blocks that don't begin a utest + if not utest: return block - else: # we have an interesting block - old = utest.group(0).lstrip()[5:-1] - # old - the name we want to replace -- between the 'self.' and the '(' - - # d is the dictionary of unittest changes, keyed to the old name - # used by unittest. - # d[old][0] is the new replacement function. - # d[old][1] is the operator you will use , or '' if there is none. - # d[old][2] is the possible number of arguments to the unittest - # function. - - new = d[old][0] - op = d[old][1] - possible_args = d[old][2] + old = utest.group(0).lstrip()[5:-1] # the name we want to replace + new = d[old][0] # the name of the replacement function + op = d[old][1] # the operator you will use , or '' if there is none. + possible_args = d[old][2] # a list of the number of arguments the + # unittest function could possibly take. - if new == 'raises': # just rename assertRaises & friends - return re.sub('self.'+old, new, block) - else: - message_pos = possible_args[-1] - # the remaining unittests can have an optional message to - # print when they fail. It is always the last argument to - # the function. + if new == 'raises': # just rename assertRaises & friends + return re.sub('self.'+old, new, block) - try: - indent, args, message, trailer = decompose_unittest( - old, block, message_pos) - except SyntaxError: # but we couldn't parse it! - return block + message_pos = possible_args[-1] + # the remaining unittests can have an optional message to print + # when they fail. It is always the last argument to the function. - # otherwise, we have a real one that we could parse. + try: + indent, args, message, trailer = decompose_unittest( + old, block, message_pos) + except SyntaxError: # but we couldn't parse it! + return block - argnum = len(args) - if message: - argnum += 1 + argnum = len(args) + if message: + argnum += 1 - if argnum not in possible_args: - # sanity check - this one isn't real either - return block + if argnum not in possible_args: + # sanity check - this one isn't real either + return block + + if argnum is 0 or (argnum is 1 and argnum is message_pos): #unittest fail() + string = '' + if message: + message = ' ' + message - if argnum is 0: # fail() - return indent + new + trailer + elif message_pos is 4: # assertAlmostEqual & friends + try: + pos = args[2].lstrip() + except IndexError: + pos = '7' # default if none is specified + string = '(%s -%s, %s)%s 0' % (args[0], args[1], pos, op ) - elif argnum is 1 and argnum is message_pos: # fail('unhappy message') - return indent + new + ', ' + message + trailer + else: # assert_, assertEquals and all the rest + string = ' ' + op.join(args) - elif message_pos is 4: # assertAlmostEqual and friends - try: - pos = args[2].lstrip() - except IndexError: - pos = '7' # default if none is specified - string = '(' + args[0] + ' -' + args[1] + ', ' + pos + ')' - string += op + ' 0' - if message: - string = string + ',' + message - return indent + new + string + trailer - - else: #assert_, assertEquals and all the rest - string = op.join(args) - if message: - string = string + ',' + message + if message: + string = string + ',' + message - return indent + new + ' ' + string + trailer + return indent + new + string + trailer def decompose_unittest(old, block, message_pos): '''decompose the block into its component parts''' @@ -173,16 +154,16 @@ # begins, you will need another set of parens, (or a backslash). if arglist: - newl = [] - for arg in arglist: + for i in range(len(arglist)): try: - parser.expr(arg.lstrip('\t ')) + parser.expr(arglist[i].lstrip('\t ')) # Again we want to enclose things that happen to have # a linebreak just before the new arg. except SyntaxError: - arg = '(' + arg + ')' - newl.append(arg) - arglist = newl + if i == 0: + arglist[i] = '(' + arglist[i] + ')' + else: + arglist[i] = ' (' + arglist[i] + ')' return indent, arglist, message, trailer @@ -258,12 +239,12 @@ "assert func(x) # XXX") self.assertEquals(rewrite_utest( - r""" + """ self.assert_(1 + f(y) + z) # multiline, keep parentheses """ ), - r""" + """ assert (1 + f(y) + z) # multiline, keep parentheses """ @@ -317,19 +298,19 @@ """ ), r""" - assert 0 ==( + assert 0 == ( 'Run away from the snake.\n') """ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertEquals(badger + 0 + mushroom + snake, 0) """ ), - r""" + """ assert (badger + 0 + mushroom + snake) == 0 @@ -337,7 +318,7 @@ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertNotEquals(badger + 0 + mushroom + snake, @@ -345,25 +326,25 @@ - badger) """ ), - r""" + """ assert (badger + 0 + mushroom - + snake) !=( + + snake) != ( mushroom - badger) """ ) self.assertEqual(rewrite_utest( - r""" + """ self.assertEquals(badger(), mushroom() + snake(mushroom) - badger()) """ ), - r""" - assert badger() ==( + """ + assert badger() == ( mushroom() + snake(mushroom) - badger()) @@ -376,7 +357,7 @@ "assert not 0 != 0") self.assertEquals(rewrite_utest( - r""" + """ self.failUnlessEqual(mushroom() + mushroom() + mushroom(), '''badger badger badger @@ -385,7 +366,7 @@ ''') # multiline, must move the parens """ ), - r""" + """ assert not (mushroom() + mushroom() + mushroom()) != '''badger badger badger @@ -397,39 +378,39 @@ self.assertEquals(rewrite_utest( - r""" + """ self.assertEquals('''snake snake snake snake snake snake''', mushroom) """ ), - r""" + """ assert '''snake snake snake snake snake snake''' == mushroom """ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertEquals(badger(), snake(), 'BAD BADGER') """ ), - r""" - assert badger() ==( + """ + assert badger() == ( snake()), 'BAD BADGER' """ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertNotEquals(badger(), snake()+ snake(), 'POISONOUS MUSHROOM!\ Ai! I ate a POISONOUS MUSHROOM!!') """ ), - r""" - assert badger() !=( + """ + assert badger() != ( snake()+ snake()), 'POISONOUS MUSHROOM!\ Ai! I ate a POISONOUS MUSHROOM!!' @@ -437,7 +418,7 @@ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertEquals(badger(), snake(), '''BAD BADGER BAD BADGER @@ -445,8 +426,8 @@ ) """ ), - r""" - assert badger() ==( + """ + assert badger() == ( snake()), '''BAD BADGER BAD BADGER BAD BADGER''' @@ -455,7 +436,7 @@ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertEquals('''BAD BADGER BAD BADGER BAD BADGER''', '''BAD BADGER @@ -463,7 +444,7 @@ BAD BADGER''') """ ), - r""" + """ assert '''BAD BADGER BAD BADGER BAD BADGER''' == '''BAD BADGER @@ -473,7 +454,7 @@ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertEquals('''GOOD MUSHROOM GOOD MUSHROOM GOOD MUSHROOM''', @@ -485,10 +466,10 @@ FAILURE''') """ ), - r""" + """ assert '''GOOD MUSHROOM GOOD MUSHROOM - GOOD MUSHROOM''' ==( + GOOD MUSHROOM''' == ( '''GOOD MUSHROOM GOOD MUSHROOM GOOD MUSHROOM'''),( @@ -499,43 +480,43 @@ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertAlmostEquals(first, second, 5, 'A Snake!') """ ), - r""" + """ assert round(first - second, 5) == 0, 'A Snake!' """ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertAlmostEquals(first, second, 120) """ ), - r""" + """ assert round(first - second, 120) == 0 """ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertAlmostEquals(first, second) """ ), - r""" + """ assert round(first - second, 7) == 0 """ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertAlmostEqual(first, second, 5, '''A Snake! Ohh A Snake! A Snake!! ''') """ ), - r""" + """ assert round(first - second, 5) == 0, '''A Snake! Ohh A Snake! A Snake!! ''' @@ -543,54 +524,54 @@ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertNotAlmostEqual(first, second, 5, 'A Snake!') """ ), - r""" + """ assert round(first - second, 5) != 0, 'A Snake!' """ ) self.assertEquals(rewrite_utest( - r""" + """ self.failIfAlmostEqual(first, second, 5, 'A Snake!') """ ), - r""" + """ assert not round(first - second, 5) == 0, 'A Snake!' """ ) self.assertEquals(rewrite_utest( - r""" + """ self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ ), - r""" + """ self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ ) self.assertEquals(rewrite_utest( - r""" + """ self.failUnlessAlmostEquals(first, second, 5, 'A Snake!') """ ), - r""" + """ assert not round(first - second, 5) != 0, 'A Snake!' """ ) self.assertEquals(rewrite_utest( - r""" + """ self.assertAlmostEquals(now do something reasonable ..() oops, I am inside a comment as a ''' string, and the fname was mentioned in passing, leaving us with something that isn't an expression ... will this blow up? """ ), - r""" + """ self.assertAlmostEquals(now do something reasonable ..() oops, I am inside a comment as a ''' string, and the fname was mentioned in passing, leaving us with something that isn't an @@ -601,6 +582,15 @@ if __name__ == '__main__': unittest.main() - #for block in blocksplitter('xxx.py'): print rewrite_utest(block) + '''count = 1 + for block in blocksplitter('xxx.py'): + print 'START BLOCK', count + print rewrite_utest(block) + print 'END BLOCK', count + print + print + count +=1 + ''' +#for block in blocksplitter('xxx.py'): print rewrite_utest(block) From sanxiyn at codespeak.net Sat Jul 3 14:46:26 2004 From: sanxiyn at codespeak.net (sanxiyn at codespeak.net) Date: Sat, 3 Jul 2004 14:46:26 +0200 (MEST) Subject: [pypy-svn] r5427 - pypy/trunk/src/pypy/appspace Message-ID: <20040703124626.1E0A05A183@thoth.codespeak.net> Author: sanxiyn Date: Sat Jul 3 14:46:25 2004 New Revision: 5427 Removed: pypy/trunk/src/pypy/appspace/pprint.py Log: Remove no more needed pprint.py. Deleted: /pypy/trunk/src/pypy/appspace/pprint.py ============================================================================== --- /pypy/trunk/src/pypy/appspace/pprint.py Sat Jul 3 14:46:25 2004 +++ (empty file) @@ -1,310 +0,0 @@ -# Copied from CPython 2.3 - -# Author: Fred L. Drake, Jr. -# fdrake at acm.org -# -# This is a simple little module I wrote to make life easier. I didn't -# see anything quite like it in the library, though I may have overlooked -# something. I wrote this when I was trying to read some heavily nested -# tuples with fairly non-descriptive content. This is modeled very much -# after Lisp/Scheme - style pretty-printing of lists. If you find it -# useful, thank small children who sleep at night. - -"""Support to pretty-print lists, tuples, & dictionaries recursively. - -Very simple, but useful, especially in debugging data structures. - -Classes -------- - -PrettyPrinter() - Handle pretty-printing operations onto a stream using a configured - set of formatting parameters. - -Functions ---------- - -pformat() - Format a Python object into a pretty-printed representation. - -pprint() - Pretty-print a Python object to a stream [default is sys.sydout]. - -saferepr() - Generate a 'standard' repr()-like value, but protect against recursive - data structures. - -""" - -import sys as _sys - -from cStringIO import StringIO as _StringIO - -__all__ = ["pprint","pformat","isreadable","isrecursive","saferepr", - "PrettyPrinter"] - -# cache these for faster access: -_commajoin = ", ".join -_id = id -_len = len -_type = type - -def pprint(object, stream=None): - """Pretty-print a Python object to a stream [default is sys.sydout].""" - printer = PrettyPrinter(stream=stream) - printer.pprint(object) - -def pformat(object): - """Format a Python object into a pretty-printed representation.""" - return PrettyPrinter().pformat(object) - -def saferepr(object): - """Version of repr() which can handle recursive data structures.""" - return _safe_repr(object, {}, None, 0)[0] - -def isreadable(object): - """Determine if saferepr(object) is readable by eval().""" - return _safe_repr(object, {}, None, 0)[1] - -def isrecursive(object): - """Determine if object requires a recursive representation.""" - return _safe_repr(object, {}, None, 0)[2] - -class PrettyPrinter: - def __init__(self, indent=1, width=80, depth=None, stream=None): - """Handle pretty printing operations onto a stream using a set of - configured parameters. - - indent - Number of spaces to indent for each level of nesting. - - width - Attempted maximum number of columns in the output. - - depth - The maximum depth to print out nested structures. - - stream - The desired output stream. If omitted (or false), the standard - output stream available at construction will be used. - - """ - indent = int(indent) - width = int(width) - assert indent >= 0 - assert depth is None or depth > 0, "depth must be > 0" - assert width - self._depth = depth - self._indent_per_level = indent - self._width = width - if stream is not None: - self._stream = stream - else: - self._stream = _sys.stdout - - def pprint(self, object): - self._stream.write(self.pformat(object) + "\n") - - def pformat(self, object): - sio = _StringIO() - self._format(object, sio, 0, 0, {}, 0) - return sio.getvalue() - - def isrecursive(self, object): - return self.format(object, {}, 0, 0)[2] - - def isreadable(self, object): - s, readable, recursive = self.format(object, {}, 0, 0) - return readable and not recursive - - def _format(self, object, stream, indent, allowance, context, level): - level = level + 1 - objid = _id(object) - if objid in context: - stream.write(_recursion(object)) - self._recursive = True - self._readable = False - return - rep = self._repr(object, context, level - 1) - typ = _type(object) - sepLines = _len(rep) > (self._width - 1 - indent - allowance) - write = stream.write - - if sepLines: - if typ is dict: - write('{') - if self._indent_per_level > 1: - write((self._indent_per_level - 1) * ' ') - length = _len(object) - if length: - context[objid] = 1 - indent = indent + self._indent_per_level - items = object.items() - items.sort() - key, ent = items[0] - rep = self._repr(key, context, level) - write(rep) - write(': ') - self._format(ent, stream, indent + _len(rep) + 2, - allowance + 1, context, level) - if length > 1: - for key, ent in items[1:]: - rep = self._repr(key, context, level) - write(',\n%s%s: ' % (' '*indent, rep)) - self._format(ent, stream, indent + _len(rep) + 2, - allowance + 1, context, level) - indent = indent - self._indent_per_level - del context[objid] - write('}') - return - - if typ is list or typ is tuple: - if typ is list: - write('[') - endchar = ']' - else: - write('(') - endchar = ')' - if self._indent_per_level > 1: - write((self._indent_per_level - 1) * ' ') - length = _len(object) - if length: - context[objid] = 1 - indent = indent + self._indent_per_level - self._format(object[0], stream, indent, allowance + 1, - context, level) - if length > 1: - for ent in object[1:]: - write(',\n' + ' '*indent) - self._format(ent, stream, indent, - allowance + 1, context, level) - indent = indent - self._indent_per_level - del context[objid] - if typ is tuple and length == 1: - write(',') - write(endchar) - return - - write(rep) - - def _repr(self, object, context, level): - repr, readable, recursive = self.format(object, context.copy(), - self._depth, level) - if not readable: - self._readable = False - if recursive: - self._recursive = True - return repr - - def format(self, object, context, maxlevels, level): - """Format object for a specific context, returning a string - and flags indicating whether the representation is 'readable' - and whether the object represents a recursive construct. - """ - return _safe_repr(object, context, maxlevels, level) - - -# Return triple (repr_string, isreadable, isrecursive). - -def _safe_repr(object, context, maxlevels, level): - typ = _type(object) - if typ is str: - if 'locale' not in _sys.modules: - return `object`, True, False - if "'" in object and '"' not in object: - closure = '"' - quotes = {'"': '\\"'} - else: - closure = "'" - quotes = {"'": "\\'"} - qget = quotes.get - sio = _StringIO() - write = sio.write - for char in object: - if char.isalpha(): - write(char) - else: - write(qget(char, `char`[1:-1])) - return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False - - if typ is dict: - if not object: - return "{}", True, False - objid = _id(object) - if maxlevels and level > maxlevels: - return "{...}", False, objid in context - if objid in context: - return _recursion(object), False, True - context[objid] = 1 - readable = True - recursive = False - components = [] - append = components.append - level += 1 - saferepr = _safe_repr - for k, v in object.iteritems(): - krepr, kreadable, krecur = saferepr(k, context, maxlevels, level) - vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level) - append("%s: %s" % (krepr, vrepr)) - readable = readable and kreadable and vreadable - if krecur or vrecur: - recursive = True - del context[objid] - return "{%s}" % _commajoin(components), readable, recursive - - if typ is list or typ is tuple: - if typ is list: - if not object: - return "[]", True, False - format = "[%s]" - elif _len(object) == 1: - format = "(%s,)" - else: - if not object: - return "()", True, False - format = "(%s)" - objid = _id(object) - if maxlevels and level > maxlevels: - return format % "...", False, objid in context - if objid in context: - return _recursion(object), False, True - context[objid] = 1 - readable = True - recursive = False - components = [] - append = components.append - level += 1 - for o in object: - orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level) - append(orepr) - if not oreadable: - readable = False - if orecur: - recursive = True - del context[objid] - return format % _commajoin(components), readable, recursive - - rep = `object` - return rep, (rep and not rep.startswith('<')), False - - -def _recursion(object): - return ("" - % (_type(object).__name__, _id(object))) - - -def _perfcheck(object=None): - import time - if object is None: - object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000 - p = PrettyPrinter() - t1 = time.time() - _safe_repr(object, {}, None, 0) - t2 = time.time() - p.pformat(object) - t3 = time.time() - print "_safe_repr:", t2 - t1 - print "pformat:", t3 - t2 - -if __name__ == "__main__": - _perfcheck() From sanxiyn at codespeak.net Sat Jul 3 15:05:39 2004 From: sanxiyn at codespeak.net (sanxiyn at codespeak.net) Date: Sat, 3 Jul 2004 15:05:39 +0200 (MEST) Subject: [pypy-svn] r5428 - pypy/trunk/src/pypy/module Message-ID: <20040703130539.65D0B5A183@thoth.codespeak.net> Author: sanxiyn Date: Sat Jul 3 15:05:38 2004 New Revision: 5428 Modified: pypy/trunk/src/pypy/module/sysinterp.py pypy/trunk/src/pypy/module/sysmodule.py Log: Trying to run "import encodings". Doesn't work yet. (Built-in function _codecs.register refuses to accept PyPy-wrapped function.) Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Sat Jul 3 15:05:38 2004 @@ -38,7 +38,7 @@ # The following built-in modules are not written in PyPy, so we # steal them from Python. for fn in ['posix', 'nt', 'os2', 'mac', 'ce', 'riscos', - 'itertools', 'math', + 'itertools', 'math', '_codecs', '_random', '_sre', 'time', '_socket', 'errno', 'marshal', 'struct', 'binascii', 'parser']: if fn not in builtin_modules: @@ -69,6 +69,7 @@ w_hexversion = space.wrap(cpy_sys.hexversion) w_platform = space.wrap(cpy_sys.platform) w_maxint = space.wrap(cpy_sys.maxint) +w_byteorder = space.wrap(cpy_sys.byteorder) w_stdin = space.wrap(cpy_sys.stdin) w_stdout = space.wrap(cpy_sys.stdout) Modified: pypy/trunk/src/pypy/module/sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/sysmodule.py (original) +++ pypy/trunk/src/pypy/module/sysmodule.py Sat Jul 3 15:05:38 2004 @@ -11,7 +11,7 @@ # Objects from interpreter-level from __interplevel__ import stdin, stdout, stderr, maxint -from __interplevel__ import hexversion, platform +from __interplevel__ import hexversion, platform, byteorder from __interplevel__ import pypy_objspaceclass # Functions from interpreter-level From sanxiyn at codespeak.net Sat Jul 3 15:47:56 2004 From: sanxiyn at codespeak.net (sanxiyn at codespeak.net) Date: Sat, 3 Jul 2004 15:47:56 +0200 (MEST) Subject: [pypy-svn] r5429 - pypy/trunk/src/goal Message-ID: <20040703134756.032AA5A183@thoth.codespeak.net> Author: sanxiyn Date: Sat Jul 3 15:47:56 2004 New Revision: 5429 Modified: pypy/trunk/src/goal/pydoc-pregoal.py Log: Remove os.error hack. Takes ~2 minutes to finish on StdObjSpace(r5428). Modified: pypy/trunk/src/goal/pydoc-pregoal.py ============================================================================== --- pypy/trunk/src/goal/pydoc-pregoal.py (original) +++ pypy/trunk/src/goal/pydoc-pregoal.py Sat Jul 3 15:47:56 2004 @@ -1,3 +1 @@ -import os -os.error = OSError import pydoc From sanxiyn at codespeak.net Sun Jul 4 13:46:27 2004 From: sanxiyn at codespeak.net (sanxiyn at codespeak.net) Date: Sun, 4 Jul 2004 13:46:27 +0200 (MEST) Subject: [pypy-svn] r5430 - pypy/trunk/src/pypy/module Message-ID: <20040704114627.958495AC80@thoth.codespeak.net> Author: sanxiyn Date: Sun Jul 4 13:46:26 2004 New Revision: 5430 Modified: pypy/trunk/src/pypy/module/sysinterp.py Log: More borrowing. "import urllib2" works. Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Sun Jul 4 13:46:26 2004 @@ -38,7 +38,7 @@ # The following built-in modules are not written in PyPy, so we # steal them from Python. for fn in ['posix', 'nt', 'os2', 'mac', 'ce', 'riscos', - 'itertools', 'math', '_codecs', + 'itertools', 'math', '_codecs', 'md5', 'sha', '_random', '_sre', 'time', '_socket', 'errno', 'marshal', 'struct', 'binascii', 'parser']: if fn not in builtin_modules: From hpk at codespeak.net Mon Jul 5 11:54:32 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jul 2004 11:54:32 +0200 (MEST) Subject: [pypy-svn] r5432 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040705095432.59A2D5AF46@thoth.codespeak.net> Author: hpk Date: Mon Jul 5 11:54:31 2004 New Revision: 5432 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: Ben Young's test and implementation of zero-padding for string-formatting Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Mon Jul 5 11:54:31 2004 @@ -991,9 +991,16 @@ else: width = None prec = None + lpadchar = ' ' + padzeros = False + seennum = False if c in '-0123456789': j = i while format[j] in '-0123456789': + if format[j] in '0123456789' and not seennum: + seennum = True + if format[j] == '0': + padzeros = True j += 1 if format[i:j] != '-': width = int(format[i:j]) @@ -1050,6 +1057,10 @@ else: raise ValueError, "unsupported format character '%s' (%x) at index %d" % ( c, ord(c), i) + + if c in 'xdg' and padzeros: + lpadchar = '0' + if prec is not None: pieces[-1] = pieces[-1][:prec] if width is not None: @@ -1059,7 +1070,7 @@ p = p + ' '*d else: d = max(width - len(p), 0) - p = ' '*d + p + p = lpadchar*d + p pieces[-1] = p state = 0 start = i+1 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Mon Jul 5 11:54:31 2004 @@ -1,6 +1,14 @@ import autopath from pypy.tool import testit + def test_zero_pad(self): + self.assertEquals("%02d"%1, "01") + self.assertEquals("%05d"%1, "00001") + self.assertEquals("%-05d"%1, "1 ") + self.assertEquals("%04f"%2.3, "2.300000") + self.assertEquals("%04g"%2.3, "02.3") + self.assertEquals("%-04g"%2.3,"2.3 ") + self.assertEquals("%04s"%2.3, " 2.3") class TestStringObjectWithDict(testit.AppTestCase): From hpk at codespeak.net Mon Jul 5 12:22:43 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 5 Jul 2004 12:22:43 +0200 (MEST) Subject: [pypy-svn] r5433 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040705102243.7F9DA5AF46@thoth.codespeak.net> Author: hpk Date: Mon Jul 5 12:22:42 2004 New Revision: 5433 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: moved the test function to its right place Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Mon Jul 5 12:22:42 2004 @@ -1,15 +1,6 @@ import autopath from pypy.tool import testit - def test_zero_pad(self): - self.assertEquals("%02d"%1, "01") - self.assertEquals("%05d"%1, "00001") - self.assertEquals("%-05d"%1, "1 ") - self.assertEquals("%04f"%2.3, "2.300000") - self.assertEquals("%04g"%2.3, "02.3") - self.assertEquals("%-04g"%2.3,"2.3 ") - self.assertEquals("%04s"%2.3, " 2.3") - class TestStringObjectWithDict(testit.AppTestCase): def setUp(self): @@ -112,6 +103,16 @@ self.assertEquals("%5.3s"%'abcde', ' abc') self.assertEquals("%-5.3s"%'a', 'a ') self.assertEquals("%-5.3s"%'abcde', 'abc ') + + def test_zero_pad(self): + self.assertEquals("%02d"%1, "01") + self.assertEquals("%05d"%1, "00001") + self.assertEquals("%-05d"%1, "1 ") + self.assertEquals("%04f"%2.3, "2.300000") + self.assertEquals("%04g"%2.3, "02.3") + self.assertEquals("%-04g"%2.3,"2.3 ") + self.assertEquals("%04s"%2.3, " 2.3") + if __name__ == '__main__': From mwh at codespeak.net Mon Jul 5 15:33:24 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 5 Jul 2004 15:33:24 +0200 (MEST) Subject: [pypy-svn] r5434 - in pypy/trunk/src/pypy: appspace objspace/std objspace/std/test Message-ID: <20040705133324.A49FA5AF46@thoth.codespeak.net> Author: mwh Date: Mon Jul 5 15:33:24 2004 New Revision: 5434 Added: pypy/trunk/src/pypy/appspace/_formatting.py Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: redo string formatting. this makes some of the tests pass which didn't before! Added: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/_formatting.py Mon Jul 5 15:33:24 2004 @@ -0,0 +1,209 @@ +class _Flags(object): + def __repr__(self): + return "<%s>"%(', '.join([f for f in self.__dict__ + if f[0] == 'f' and getattr(self, f)]),) + f_ljust = 0 + f_sign = 0 + f_blank = 0 + f_alt = 0 + f_zero = 0 + +def value_next(valueiter): + try: + return valueiter.next() + except StopIteration: + raise TypeError('not enough arguments for format string') + + +def peel_num(c, fmtiter, valueiter): + if c == '*': + v = value_next(valueiter) + if not isinstance(v, int): + raise TypeError, "* wants int" + return fmtiter.next(), v + n = '' + while c in '0123456789': + n += c + c = fmtiter.next() + if n: + return c, int(n) + else: + return c, 0 + +def peel_flags(c, fmtiter): + flags = _Flags() + while 1: + if c == '-': + flags.f_ljust = True + elif c == '+': + flags.f_sign = True + elif c == ' ': + flags.f_blank = True + elif c == '#': + flags.f_alt = True + elif c == '0': + flags.f_zero = True + else: + break + c = fmtiter.next() + return c, flags + +def parse_fmt(fmtiter, valueiter, valuedict): + """return (char, flags, width, prec, value) + partially consumes fmtiter & valueiter""" + c = fmtiter.next() + gotvalue = False + if c == '(': + n = '' + pcount = 1 + while 1: + c = fmtiter.next() + if c == ')': + pcount -= 1 + if pcount == 0: + break + elif c == '(': + pcount += 1 + n += c + value = valuedict[n] + gotvalue = True + c = fmtiter.next() + c, flags = peel_flags(c, fmtiter) + c, width = peel_num(c, fmtiter, valueiter) + if c == '.': + c, prec = peel_num(fmtiter.next(), fmtiter, valueiter) + else: + prec = None + if c in 'hlL': + c = fmtiter.next() + if width and width < 0: + # this can happen with *-args + flags.f_ljust = True + width = -width + if not gotvalue: + if c == '%': + # did YOU realize that "%4%"%() == ' %'?? + value = '%' + c = 's' + else: + value = value_next(valueiter) + return (c, flags, width, prec, value) + +class Formatter(object): + def __init__(self, char, flags, width, prec, value): + self.char = char + self.flags = flags + self.width = width + self.prec = prec + self.value = value + + def format(self): + raise NotImplementedError + + def std_wp(self, r): + padchar = ' ' + if self.flags.f_zero and self.char in 'iduoxXeEfFgG': + padchar = '0' + + if self.prec is not None: + r = r[:self.prec] + if self.width is not None: + p = self.width - len(r) + if self.flags.f_ljust: + r = r + ' '*p + else: + r = padchar*p + r + return r + +def funcFormatter(*funcs): + class _F(Formatter): + def format(self): + r = self.value + for f in funcs: + r = f(r) + return self.std_wp(r) + return _F + +def maybe_int(value): + try: + inter = value.__int__ + except AttributeError: + raise TypeError, "an integer argument is required" + return inter() + +class floatFFormatter(Formatter): + def format(self): + if self.prec is None: + self.prec = 6 + r = str(int(self.value)) + # XXX this is a bit horrid + if self.prec > 0: + frac_part = str(self.value%1)[1:2+self.prec] + if len(frac_part) < self.prec + 1: + frac_part += (1 + self.prec - len(frac_part)) * '0' + r += frac_part + self.prec = None + return self.std_wp(r) + +format_registry = { + 's':funcFormatter(str), + 'r':funcFormatter(repr), + 'x':funcFormatter(maybe_int, hex), + 'X':funcFormatter(maybe_int, hex, lambda r:r.upper()), + 'd':funcFormatter(maybe_int, str), + 'f':floatFFormatter, + 'g':funcFormatter(str), + } + +class FmtIter(object): + def __init__(self, fmt): + self.fmt = fmt + self.i = 0 + def __iter__(self): + return self + def next(self): + try: + c = self.fmt[self.i] + except IndexError: + raise StopIteration + self.i += 1 + return c + def skip_to_fmt(self): + i = self.i + j = self.fmt.find('%', i) + if j < 0: + self.i = len(self.fmt) + return self.fmt[i:] + else: + self.i = j + return self.fmt[i:j] + +def format(fmt, values, valuedict=None): + fmtiter = FmtIter(fmt) + valueiter = iter(values) + r = [] + try: + for c in fmtiter: + if c == '%': + t = parse_fmt(fmtiter, valueiter, valuedict) + try: + f = format_registry[t[0]] + except KeyError: + raise ValueError("unsupported format character " + "'%s' (%x) at index %d" + %(t[0], ord(t[0]), fmtiter.i)) + r.append(f(*t).format()) + else: + # efficiency hack: + r.append(c + fmtiter.skip_to_fmt()) + except StopIteration: + raise ValueError, "incomplete format" + try: + valueiter.next() + except StopIteration: + pass + else: + raise TypeError('not all arguments converted ' + 'during string formatting') + return ''.join(r) + Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Mon Jul 5 15:33:24 2004 @@ -2,6 +2,9 @@ """ stringobject.py +this is here: + to not confuse python-mode + Synopsis of implemented methods (* marks work in progress) Py PyPy @@ -968,120 +971,15 @@ def ord__String(space, w_str): return space.wrap(ord(space.unwrap(w_str))) -def mod__String_ANY(space, w_str, w_item): - return mod__String_Tuple(space, w_str, space.newtuple([w_item])) - def app_mod__String_ANY(format, values): - pieces = [] - start = 0 - state = 0 - i = 0 - index = -1 - len_format = len(format) - while i < len_format: - c = format[i] - if state == 0: - # just copy constant-pieces of the format - if c=='%': - pieces.append(format[start:i]) - state = 1 + import _formatting + if isinstance(values, tuple): + return _formatting.format(format, values, None) + else: + if hasattr(values, '__getitem__') and not isinstance(values, str): + return _formatting.format(format, (), values) else: - if c=='%': - pieces.append('%') - else: - width = None - prec = None - lpadchar = ' ' - padzeros = False - seennum = False - if c in '-0123456789': - j = i - while format[j] in '-0123456789': - if format[j] in '0123456789' and not seennum: - seennum = True - if format[j] == '0': - padzeros = True - j += 1 - if format[i:j] != '-': - width = int(format[i:j]) - i = j - c = format[j] - if c == '.': - i += 1 - j = i - while format[j] in '0123456789': - j += 1 - prec = int(format[i:j]) - i = j - c = format[j] - - if c == '(': - # read name - j = format.find(')', i+1) - if j == -1: - raise ValueError, "incomplete format string" - if index >= 0: - raise TypeError, "format string mismatch" - name = format[i+1:j] - value = values[name] - index = -2 - i = j+1 - c = format[i] - else: - index += 1 - if index < 0: - raise TypeError, "format string mismatch" - elif index == 0 and not isinstance(values, tuple): - values = tuple([values]) - try: - value = values[index] - except IndexError: - raise TypeError, "not enough arguments for format string" - - if c=='s': - pieces.append(str(value)) - elif c=='d': - try: - inter = value.__int__ - except AttributeError: - raise TypeError, "an integer argument is required" - pieces.append(str(inter())) - elif c=='x': - pieces.append(hex(int(value))) - elif c=='r': - pieces.append(repr(value)) - elif c=='f': - pieces.append(str(float(value))) - elif c=='g': - pieces.append(str(value)) # XXX - else: - raise ValueError, "unsupported format character '%s' (%x) at index %d" % ( - c, ord(c), i) - - if c in 'xdg' and padzeros: - lpadchar = '0' - - if prec is not None: - pieces[-1] = pieces[-1][:prec] - if width is not None: - p = pieces[-1] - if width < 0: - d = max(-width - len(p), 0) - p = p + ' '*d - else: - d = max(width - len(p), 0) - p = lpadchar*d + p - pieces[-1] = p - state = 0 - start = i+1 - i += 1 - - if state == 1: - raise ValueError, "incomplete format" - if index >= 0 and index < len(values) - 1: - raise TypeError, 'not all arguments converted during string formatting' - pieces.append(format[start:]) - return ''.join(pieces) + return _formatting.format(format, (values,), None) mod__String_ANY = gateway.app2interp(app_mod__String_ANY) Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Mon Jul 5 15:33:24 2004 @@ -86,21 +86,24 @@ def test_format_wrong_char(self): self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) + def test_incomplete_format(self): + self.assertRaises(ValueError, '%'.__mod__, ((23,),)) + class TestWidthPrec(testit.AppTestCase): def setUp(self): self.space = testit.objspace() def test_width(self): - self.assertEquals("%3s"%'a', ' a') + self.assertEquals("%3s" %'a', ' a') self.assertEquals("%-3s"%'a', 'a ') def test_prec_string(self): - self.assertEquals("%.3s"%'a', 'a') + self.assertEquals("%.3s"%'a', 'a') self.assertEquals("%.3s"%'abcde', 'abc') def test_prec_width_string(self): - self.assertEquals("%5.3s"%'a', ' a') - self.assertEquals("%5.3s"%'abcde', ' abc') + self.assertEquals("%5.3s" %'a', ' a') + self.assertEquals("%5.3s" %'abcde', ' abc') self.assertEquals("%-5.3s"%'a', 'a ') self.assertEquals("%-5.3s"%'abcde', 'abc ') @@ -114,6 +117,21 @@ self.assertEquals("%04s"%2.3, " 2.3") + def test_star_width(self): + self.assertEquals("%*s" %( 5, 'abc'), ' abc') + self.assertEquals("%*s" %(-5, 'abc'), 'abc ') + self.assertEquals("%-*s"%( 5, 'abc'), 'abc ') + self.assertEquals("%-*s"%(-5, 'abc'), 'abc ') + + def test_star_prec(self): + self.assertEquals("%.*s"%( 3, 'abc'), 'abc') + self.assertEquals("%.*s"%( 3, 'abcde'), 'abc') + self.assertEquals("%.*s"%(-3, 'abc'), '') + + def test_star_width_prec(self): + self.assertEquals("%*.*s"%( 5, 3, 'abc'), ' abc') + self.assertEquals("%*.*s"%( 5, 3, 'abcde'), ' abc') + self.assertEquals("%*.*s"%(-5, 3, 'abcde'), 'abc ') if __name__ == '__main__': testit.main() From mwh at codespeak.net Mon Jul 5 16:30:35 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 5 Jul 2004 16:30:35 +0200 (MEST) Subject: [pypy-svn] r5439 - pypy/trunk/src/pypy/interpreter/test Message-ID: <20040705143035.F2AC95AF46@thoth.codespeak.net> Author: mwh Date: Mon Jul 5 16:30:35 2004 New Revision: 5439 Modified: pypy/trunk/src/pypy/interpreter/test/test_nestedscope.py Log: fix test Modified: pypy/trunk/src/pypy/interpreter/test/test_nestedscope.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_nestedscope.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_nestedscope.py Mon Jul 5 16:30:35 2004 @@ -55,7 +55,7 @@ return g() outer_locals, inner_locals = f() self.assertEquals(inner_locals, {'i':3}) - self.assertEquals(len(outer_locals), 1, "len!=1 for %r" % outer_locals) + self.assertEquals(len(outer_locals), 1, "len!=1 for %r" % (outer_locals,)) if __name__ == '__main__': testit.main() From lac at codespeak.net Mon Jul 5 19:09:12 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Mon, 5 Jul 2004 19:09:12 +0200 (MEST) Subject: [pypy-svn] r5444 - pypy/trunk/src/pypy/tool/test Message-ID: <20040705170912.C5D2C5AF46@thoth.codespeak.net> Author: lac Date: Mon Jul 5 19:09:05 2004 New Revision: 5444 Added: pypy/trunk/src/pypy/tool/test/test_utestconvert.py pypy/trunk/src/pypy/tool/test/test_utestconvert2.py Log: In the interest of 'eating your own dogfood' here are the unittests factored out from utestconvert.py. test_utestconvert.py doesn't use unittest, but just uses asserts. test_utestconvert2.py is the same thing but uses unittest. By the way, you cannot get test_utestconvert.py by running utestconvert with input utestconvert2.py. The tests which are input to the tests, that need checking, get converted as well. :-) Added: pypy/trunk/src/pypy/tool/test/test_utestconvert.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert.py Mon Jul 5 19:09:05 2004 @@ -0,0 +1,389 @@ +import autopath +from pypy.tool.utestconvert import rewrite_utest +import unittest + +class Testit(unittest.TestCase): + def test(self): + + assert rewrite_utest("badger badger badger") == ( + "badger badger badger") + + assert rewrite_utest( + "self.assertRaises(excClass, callableObj, *args, **kwargs)") == ( + "raises(excClass, callableObj, *args, **kwargs)") + + assert rewrite_utest(""" + self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) + """) == (""" + raises(TypeError, func, 42, **{'arg1': 23}) + """ + ) + + assert rewrite_utest( + """ + self.assertRaises(TypeError, + func, + mushroom) + """ + ) == ( + """ + raises(TypeError, + func, + mushroom) + """ + ) + + assert rewrite_utest("self.fail()") == "raise AssertionError" + + assert rewrite_utest("self.fail('mushroom, mushroom')") == ( + "raise AssertionError, 'mushroom, mushroom'") + + assert rewrite_utest("self.assert_(x)") == "assert x" + + assert rewrite_utest("self.failUnless(func(x)) # XXX") == ( + "assert func(x) # XXX") + + assert rewrite_utest( + """ + self.assert_(1 + f(y) + + z) # multiline, keep parentheses + """ + ) == ( + """ + assert (1 + f(y) + + z) # multiline, keep parentheses + """ + ) + + assert rewrite_utest("self.assert_(0, 'badger badger')") == ( + "assert 0, 'badger badger'") + + assert rewrite_utest("self.assert_(0, '''badger badger''')") == ( + "assert 0, '''badger badger'''") + + assert rewrite_utest( + r""" + self.assert_(0, + 'Meet the badger.\n') + """ + ) == ( + r""" + assert 0,( + 'Meet the badger.\n') + """ + ) + + assert rewrite_utest( + r""" + self.failIf(0 + 0 + + len('badger\n') + + 0, '''badger badger badger badger + mushroom mushroom + Snake! Ooh a snake! + ''') # multiline, must move the parens + """ + ) == ( + r""" + assert not (0 + 0 + + len('badger\n') + + 0), '''badger badger badger badger + mushroom mushroom + Snake! Ooh a snake! + ''' # multiline, must move the parens + """ + ) + + assert rewrite_utest("self.assertEquals(0, 0)") == ( + "assert 0 == 0") + + assert rewrite_utest( + r""" + self.assertEquals(0, + 'Run away from the snake.\n') + """ + ) == ( + r""" + assert 0 == ( + 'Run away from the snake.\n') + """ + ) + + assert rewrite_utest( + """ + self.assertEquals(badger + 0 + + mushroom + + snake, 0) + """ + ) == ( + """ + assert (badger + 0 + + mushroom + + snake) == 0 + """ + ) + + assert rewrite_utest( + """ + self.assertNotEquals(badger + 0 + + mushroom + + snake, + mushroom + - badger) + """ + ) == ( + """ + assert (badger + 0 + + mushroom + + snake) != ( + mushroom + - badger) + """ + ) + + assert rewrite_utest( + """ + self.assertEquals(badger(), + mushroom() + + snake(mushroom) + - badger()) + """ + ) == ( + """ + assert badger() == ( + mushroom() + + snake(mushroom) + - badger()) + """ + ) + + assert rewrite_utest("self.failIfEqual(0, 0)") == ( + "assert not 0 == 0") + + assert rewrite_utest("self.failUnlessEqual(0, 0)") == ( + "assert not 0 != 0") + + assert rewrite_utest( + """ + self.failUnlessEqual(mushroom() + + mushroom() + + mushroom(), '''badger badger badger + badger badger badger badger + badger badger badger badger + ''') # multiline, must move the parens + """ + ) == ( + """ + assert not (mushroom() + + mushroom() + + mushroom()) != '''badger badger badger + badger badger badger badger + badger badger badger badger + ''' # multiline, must move the parens + """ + ) + + assert rewrite_utest( + """ + self.assertEquals('''snake snake snake + snake snake snake''', mushroom) + """ + ) == ( + """ + assert '''snake snake snake + snake snake snake''' == mushroom + """ + ) + + assert rewrite_utest( + """ + self.assertEquals(badger(), + snake(), 'BAD BADGER') + """ + ) == ( + """ + assert badger() == ( + snake()), 'BAD BADGER' + """ + ) + + assert rewrite_utest( + """ + self.assertNotEquals(badger(), + snake()+ + snake(), 'POISONOUS MUSHROOM!\ + Ai! I ate a POISONOUS MUSHROOM!!') + """ + ) == ( + """ + assert badger() != ( + snake()+ + snake()), 'POISONOUS MUSHROOM!\ + Ai! I ate a POISONOUS MUSHROOM!!' + """ + ) + + assert rewrite_utest( + """ + self.assertEquals(badger(), + snake(), '''BAD BADGER + BAD BADGER + BAD BADGER''' + ) + """ + ) == ( + """ + assert badger() == ( + snake()), '''BAD BADGER + BAD BADGER + BAD BADGER''' + + """ + ) + + assert rewrite_utest( + """ + self.assertEquals('''BAD BADGER + BAD BADGER + BAD BADGER''', '''BAD BADGER + BAD BADGER + BAD BADGER''') + """ + ) == ( + """ + assert '''BAD BADGER + BAD BADGER + BAD BADGER''' == '''BAD BADGER + BAD BADGER + BAD BADGER''' + """ + ) + + assert rewrite_utest( + """ + self.assertEquals('''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''', + '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''', + ''' FAILURE + FAILURE + FAILURE''') + """ + ) == ( + """ + assert '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''' == ( + '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM'''),( + ''' FAILURE + FAILURE + FAILURE''') + """ + ) + + + assert rewrite_utest( + """ + self.assertAlmostEquals(first, second, 5, 'A Snake!') + """ + ) == ( + """ + assert round(first - second, 5) == 0, 'A Snake!' + """ + ) + + assert rewrite_utest( + """ + self.assertAlmostEquals(first, second, 120) + """ + ) == ( + """ + assert round(first - second, 120) == 0 + """ + ) + + assert rewrite_utest( + """ + self.assertAlmostEquals(first, second) + """ + ) == ( + """ + assert round(first - second, 7) == 0 + """ + ) + + assert rewrite_utest( + """ + self.assertAlmostEqual(first, second, 5, '''A Snake! + Ohh A Snake! A Snake!! + ''') + """ + ) == ( + """ + assert round(first - second, 5) == 0, '''A Snake! + Ohh A Snake! A Snake!! + ''' + """ + ) + + assert rewrite_utest( + """ + self.assertNotAlmostEqual(first, second, 5, 'A Snake!') + """ + ) == ( + """ + assert round(first - second, 5) != 0, 'A Snake!' + """ + ) + + assert rewrite_utest( + """ + self.failIfAlmostEqual(first, second, 5, 'A Snake!') + """ + ) == ( + """ + assert not round(first - second, 5) == 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') + """ + ), + """ + self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') + """ + ) + + assert rewrite_utest( + """ + self.failUnlessAlmostEquals(first, second, 5, 'A Snake!') + """ + ) == ( + """ + assert not round(first - second, 5) != 0, 'A Snake!' + """ + ) + + assert rewrite_utest( + """ + self.assertAlmostEquals(now do something reasonable ..() + oops, I am inside a comment as a ''' string, and the fname was + mentioned in passing, leaving us with something that isn't an + expression ... will this blow up? + """ + ) == ( + """ + self.assertAlmostEquals(now do something reasonable ..() + oops, I am inside a comment as a ''' string, and the fname was + mentioned in passing, leaving us with something that isn't an + expression ... will this blow up? + """ + ) + +if __name__ == '__main__': + unittest.main() Added: pypy/trunk/src/pypy/tool/test/test_utestconvert2.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert2.py Mon Jul 5 19:09:05 2004 @@ -0,0 +1,390 @@ +import autopath +from pypy.tool.utestconvert import rewrite_utest +import unittest + +class Testit(unittest.TestCase): + def test(self): + self.assertEquals(rewrite_utest("badger badger badger"), + "badger badger badger") + + self.assertEquals(rewrite_utest( + "self.assertRaises(excClass, callableObj, *args, **kwargs)" + ), + "raises(excClass, callableObj, *args, **kwargs)" + ) + + self.assertEquals(rewrite_utest( + """ + self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) + """ + ), + """ + raises(TypeError, func, 42, **{'arg1': 23}) + """ + ) + self.assertEquals(rewrite_utest( + """ + self.assertRaises(TypeError, + func, + mushroom) + """ + ), + """ + raises(TypeError, + func, + mushroom) + """ + ) + self.assertEquals(rewrite_utest("self.fail()"), "raise AssertionError") + self.assertEquals(rewrite_utest("self.fail('mushroom, mushroom')"), + "raise AssertionError, 'mushroom, mushroom'") + self.assertEquals(rewrite_utest("self.assert_(x)"), "assert x") + self.assertEquals(rewrite_utest("self.failUnless(func(x)) # XXX"), + "assert func(x) # XXX") + + self.assertEquals(rewrite_utest( + """ + self.assert_(1 + f(y) + + z) # multiline, keep parentheses + """ + ), + """ + assert (1 + f(y) + + z) # multiline, keep parentheses + """ + ) + + self.assertEquals(rewrite_utest("self.assert_(0, 'badger badger')"), + "assert 0, 'badger badger'") + + self.assertEquals(rewrite_utest("self.assert_(0, '''badger badger''')"), + "assert 0, '''badger badger'''") + + self.assertEquals(rewrite_utest( + r""" + self.assert_(0, + 'Meet the badger.\n') + """ + ), + r""" + assert 0,( + 'Meet the badger.\n') + """ + ) + + self.assertEquals(rewrite_utest( + r""" + self.failIf(0 + 0 + + len('badger\n') + + 0, '''badger badger badger badger + mushroom mushroom + Snake! Ooh a snake! + ''') # multiline, must move the parens + """ + ), + r""" + assert not (0 + 0 + + len('badger\n') + + 0), '''badger badger badger badger + mushroom mushroom + Snake! Ooh a snake! + ''' # multiline, must move the parens + """ + ) + + self.assertEquals(rewrite_utest("self.assertEquals(0, 0)"), + "assert 0 == 0") + + self.assertEquals(rewrite_utest( + r""" + self.assertEquals(0, + 'Run away from the snake.\n') + """ + ), + r""" + assert 0 == ( + 'Run away from the snake.\n') + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertEquals(badger + 0 + + mushroom + + snake, 0) + """ + ), + """ + assert (badger + 0 + + mushroom + + snake) == 0 + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertNotEquals(badger + 0 + + mushroom + + snake, + mushroom + - badger) + """ + ), + """ + assert (badger + 0 + + mushroom + + snake) != ( + mushroom + - badger) + """ + ) + + self.assertEqual(rewrite_utest( + """ + self.assertEquals(badger(), + mushroom() + + snake(mushroom) + - badger()) + """ + ), + """ + assert badger() == ( + mushroom() + + snake(mushroom) + - badger()) + """ + ) + self.assertEquals(rewrite_utest("self.failIfEqual(0, 0)"), + "assert not 0 == 0") + + self.assertEquals(rewrite_utest("self.failUnlessEqual(0, 0)"), + "assert not 0 != 0") + + self.assertEquals(rewrite_utest( + """ + self.failUnlessEqual(mushroom() + + mushroom() + + mushroom(), '''badger badger badger + badger badger badger badger + badger badger badger badger + ''') # multiline, must move the parens + """ + ), + """ + assert not (mushroom() + + mushroom() + + mushroom()) != '''badger badger badger + badger badger badger badger + badger badger badger badger + ''' # multiline, must move the parens + """ + ) + + + self.assertEquals(rewrite_utest( + """ + self.assertEquals('''snake snake snake + snake snake snake''', mushroom) + """ + ), + """ + assert '''snake snake snake + snake snake snake''' == mushroom + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertEquals(badger(), + snake(), 'BAD BADGER') + """ + ), + """ + assert badger() == ( + snake()), 'BAD BADGER' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertNotEquals(badger(), + snake()+ + snake(), 'POISONOUS MUSHROOM!\ + Ai! I ate a POISONOUS MUSHROOM!!') + """ + ), + """ + assert badger() != ( + snake()+ + snake()), 'POISONOUS MUSHROOM!\ + Ai! I ate a POISONOUS MUSHROOM!!' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertEquals(badger(), + snake(), '''BAD BADGER + BAD BADGER + BAD BADGER''' + ) + """ + ), + """ + assert badger() == ( + snake()), '''BAD BADGER + BAD BADGER + BAD BADGER''' + + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertEquals('''BAD BADGER + BAD BADGER + BAD BADGER''', '''BAD BADGER + BAD BADGER + BAD BADGER''') + """ + ), + """ + assert '''BAD BADGER + BAD BADGER + BAD BADGER''' == '''BAD BADGER + BAD BADGER + BAD BADGER''' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertEquals('''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''', + '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''', + ''' FAILURE + FAILURE + FAILURE''') + """ + ), + """ + assert '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM''' == ( + '''GOOD MUSHROOM + GOOD MUSHROOM + GOOD MUSHROOM'''),( + ''' FAILURE + FAILURE + FAILURE''') + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertAlmostEquals(first, second, 5, 'A Snake!') + """ + ), + """ + assert round(first - second, 5) == 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertAlmostEquals(first, second, 120) + """ + ), + """ + assert round(first - second, 120) == 0 + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertAlmostEquals(first, second) + """ + ), + """ + assert round(first - second, 7) == 0 + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertAlmostEqual(first, second, 5, '''A Snake! + Ohh A Snake! A Snake!! + ''') + """ + ), + """ + assert round(first - second, 5) == 0, '''A Snake! + Ohh A Snake! A Snake!! + ''' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertNotAlmostEqual(first, second, 5, 'A Snake!') + """ + ), + """ + assert round(first - second, 5) != 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.failIfAlmostEqual(first, second, 5, 'A Snake!') + """ + ), + """ + assert not round(first - second, 5) == 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') + """ + ), + """ + self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.failUnlessAlmostEquals(first, second, 5, 'A Snake!') + """ + ), + """ + assert not round(first - second, 5) != 0, 'A Snake!' + """ + ) + + self.assertEquals(rewrite_utest( + """ + self.assertAlmostEquals(now do something reasonable ..() + oops, I am inside a comment as a ''' string, and the fname was + mentioned in passing, leaving us with something that isn't an + expression ... will this blow up? + """ + ), + """ + self.assertAlmostEquals(now do something reasonable ..() + oops, I am inside a comment as a ''' string, and the fname was + mentioned in passing, leaving us with something that isn't an + expression ... will this blow up? + """ + ) + + +if __name__ == '__main__': + unittest.main() + + From lac at codespeak.net Mon Jul 5 19:42:59 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Mon, 5 Jul 2004 19:42:59 +0200 (MEST) Subject: [pypy-svn] r5445 - pypy/trunk/src/pypy/tool Message-ID: <20040705174259.9A8015AF46@thoth.codespeak.net> Author: lac Date: Mon Jul 5 19:42:57 2004 New Revision: 5445 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: Add options for stdin, and file parsing. I'm not all that fond of optparse, which I learned to use. I think it may be the wrong sized tool for most of my jobs. I think I will go rewrite the option parsing with getopt which should be a lot smaller. But I wanted to preserve this version... Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Mon Jul 5 19:42:57 2004 @@ -1,9 +1,8 @@ import re -import unittest +import sys import parser d={} - # d is the dictionary of unittest changes, keyed to the old name # used by unittest. # d[old][0] is the new replacement function. @@ -12,7 +11,7 @@ # function. # Old Unittest Name new name operator # of args -d['assertRaises'] = ('raises', '', ['Any']) +#d['assertRaises'] = ('raises', '', ['Any']) d['fail'] = ('raise AssertionError', '', [0,1]) d['assert_'] = ('assert', '', [1,2]) d['failIf'] = ('assert not', '', [1,2]) @@ -45,9 +44,9 @@ # in text mode, will they? -def blocksplitter(filename): +def blocksplitter(fp): '''split a file into blocks that are headed by functions to rename''' - fp = file(filename, 'r') + blocklist = [] blockstring = '' @@ -198,399 +197,63 @@ pass raise SyntaxError # We never found anything that worked. -class Testit(unittest.TestCase): - def test(self): - self.assertEquals(rewrite_utest("badger badger badger"), - "badger badger badger") - - self.assertEquals(rewrite_utest( - "self.assertRaises(excClass, callableObj, *args, **kwargs)" - ), - "raises(excClass, callableObj, *args, **kwargs)" - ) - - self.assertEquals(rewrite_utest( - """ - self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) - """ - ), - """ - raises(TypeError, func, 42, **{'arg1': 23}) - """ - ) - self.assertEquals(rewrite_utest( - """ - self.assertRaises(TypeError, - func, - mushroom) - """ - ), - """ - raises(TypeError, - func, - mushroom) - """ - ) - self.assertEquals(rewrite_utest("self.fail()"), "raise AssertionError") - self.assertEquals(rewrite_utest("self.fail('mushroom, mushroom')"), - "raise AssertionError, 'mushroom, mushroom'") - self.assertEquals(rewrite_utest("self.assert_(x)"), "assert x") - self.assertEquals(rewrite_utest("self.failUnless(func(x)) # XXX"), - "assert func(x) # XXX") - - self.assertEquals(rewrite_utest( - """ - self.assert_(1 + f(y) - + z) # multiline, keep parentheses - """ - ), - """ - assert (1 + f(y) - + z) # multiline, keep parentheses - """ - ) - - self.assertEquals(rewrite_utest("self.assert_(0, 'badger badger')"), - "assert 0, 'badger badger'") - - self.assertEquals(rewrite_utest("self.assert_(0, '''badger badger''')"), - "assert 0, '''badger badger'''") - - self.assertEquals(rewrite_utest( - r""" - self.assert_(0, - 'Meet the badger.\n') - """ - ), - r""" - assert 0,( - 'Meet the badger.\n') - """ - ) - - self.assertEquals(rewrite_utest( - r""" - self.failIf(0 + 0 - + len('badger\n') - + 0, '''badger badger badger badger - mushroom mushroom - Snake! Ooh a snake! - ''') # multiline, must move the parens - """ - ), - r""" - assert not (0 + 0 - + len('badger\n') - + 0), '''badger badger badger badger - mushroom mushroom - Snake! Ooh a snake! - ''' # multiline, must move the parens - """ - ) - - self.assertEquals(rewrite_utest("self.assertEquals(0, 0)"), - "assert 0 == 0") - - self.assertEquals(rewrite_utest( - r""" - self.assertEquals(0, - 'Run away from the snake.\n') - """ - ), - r""" - assert 0 == ( - 'Run away from the snake.\n') - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertEquals(badger + 0 - + mushroom - + snake, 0) - """ - ), - """ - assert (badger + 0 - + mushroom - + snake) == 0 - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertNotEquals(badger + 0 - + mushroom - + snake, - mushroom - - badger) - """ - ), - """ - assert (badger + 0 - + mushroom - + snake) != ( - mushroom - - badger) - """ - ) - - self.assertEqual(rewrite_utest( - """ - self.assertEquals(badger(), - mushroom() - + snake(mushroom) - - badger()) - """ - ), - """ - assert badger() == ( - mushroom() - + snake(mushroom) - - badger()) - """ - ) - self.assertEquals(rewrite_utest("self.failIfEqual(0, 0)"), - "assert not 0 == 0") - - self.assertEquals(rewrite_utest("self.failUnlessEqual(0, 0)"), - "assert not 0 != 0") - - self.assertEquals(rewrite_utest( - """ - self.failUnlessEqual(mushroom() - + mushroom() - + mushroom(), '''badger badger badger - badger badger badger badger - badger badger badger badger - ''') # multiline, must move the parens - """ - ), - """ - assert not (mushroom() - + mushroom() - + mushroom()) != '''badger badger badger - badger badger badger badger - badger badger badger badger - ''' # multiline, must move the parens - """ - ) - - - self.assertEquals(rewrite_utest( - """ - self.assertEquals('''snake snake snake - snake snake snake''', mushroom) - """ - ), - """ - assert '''snake snake snake - snake snake snake''' == mushroom - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertEquals(badger(), - snake(), 'BAD BADGER') - """ - ), - """ - assert badger() == ( - snake()), 'BAD BADGER' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertNotEquals(badger(), - snake()+ - snake(), 'POISONOUS MUSHROOM!\ - Ai! I ate a POISONOUS MUSHROOM!!') - """ - ), - """ - assert badger() != ( - snake()+ - snake()), 'POISONOUS MUSHROOM!\ - Ai! I ate a POISONOUS MUSHROOM!!' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertEquals(badger(), - snake(), '''BAD BADGER - BAD BADGER - BAD BADGER''' - ) - """ - ), - """ - assert badger() == ( - snake()), '''BAD BADGER - BAD BADGER - BAD BADGER''' - - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertEquals('''BAD BADGER - BAD BADGER - BAD BADGER''', '''BAD BADGER - BAD BADGER - BAD BADGER''') - """ - ), - """ - assert '''BAD BADGER - BAD BADGER - BAD BADGER''' == '''BAD BADGER - BAD BADGER - BAD BADGER''' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertEquals('''GOOD MUSHROOM - GOOD MUSHROOM - GOOD MUSHROOM''', - '''GOOD MUSHROOM - GOOD MUSHROOM - GOOD MUSHROOM''', - ''' FAILURE - FAILURE - FAILURE''') - """ - ), - """ - assert '''GOOD MUSHROOM - GOOD MUSHROOM - GOOD MUSHROOM''' == ( - '''GOOD MUSHROOM - GOOD MUSHROOM - GOOD MUSHROOM'''),( - ''' FAILURE - FAILURE - FAILURE''') - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertAlmostEquals(first, second, 5, 'A Snake!') - """ - ), - """ - assert round(first - second, 5) == 0, 'A Snake!' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertAlmostEquals(first, second, 120) - """ - ), - """ - assert round(first - second, 120) == 0 - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertAlmostEquals(first, second) - """ - ), - """ - assert round(first - second, 7) == 0 - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertAlmostEqual(first, second, 5, '''A Snake! - Ohh A Snake! A Snake!! - ''') - """ - ), - """ - assert round(first - second, 5) == 0, '''A Snake! - Ohh A Snake! A Snake!! - ''' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertNotAlmostEqual(first, second, 5, 'A Snake!') - """ - ), - """ - assert round(first - second, 5) != 0, 'A Snake!' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.failIfAlmostEqual(first, second, 5, 'A Snake!') - """ - ), - """ - assert not round(first - second, 5) == 0, 'A Snake!' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') - """ - ), - """ - self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.failUnlessAlmostEquals(first, second, 5, 'A Snake!') - """ - ), - """ - assert not round(first - second, 5) != 0, 'A Snake!' - """ - ) - - self.assertEquals(rewrite_utest( - """ - self.assertAlmostEquals(now do something reasonable ..() - oops, I am inside a comment as a ''' string, and the fname was - mentioned in passing, leaving us with something that isn't an - expression ... will this blow up? - """ - ), - """ - self.assertAlmostEquals(now do something reasonable ..() - oops, I am inside a comment as a ''' string, and the fname was - mentioned in passing, leaving us with something that isn't an - expression ... will this blow up? - """ - ) - - if __name__ == '__main__': - unittest.main() - '''count = 1 - for block in blocksplitter('xxx.py'): - print 'START BLOCK', count - print rewrite_utest(block) - print 'END BLOCK', count - print - print - count +=1 - ''' -#for block in blocksplitter('xxx.py'): print rewrite_utest(block) + from optparse import OptionParser + import sys + + usage = "usage: %prog [-s [filename ...] | [-i | -c filename ...]]" + optparser = OptionParser(usage) + + def select_output (option, opt, value, optparser, **kw): + if hasattr(optparser, 'output'): + optparser.error( + 'Cannot combine -s -i and -c options. Use one only.') + else: + optparser.output = kw['output'] + + optparser.add_option("-s", "--stdout", action="callback", + callback=select_output, + callback_kwargs={'output':'stdout'}, + help="send your output to stdout") + + optparser.add_option("-i", "--inplace", action="callback", + callback=select_output, + callback_kwargs={'output':'inplace'}, + help="overwrite files in place") + + optparser.add_option("-c", "--copy", action="callback", + callback=select_output, + callback_kwargs={'output':'copy'}, + help="copy files ... fn.py --> fn.new.py") + + options, args = optparser.parse_args() + + output = getattr(optparser, 'output', 'stdout') + + if output in ['inplace', 'copy'] and not args: + optparser.error( + '-i and -c option require at least one filename') + + if not args: + s = '' + for block in blocksplitter(sys.stdin.read()): + s += rewrite_utest(block) + sys.stdout.write(s) + + else: + for infilename in args: # no error checking to see if we can open, etc. + infile = file(infilename) + s = '' + for block in blocksplitter(infile): + s += rewrite_utest(block) + if output == 'inplace': + outfile = file(infilename, 'w+') + elif output == 'copy': # yes, just go clobber any existing .cp + outfile = file (infilename + '.cp', 'w+') + else: + outfile = sys.stdout + + outfile.write(s) + From lac at codespeak.net Mon Jul 5 19:48:43 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Mon, 5 Jul 2004 19:48:43 +0200 (MEST) Subject: [pypy-svn] r5446 - pypy/trunk/src/pypy/tool Message-ID: <20040705174843.C2D325AF46@thoth.codespeak.net> Author: lac Date: Mon Jul 5 19:48:43 2004 New Revision: 5446 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: oops, forgot one of the 'raises' to be commented out ... Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Mon Jul 5 19:48:43 2004 @@ -25,7 +25,7 @@ d['failUnlessAlmostEquals'] = ('assert not round', ' !=', [2,3,4]) # the list of synonyms -d['failUnlessRaises'] = d['assertRaises'] +#d['failUnlessRaises'] = d['assertRaises'] d['failUnless'] = d['assert_'] d['assertEquals'] = d['assertEqual'] d['assertNotEquals'] = d['assertNotEqual'] From rxe at codespeak.net Tue Jul 6 15:06:47 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Tue, 6 Jul 2004 15:06:47 +0200 (MEST) Subject: [pypy-svn] r5450 - in pypy/trunk/src/pypy/interpreter: . test Message-ID: <20040706130647.7560F5B4A4@thoth.codespeak.net> Author: rxe Date: Tue Jul 6 15:06:46 2004 New Revision: 5450 Modified: pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/test/test_function.py pypy/trunk/src/pypy/interpreter/typedef.py Log: Add functionality so methods have __get__() * add a __get__() method to interpreter.function.Method which forwards request onto w_function attribute. * add some tests for function __get__() and method __get__() Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Tue Jul 6 15:06:46 2004 @@ -100,6 +100,10 @@ self.space.wrap(msg)) return self.space.call_args(self.w_function, args) + def descr_method_get(self, w_obj, w_cls=None): + function = self.space.unwrap(self.w_function) + return function.descr_function_get(w_obj, w_cls=w_cls) + def descr_method_call(self, __args__): return self.call_args(__args__) Modified: pypy/trunk/src/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_function.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_function.py Tue Jul 6 15:06:46 2004 @@ -130,6 +130,36 @@ res = func(self=6) self.assertEquals(res, 42) + def test_get(self): + def func(self): return self + obj = object() + meth = func.__get__(obj, object) + self.assertEquals(meth(), obj) + +class AppTestMethod(testit.AppTestCase): + + def test_get(self): + def func(self): return self + class Object(object): pass + obj = Object() + # Create bound method from function + obj.meth = func.__get__(obj, Object) + self.assertEquals(obj.meth(), obj) + # Create bound method from method + meth2 = obj.meth.__get__(obj, Object) + self.assertEquals(meth2(), obj) + + def test_get_get(self): + # sanxiyn's test from email + def m(self): return self + class C: pass + class D(C): pass + C.m = m + D.m = C.m + c = C() + self.assertEquals(c.m(), c) + d = D() + self.assertEquals(d.m(), d) class TestMethod(testit.IntTestCase): def setUp(self): @@ -159,5 +189,25 @@ args = Arguments(space, [space.wrap("spam"), space.wrap("egg")]) self.assertRaises_w(self.space.w_TypeError, meth.call_args, args) + def test_method_get(self): + space = self.space + # Create some function for this test only + def m(self): return self + func = Function(space, PyCode()._from_code(m.func_code)) + # Some shorthands + obj1 = space.wrap(23) + obj2 = space.wrap(42) + args = Arguments(space, []) + # Check method returned from func.__get__() + w_meth1 = func.descr_function_get(obj1, space.type(obj1)) + meth1 = space.unwrap(w_meth1) + self.failUnless(isinstance(meth1, Method)) + self.assertEquals(meth1.call_args(args), obj1) + # Check method returned from method.__get__() + w_meth2 = meth1.descr_method_get(obj2, space.type(obj2)) + meth2 = space.unwrap(w_meth2) + self.failUnless(isinstance(meth2, Method)) + self.assertEquals(meth2.call_args(args), obj2) + if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Tue Jul 6 15:06:46 2004 @@ -233,6 +233,7 @@ Method.typedef = TypeDef("method", __call__ = interp2app(Method.descr_method_call.im_func), + __get__ = interp2app(Method.descr_method_get.im_func), im_func = attrproperty_w('w_function'), im_self = attrproperty_w('w_instance'), im_class = attrproperty_w('w_class'), From lac at codespeak.net Tue Jul 6 19:07:23 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Tue, 6 Jul 2004 19:07:23 +0200 (MEST) Subject: [pypy-svn] r5462 - in pypy/trunk/src/pypy/tool: . test Message-ID: <20040706170723.0A9545A95D@thoth.codespeak.net> Author: lac Date: Tue Jul 6 19:07:22 2004 New Revision: 5462 Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert.py pypy/trunk/src/pypy/tool/test/test_utestconvert2.py pypy/trunk/src/pypy/tool/utestconvert.py Log: Check in the tests from work so I can work on them from home. They don't pass yet. Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/test/test_utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert.py Tue Jul 6 19:07:22 2004 @@ -349,11 +349,11 @@ """ ) - self.assertEquals(rewrite_utest( + assert rewrite_utest( """ self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ - ), + ) == ( """ self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ @@ -384,6 +384,19 @@ expression ... will this blow up? """ ) - + + assert rewrite_utest( + """ + self.failUnless('__builtin__' in modules, "An entry for __builtin__ " + "is not in sys.modules.") + """ + ) == ( + """ + assert '__builtin__' in modules, ("An entry for __builtin__ " + "is not in sys.modules.") + """ + ) + + if __name__ == '__main__': unittest.main() Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert2.py ============================================================================== --- pypy/trunk/src/pypy/tool/test/test_utestconvert2.py (original) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert2.py Tue Jul 6 19:07:22 2004 @@ -382,6 +382,18 @@ expression ... will this blow up? """ ) + + self.assertEquals(rewrite_utest( + """ + self.failUnless('__builtin__' in modules, "An entry for __builtin__ " + "is not in sys.modules.") + """ + ), + """ + assert '__builtin__' in modules, ("An entry for __builtin__ " + "is not in sys.modules.") + """ + ) if __name__ == '__main__': Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Tue Jul 6 19:07:22 2004 @@ -11,7 +11,7 @@ # function. # Old Unittest Name new name operator # of args -#d['assertRaises'] = ('raises', '', ['Any']) +d['assertRaises'] = ('raises', '', ['Any']) d['fail'] = ('raise AssertionError', '', [0,1]) d['assert_'] = ('assert', '', [1,2]) d['failIf'] = ('assert not', '', [1,2]) @@ -25,7 +25,7 @@ d['failUnlessAlmostEquals'] = ('assert not round', ' !=', [2,3,4]) # the list of synonyms -#d['failUnlessRaises'] = d['assertRaises'] +d['failUnlessRaises'] = d['assertRaises'] d['failUnless'] = d['assert_'] d['assertEquals'] = d['assertEqual'] d['assertNotEquals'] = d['assertNotEqual'] @@ -139,31 +139,22 @@ if arglist == ['']: # there weren't any return indent, [], [], trailer - if len(arglist) != message_pos: - message = None else: - message = arglist[-1] - arglist = arglist[:-1] - if message.lstrip('\t ').startswith(linesep): - message = '(' + message + ')' - # In proper input, message is required to be a string. - # Thus we can assume that however the string handled its - # line continuations in the original unittest will also work - # here. But if the line happens to break before the quoting - # begins, you will need another set of parens, (or a backslash). - - if arglist: for i in range(len(arglist)): try: parser.expr(arglist[i].lstrip('\t ')) - # Again we want to enclose things that happen to have - # a linebreak just before the new arg. except SyntaxError: if i == 0: arglist[i] = '(' + arglist[i] + ')' else: arglist[i] = ' (' + arglist[i] + ')' + if len(arglist) != message_pos: + message = None + else: + message = arglist[-1] + arglist = arglist[:-1] + return indent, arglist, message, trailer def break_args(args, arglist): From rxe at codespeak.net Thu Jul 8 17:40:39 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 8 Jul 2004 17:40:39 +0200 (MEST) Subject: [pypy-svn] r5490 - pypy/trunk/src/pypy/interpreter Message-ID: <20040708154039.7D0885AA07@thoth.codespeak.net> Author: rxe Date: Thu Jul 8 17:40:38 2004 New Revision: 5490 Modified: pypy/trunk/src/pypy/interpreter/function.py Log: Route get() on wrapped object through the object space. Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Thu Jul 8 17:40:38 2004 @@ -101,8 +101,7 @@ return self.space.call_args(self.w_function, args) def descr_method_get(self, w_obj, w_cls=None): - function = self.space.unwrap(self.w_function) - return function.descr_function_get(w_obj, w_cls=w_cls) + return self.space.get(self.w_function, w_obj, w_type=w_cls) def descr_method_call(self, __args__): return self.call_args(__args__) From lac at codespeak.net Fri Jul 9 14:50:47 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Fri, 9 Jul 2004 14:50:47 +0200 (MEST) Subject: [pypy-svn] r5497 - pypy/trunk/src/pypy/tool Message-ID: <20040709125047.6CEA55A0EF@thoth.codespeak.net> Author: lac Date: Fri Jul 9 14:50:46 2004 New Revision: 5497 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: If messages aren't to be treated differently than the other args then some simplification can be done. Also make the -c opt produce xxx.cp.py files, so that they will be picked up by test_all.py Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Fri Jul 9 14:50:46 2004 @@ -11,7 +11,7 @@ # function. # Old Unittest Name new name operator # of args -d['assertRaises'] = ('raises', '', ['Any']) +#d['assertRaises'] = ('raises', '', ['Any']) d['fail'] = ('raise AssertionError', '', [0,1]) d['assert_'] = ('assert', '', [1,2]) d['failIf'] = ('assert not', '', [1,2]) @@ -25,7 +25,7 @@ d['failUnlessAlmostEquals'] = ('assert not round', ' !=', [2,3,4]) # the list of synonyms -d['failUnlessRaises'] = d['assertRaises'] +#d['failUnlessRaises'] = d['assertRaises'] d['failUnless'] = d['assert_'] d['assertEquals'] = d['assertEqual'] d['assertNotEquals'] = d['assertNotEqual'] @@ -87,19 +87,22 @@ # when they fail. It is always the last argument to the function. try: - indent, args, message, trailer = decompose_unittest( - old, block, message_pos) + indent, argl, trailer = decompose_unittest(old, block) + except SyntaxError: # but we couldn't parse it! return block - - argnum = len(args) - if message: - argnum += 1 - + + argnum = len(argl) if argnum not in possible_args: # sanity check - this one isn't real either return block + elif argnum == message_pos: + message = argl[-1] + argl = argl[:-1] + else: + message = None + if argnum is 0 or (argnum is 1 and argnum is message_pos): #unittest fail() string = '' if message: @@ -107,26 +110,25 @@ elif message_pos is 4: # assertAlmostEqual & friends try: - pos = args[2].lstrip() + pos = argl[2].lstrip() except IndexError: pos = '7' # default if none is specified - string = '(%s -%s, %s)%s 0' % (args[0], args[1], pos, op ) + string = '(%s -%s, %s)%s 0' % (argl[0], argl[1], pos, op ) else: # assert_, assertEquals and all the rest - string = ' ' + op.join(args) + string = ' ' + op.join(argl) if message: string = string + ',' + message return indent + new + string + trailer -def decompose_unittest(old, block, message_pos): +def decompose_unittest(old, block): '''decompose the block into its component parts''' - ''' returns indent, arglist, message, trailer + ''' returns indent, arglist, trailer indent -- the indentation arglist -- the arguments to the unittest function - message -- the optional message to print when it fails, and trailer -- any extra junk after the closing paren, such as #commment ''' @@ -137,25 +139,18 @@ arglist = break_args(args, []) if arglist == ['']: # there weren't any - return indent, [], [], trailer - - else: - for i in range(len(arglist)): - try: - parser.expr(arglist[i].lstrip('\t ')) - except SyntaxError: - if i == 0: - arglist[i] = '(' + arglist[i] + ')' - else: - arglist[i] = ' (' + arglist[i] + ')' + return indent, [], trailer - if len(arglist) != message_pos: - message = None - else: - message = arglist[-1] - arglist = arglist[:-1] + for i in range(len(arglist)): + try: + parser.expr(arglist[i].lstrip('\t ')) + except SyntaxError: + if i == 0: + arglist[i] = '(' + arglist[i] + ')' + else: + arglist[i] = ' (' + arglist[i] + ')' - return indent, arglist, message, trailer + return indent, arglist, trailer def break_args(args, arglist): '''recursively break a string into a list of arguments''' @@ -241,7 +236,7 @@ if output == 'inplace': outfile = file(infilename, 'w+') elif output == 'copy': # yes, just go clobber any existing .cp - outfile = file (infilename + '.cp', 'w+') + outfile = file (infilename[:-3]+ '.cp.py', 'w+') else: outfile = sys.stdout From arigo at codespeak.net Fri Jul 9 17:36:38 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 9 Jul 2004 17:36:38 +0200 (MEST) Subject: [pypy-svn] r5498 - in pypy/trunk/src/pypy/interpreter: . test Message-ID: <20040709153638.2705F5A0EF@thoth.codespeak.net> Author: arigo Date: Fri Jul 9 17:36:37 2004 New Revision: 5498 Modified: pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/test/test_function.py Log: Copied Method.__get__() from CPython. Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Fri Jul 9 17:36:37 2004 @@ -101,7 +101,16 @@ return self.space.call_args(self.w_function, args) def descr_method_get(self, w_obj, w_cls=None): - return self.space.get(self.w_function, w_obj, w_type=w_cls) + space = self.space + if self.w_instance is not None: + return space.wrap(self) # already bound + else: + # only allow binding to a more specific class than before + if w_cls == space.w_None: + w_cls = space.type(w_obj) + if not space.is_true(space.issubtype(w_cls, self.w_class)): + return space.wrap(self) # subclass test failed + return space.get(self.w_function, w_obj, w_cls) def descr_method_call(self, __args__): return self.call_args(__args__) Modified: pypy/trunk/src/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_function.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_function.py Fri Jul 9 17:36:37 2004 @@ -204,10 +204,22 @@ self.failUnless(isinstance(meth1, Method)) self.assertEquals(meth1.call_args(args), obj1) # Check method returned from method.__get__() + # --- meth1 is already bound so meth1.__get__(*) is meth1. w_meth2 = meth1.descr_method_get(obj2, space.type(obj2)) meth2 = space.unwrap(w_meth2) self.failUnless(isinstance(meth2, Method)) - self.assertEquals(meth2.call_args(args), obj2) + self.assertEquals(meth2.call_args(args), obj1) + # Check method returned from unbound_method.__get__() + w_meth3 = func.descr_function_get(None, space.type(obj2)) + meth3 = space.unwrap(w_meth3) + w_meth4 = meth3.descr_method_get(obj2, space.w_None) + meth4 = space.unwrap(w_meth4) + self.failUnless(isinstance(meth4, Method)) + self.assertEquals(meth4.call_args(args), obj2) + # Check method returned from unbound_method.__get__() + # --- with an incompatible class + w_meth5 = meth3.descr_method_get(space.wrap('hello'), space.w_None) + self.assert_(space.is_true(space.is_(w_meth5, w_meth3))) if __name__ == '__main__': testit.main() From lac at codespeak.net Sat Jul 10 22:09:06 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 10 Jul 2004 22:09:06 +0200 (MEST) Subject: [pypy-svn] r5510 - in pypy/trunk/src/pypy/tool: . test Message-ID: <20040710200906.6E9A45AAB7@thoth.codespeak.net> Author: lac Date: Sat Jul 10 22:09:05 2004 New Revision: 5510 Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert.py pypy/trunk/src/pypy/tool/test/test_utestconvert2.py pypy/trunk/src/pypy/tool/utestconvert.py Log: now they all pass. Note, before you start using them, utestconvert as it stands will change assertRaises. comment out the 2 dictionary entries if you do not want this. But to pass its own unittests, it needs to have them uncommented ... Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/test/test_utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert.py Sat Jul 10 22:09:05 2004 @@ -4,21 +4,24 @@ class Testit(unittest.TestCase): def test(self): - assert rewrite_utest("badger badger badger") == ( - "badger badger badger") + "badger badger badger") assert rewrite_utest( - "self.assertRaises(excClass, callableObj, *args, **kwargs)") == ( - "raises(excClass, callableObj, *args, **kwargs)") + "self.assertRaises(excClass, callableObj, *args, **kwargs)" + ) == ( + "raises(excClass, callableObj, *args, **kwargs)" + ) - assert rewrite_utest(""" + assert rewrite_utest( + """ self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) - """) == (""" + """ + ) == ( + """ raises(TypeError, func, 42, **{'arg1': 23}) """ ) - assert rewrite_utest( """ self.assertRaises(TypeError, @@ -32,17 +35,13 @@ mushroom) """ ) - assert rewrite_utest("self.fail()") == "raise AssertionError" - assert rewrite_utest("self.fail('mushroom, mushroom')") == ( "raise AssertionError, 'mushroom, mushroom'") - assert rewrite_utest("self.assert_(x)") == "assert x" - assert rewrite_utest("self.failUnless(func(x)) # XXX") == ( "assert func(x) # XXX") - + assert rewrite_utest( """ self.assert_(1 + f(y) @@ -68,11 +67,11 @@ """ ) == ( r""" - assert 0,( + assert 0, ( 'Meet the badger.\n') """ ) - + assert rewrite_utest( r""" self.failIf(0 + 0 @@ -95,7 +94,7 @@ assert rewrite_utest("self.assertEquals(0, 0)") == ( "assert 0 == 0") - + assert rewrite_utest( r""" self.assertEquals(0, @@ -121,7 +120,7 @@ + snake) == 0 """ ) - + assert rewrite_utest( """ self.assertNotEquals(badger + 0 @@ -155,7 +154,6 @@ - badger()) """ ) - assert rewrite_utest("self.failIfEqual(0, 0)") == ( "assert not 0 == 0") @@ -182,6 +180,7 @@ """ ) + assert rewrite_utest( """ self.assertEquals('''snake snake snake @@ -193,7 +192,7 @@ snake snake snake''' == mushroom """ ) - + assert rewrite_utest( """ self.assertEquals(badger(), @@ -233,10 +232,10 @@ ) == ( """ assert badger() == ( - snake()), '''BAD BADGER + snake()), ( '''BAD BADGER BAD BADGER BAD BADGER''' - + ) """ ) @@ -277,14 +276,13 @@ GOOD MUSHROOM''' == ( '''GOOD MUSHROOM GOOD MUSHROOM - GOOD MUSHROOM'''),( + GOOD MUSHROOM'''), ( ''' FAILURE FAILURE FAILURE''') """ ) - assert rewrite_utest( """ self.assertAlmostEquals(first, second, 5, 'A Snake!') @@ -349,11 +347,11 @@ """ ) - assert rewrite_utest( + self.assertEquals(rewrite_utest( """ self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ - ) == ( + ), """ self.failIfAlmostEqual(first, second, 5, 6, 7, 'Too Many Args') """ @@ -384,7 +382,7 @@ expression ... will this blow up? """ ) - + assert rewrite_utest( """ self.failUnless('__builtin__' in modules, "An entry for __builtin__ " @@ -392,11 +390,13 @@ """ ) == ( """ - assert '__builtin__' in modules, ("An entry for __builtin__ " + assert '__builtin__' in modules, ( "An entry for __builtin__ " "is not in sys.modules.") """ ) - + if __name__ == '__main__': unittest.main() + + Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert2.py ============================================================================== --- pypy/trunk/src/pypy/tool/test/test_utestconvert2.py (original) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert2.py Sat Jul 10 22:09:05 2004 @@ -67,7 +67,7 @@ """ ), r""" - assert 0,( + assert 0, ( 'Meet the badger.\n') """ ) @@ -232,10 +232,10 @@ ), """ assert badger() == ( - snake()), '''BAD BADGER + snake()), ( '''BAD BADGER BAD BADGER BAD BADGER''' - + ) """ ) @@ -276,7 +276,7 @@ GOOD MUSHROOM''' == ( '''GOOD MUSHROOM GOOD MUSHROOM - GOOD MUSHROOM'''),( + GOOD MUSHROOM'''), ( ''' FAILURE FAILURE FAILURE''') @@ -390,7 +390,7 @@ """ ), """ - assert '__builtin__' in modules, ("An entry for __builtin__ " + assert '__builtin__' in modules, ( "An entry for __builtin__ " "is not in sys.modules.") """ ) Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Sat Jul 10 22:09:05 2004 @@ -11,7 +11,7 @@ # function. # Old Unittest Name new name operator # of args -#d['assertRaises'] = ('raises', '', ['Any']) +d['assertRaises'] = ('raises', '', ['Any']) d['fail'] = ('raise AssertionError', '', [0,1]) d['assert_'] = ('assert', '', [1,2]) d['failIf'] = ('assert not', '', [1,2]) @@ -25,7 +25,7 @@ d['failUnlessAlmostEquals'] = ('assert not round', ' !=', [2,3,4]) # the list of synonyms -#d['failUnlessRaises'] = d['assertRaises'] +d['failUnlessRaises'] = d['assertRaises'] d['failUnless'] = d['assert_'] d['assertEquals'] = d['assertEqual'] d['assertNotEquals'] = d['assertNotEqual'] @@ -211,10 +211,14 @@ optparser.add_option("-c", "--copy", action="callback", callback=select_output, callback_kwargs={'output':'copy'}, - help="copy files ... fn.py --> fn.new.py") + help="copy files ... fn.py --> fn.cp.py") options, args = optparser.parse_args() + + + + output = getattr(optparser, 'output', 'stdout') if output in ['inplace', 'copy'] and not args: From lac at codespeak.net Sat Jul 10 22:40:37 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 10 Jul 2004 22:40:37 +0200 (MEST) Subject: [pypy-svn] r5511 - pypy/trunk/src/pypy/tool Message-ID: <20040710204037.383E65AAB7@thoth.codespeak.net> Author: lac Date: Sat Jul 10 22:40:36 2004 New Revision: 5511 Modified: pypy/trunk/src/pypy/tool/utestconvert.py Log: ooops, calling the copy version as xxx.cp.py wasn't a good idea. now they are xxx_cp.py Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Sat Jul 10 22:40:36 2004 @@ -211,14 +211,10 @@ optparser.add_option("-c", "--copy", action="callback", callback=select_output, callback_kwargs={'output':'copy'}, - help="copy files ... fn.py --> fn.cp.py") + help="copy files ... fn.py --> fn_cp.py") options, args = optparser.parse_args() - - - - output = getattr(optparser, 'output', 'stdout') if output in ['inplace', 'copy'] and not args: @@ -240,7 +236,7 @@ if output == 'inplace': outfile = file(infilename, 'w+') elif output == 'copy': # yes, just go clobber any existing .cp - outfile = file (infilename[:-3]+ '.cp.py', 'w+') + outfile = file (infilename[:-3]+ '_cp.py', 'w+') else: outfile = sys.stdout From pedronis at codespeak.net Sun Jul 11 21:55:38 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 11 Jul 2004 21:55:38 +0200 (MEST) Subject: [pypy-svn] r5531 - in pypy/trunk/src/pypy/module: . test test/impsubdir/pkg_substituted test/impsubdir/pkg_substituting Message-ID: <20040711195538.7CEF15AFD2@thoth.codespeak.net> Author: pedronis Date: Sun Jul 11 21:55:37 2004 New Revision: 5531 Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituted/ pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituted/__init__.py pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituted/mod.py pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituting/ pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituting/__init__.py Modified: pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/test/test_import.py Log: implementing substituing import support, with test Modified: pypy/trunk/src/pypy/module/__builtin__interp.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__interp.py (original) +++ pypy/trunk/src/pypy/module/__builtin__interp.py Sun Jul 11 21:55:37 2004 @@ -42,7 +42,8 @@ space.setattr(w_mod, w('__path__'), space.newlist([w(pkgdir)])) w_dict = space.getattr(w_mod, w('__dict__')) execfile(w(f), w_dict, w_dict) - if w_parent is not None: + w_mod = check_sys_modules(w_modulename) + if w_mod is not None and w_parent is not None: space.setattr(w_parent, w_name, w_mod) return w_mod else: Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituted/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituted/__init__.py Sun Jul 11 21:55:37 2004 @@ -0,0 +1 @@ +# __init__ Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituted/mod.py ============================================================================== Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituting/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg_substituting/__init__.py Sun Jul 11 21:55:37 2004 @@ -0,0 +1,2 @@ +import sys, pkg_substituted +sys.modules[__name__] = pkg_substituted Modified: pypy/trunk/src/pypy/module/test/test_import.py ============================================================================== --- pypy/trunk/src/pypy/module/test/test_import.py (original) +++ pypy/trunk/src/pypy/module/test/test_import.py Sun Jul 11 21:55:37 2004 @@ -141,6 +141,9 @@ #self.assertEquals(sys.modules.get('pkg.x'),None) #self.assert_('pkg.x.y' not in sys.modules) + def test_substituting_import(self): + from pkg_substituting import mod + self.assertEquals(mod.__name__,'pkg_substituting.mod') if __name__ == '__main__': From rxe at codespeak.net Mon Jul 12 14:05:50 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Mon, 12 Jul 2004 14:05:50 +0200 (MEST) Subject: [pypy-svn] r5533 - in pypy/trunk/src/pypy: interpreter objspace objspace/test tool Message-ID: <20040712120550.A38825A9FE@thoth.codespeak.net> Author: rxe Date: Mon Jul 12 14:05:49 2004 New Revision: 5533 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py pypy/trunk/src/pypy/objspace/trace.py pypy/trunk/src/pypy/tool/traceinteractive.py pypy/trunk/src/pypy/tool/traceop.py Log: Tracespace hopefully now catches all operations. Generally tided up tracespace code and better print function. Had to turn base ObjectSpace into a new style class (sorry - maybe there is a better way) Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Mon Jul 12 14:05:49 2004 @@ -24,7 +24,7 @@ class Wrappable(BaseWrappable, object): """Same as BaseWrappable, just new-style instead.""" -class ObjSpace: +class ObjSpace(object): """Base class for the interpreter-level implementations of object spaces. http://codespeak.net/moin/pypy/moin.cgi/ObjectSpace""" Modified: pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py (original) +++ pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py Mon Jul 12 14:05:49 2004 @@ -1,28 +1,33 @@ import autopath from pypy.tool import testit -from pypy.objspace.trace import TraceObjSpace +from pypy.objspace import trace from pypy.interpreter.gateway import app2interp from pypy.tool import pydis class Test_TraceObjSpace(testit.IntTestCase): - + tspace = None + def setUp(self): - self.space = testit.objspace() - + # XXX hack so we only have one trace space + if Test_TraceObjSpace.tspace is None: + newspace = testit.objspace().__class__() + Test_TraceObjSpace.tspace = trace.create_trace_space(newspace) + def tearDown(self): pass def perform_trace(self, app_func): - tspace = TraceObjSpace(self.space) + tspace = self.tspace func_gw = app2interp(app_func) func = func_gw.get_function(tspace) + tspace.settrace() tspace.call_function(tspace.wrap(func)) res = tspace.getresult() return res def test_traceobjspace_basic(self): - t = TraceObjSpace(self.space) - self.assert_(t.is_true(t.w_builtins)) + tspace = self.tspace + self.assert_(tspace.is_true(tspace.w_builtins)) #for name, value in vars(self.space).items(): # if not name.startswith('_'): # self.assert_(value is getattr(t, name)) @@ -34,30 +39,39 @@ res = self.perform_trace(app_f) disresult = pydis.pydis(app_f) self.assertEquals(disresult.bytecodes, list(res.getbytecodes())) - #self.assertEquals(len(list(res.getoperations())), 0) - def test_some_builtin(self): + def test_some_builtin1(self): + def app_f(): + len([1,2,3,4,5]) + res = self.perform_trace(app_f) + disresult = pydis.pydis(app_f) + self.assertEquals(len(disresult.bytecodes), len(list(res.getbytecodes()))) + + def test_some_builtin2(self): def app_f(): - filter(None, []) # mapglobals() # ("c") + filter(None, []) # filter implemented in appspace -> has many more bytecodes res = self.perform_trace(app_f) disresult = pydis.pydis(app_f) - self.assertEquals(disresult.bytecodes, list(res.getbytecodes())) - #self.assertEquals(len(list(res.getoperations())), 0) + self.failUnless(len(disresult.bytecodes) < len(list(res.getbytecodes()))) + def get_operation(self, iter, optype, name): + for op in iter: + if isinstance(op, optype): + if op.callinfo.name == name: + return op + def test_trace_oneop(self): def app_f(): 1 + 1 - w = self.space.wrap res = self.perform_trace(app_f) disresult = pydis.pydis(app_f) - self.assertEquals(disresult.bytecodes, list(res.getbytecodes())) - ops = list(res.getoperations()) - self.assert_(len(ops) > 0) - #op = ops[0] - #self.assertEquals(pydis.getbytecodename(op.bytecode), 'binary_add') # XXX - #self.assertEquals(op.name, 'add') - #expected_w = (w(1), w(1)) - #self.assertEquals_w(op.args_w, expected_w) + uw = self.tspace.unwrap + ops = res.getoperations() + op_start = self.get_operation(ops, trace.CallBegin, "add") + args = [uw(x) for x in op_start.callinfo.args] + self.assertEquals(args, [1, 1]) + op_end = self.get_operation(ops, trace.CallFinished, "add") + self.assertEquals(uw(op_end.res), 2) if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/objspace/trace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trace.py (original) +++ pypy/trunk/src/pypy/objspace/trace.py Mon Jul 12 14:05:49 2004 @@ -1,51 +1,87 @@ """ - trace object space traces operations and bytecode execution + Trace object space traces operations and bytecode execution in frames. """ -from __future__ import generators + from pypy.tool import pydis +from pypy.interpreter.baseobjspace import ObjSpace # __________________________________________________________________________ # # Tracing Events # __________________________________________________________________________ +# -class ExecBytecode: +class ExecBytecode(object): """ bytecode trace. """ def __init__(self, frame): self.frame = frame self.code = frame.code self.index = frame.next_instr - #assert self.index < len(frame.code.co_code) -class EnterFrame: +class EnterFrame(object): def __init__(self, frame): self.frame = frame -class LeaveFrame: +class LeaveFrame(object): def __init__(self, frame): self.frame = frame -class CallBegin: +class CallBegin(object): def __init__(self, callinfo): self.callinfo = callinfo -class CallFinished: - def __init__(self, callinfo): +class CallFinished(object): + def __init__(self, callinfo, res): self.callinfo = callinfo - -class CallException: - def __init__(self, e, callinfo): - self.ex = e + self.res = res + +class CallException(object): + def __init__(self, callinfo, e): self.callinfo = callinfo + self.ex = e + +class TraceResult(object): + """ this is the state of tracing-in-progress. """ + def __init__(self, tracespace): + self.events = [] + self.tracespace = tracespace + + def append(self, arg): + self.events.append(arg) + + def getdisresult(self, frame, _cache = {}): + """ return (possibly cached) pydis result for the given frame. """ + try: + return _cache[id(frame.code)] + except KeyError: + res = _cache[id(frame.code)] = pydis.pydis(frame.code) + assert res is not None + return res + + def getbytecodes(self): + for event in self.events: + if isinstance(event, ExecBytecode): + disres = self.getdisresult(event.frame) + yield disres.getbytecode(event.index) + + def getoperations(self): + for event in self.events: + if isinstance(event, (CallBegin, CallFinished, CallException)): + yield event + + def getevents(self): + for event in self.events: + yield event # __________________________________________________________________________ # # Tracer Proxy objects # __________________________________________________________________________ # -class ExecutionContextTracer: + +class ExecutionContextTracer(object): def __init__(self, result, ec): self.__ec = ec self.__result = result @@ -66,7 +102,7 @@ return self.__ec.leave(previous_ec) def bytecode_trace(self, frame): - "called just before execution of a bytecode." + """ called just before execution of a bytecode. """ self.__result.append(ExecBytecode(frame)) #def exception_trace(self, operror): @@ -74,7 +110,7 @@ # print "exception trace", operror # return self.__ec.exception_trace(operror) -class CallInfo: +class CallInfo(object): """ encapsulates a function call with its arguments. """ def __init__(self, name, func, args, kwargs): self.name = name @@ -82,7 +118,7 @@ self.args = args self.kwargs = kwargs -class CallableTracer: +class CallableTracer(object): def __init__(self, result, name, func): self.__result = result self.__name = name @@ -91,129 +127,77 @@ def __call__(self, *args, **kwargs): callinfo = CallInfo(self.__name, self.__func, args, kwargs) self.__result.append(CallBegin(callinfo)) - #print "calling into", self.__name, [type(x).__name__ for x in args] - #print args + try: res = self.__func(*args, **kwargs) except Exception, e: - #self.__result.append(CallException(e, callinfo)) + self.__result.append(CallException(callinfo, e)) raise else: - self.__result.append(CallFinished(callinfo)) + self.__result.append(CallFinished(callinfo, res)) return res def __getattr__(self, name): """ generically pass through everything we don't intercept. """ return getattr(self.__func, name) -class TraceObjSpace: - def __init__(self, space=None): - self.generalcache = {} - if space is None: - # make up a TrivialObjSpace by default - # ultimately, remove this hack and fix the -P option of tests - from pypy.objspace import trivial - space = trivial.TrivialObjSpace() - self.__space = space - self.settrace() - - def settrace(self): - self.__result = TraceResult(self) - - def getresult(self): - return self.__result - - def loadfromcache(self, key, builder): - # hiding self.__cache.loadfromcache so that builder() can be called - # on self instead of self.__space, ignore the operations it performs - try: - return self.generalcache[key] - except KeyError: - saved = self.__result - self.settrace() - try: - return self.generalcache.setdefault(key, builder(key, self)) - finally: - self.__result = saved - - def getexecutioncontext(self): - ec = self.__space.getexecutioncontext() - if isinstance(ec, ExecutionContextTracer): - return ec - return ExecutionContextTracer(self.__result, ec) - - def createexecutioncontext(self): - ec = self.__space.createexecutioncontext() - return ExecutionContextTracer(self.__result, ec) - - def __getattr__(self, name): - obj = getattr(self.__space, name) - if callable(obj) and not hasattr(obj, '__bases__'): - return CallableTracer(self.__result, name, obj) - return obj - -class TraceResult: - """ this is the state of tracing-in-progress. """ - def __init__(self, tracespace): - self.tracespace = tracespace - self.events = [] - - def append(self, arg): - self.events.append(arg) - - def getdisresult(self, frame, _cache = {}): - """ return (possibly cached) pydis result for the given frame. """ - try: - return _cache[id(frame.code)] - except KeyError: - res = _cache[id(frame.code)] = pydis.pydis(frame.code) - assert res is not None - return res - - def getbytecodes(self): - lastframe = None - for event in self.events: - #if isinstance(event, EnterFrame): - # lastframe = event.frame - if isinstance(event, ExecBytecode): - disres = self.getdisresult(event.frame) - yield disres.getbytecode(event.index) - - def getoperations(self): - for event in self.events: - #if isinstance(event, EnterFrame): - # lastframe = event.frame - if isinstance(event, CallBegin): - yield event.callinfo + def __str__(self): + return "%s - CallableTracer(%s)" % (self.__name, self.__func) + __repr = __str__ +# __________________________________________________________________________ +# +# Tracer factory +# __________________________________________________________________________ +# - def getevents(self): - for event in self.events: - yield event - +operations = None +def get_operations(): + global operations + if operations is None: + operations = dict([(r[0], r[0]) for r in ObjSpace.MethodTable]) + for name in ["is_true", "newtuple", "newlist", "newstring", "newdict", + "newslice", "call_args", "is_", "get_and_call_function", + "wrap", "unwrap"]: + operations[name] = name + + return operations + +def create_trace_space(space = None, operations = None): + """ Will create a trace object space if no space supplied. Otherwise + the object.""" + + if space is None: + # make up a TrivialObjSpace by default + # ultimately, remove this hack and fix the -P option of tests + from pypy.objspace import trivial + space = trivial.TrivialObjSpace() + + if operations is None: + operations = get_operations() + + class TraceObjSpace(space.__class__): + def __getattribute__(self, name): + obj = super(TraceObjSpace, self).__getattribute__(name) + if callable(obj) and name in operations: + return CallableTracer(self.__result, name, obj) + return obj + + def settrace(self): + self.__result = TraceResult(self) + + def getresult(self): + return self.__result + + def getexecutioncontext(self): + ec = super(TraceObjSpace, self).getexecutioncontext() + assert not isinstance(ec, ExecutionContextTracer) + return ExecutionContextTracer(self.__result, ec) + space.__class__ = TraceObjSpace + space.settrace() + return space -Space = TraceObjSpace +TraceObjSpace = Space = create_trace_space # ______________________________________________________________________ # End of trace.py -""" -def display(bytecodedict, codeobject): - for i in range(len(codeobject.co_bytecode)): - print display_bytecode(codeobject, i) - if i in bytecodedict: - for opinfo in bytecodedict[i]: - print display(*opinfo) - -class FrameIndex: - def __init__(self, frame, index): - self.frame = frame - self.index = index - - def __hash__(self): - return hash((id(frame), index)) - def _getframeindex(self): - frame = self.tracespace.space.getexecutioncontext().framestack[-1] - index = frame.next_instr - return FrameIndex(frame, index) - -""" Modified: pypy/trunk/src/pypy/tool/traceinteractive.py ============================================================================== --- pypy/trunk/src/pypy/tool/traceinteractive.py (original) +++ pypy/trunk/src/pypy/tool/traceinteractive.py Mon Jul 12 14:05:49 2004 @@ -12,7 +12,6 @@ except: have_readline = False - # PyPy imports import autopath @@ -24,9 +23,6 @@ from pypy.objspace import trace - -#////////////////////////////////////////////////////////////////////////// - if have_readline: class Completer: @@ -46,7 +42,6 @@ except IndexError: return None - def global_matches(self, text): import __builtin__ @@ -85,40 +80,33 @@ return matches - -#////////////////////////////////////////////////////////////////////////// - class TraceConsole(code.InteractiveConsole): def __init__(self, space): code.InteractiveConsole.__init__(self) - s = self.space = trace.TraceObjSpace(space) + s = self.space = trace.create_trace_space(space) s.setitem(s.w_globals, s.wrap("__pytrace__"), s.w_True) - self.objspacename = space.__class__.__name__ - + self.objspacename = space.__class__.__bases__[0].__name__ def interact(self, banner=None): if banner is None: - banner = "Python %s in pypy(trace)\n%s / %s - %s" % ( - sys.version, self.__class__.__name__, - self.space, - " [Use __pytrace__ flag to turn off tracing.]" ) + banner = "PyPy in TraceObjSpace(%s) on top of %s\n%s" % ( + self.objspacename, sys.version.split()[0], + " [Use __pytrace__ flag to turn off tracing]" ) code.InteractiveConsole.interact(self, banner) - def raw_input(self, prompt=""): # add a character to the PyPy prompt so that you know where you # are when you debug it with "python -i py.py" return code.InteractiveConsole.raw_input(self, prompt[0] + prompt) - def runcode(self, code): # 'code' is a CPython code object from pypy.interpreter.pycode import PyCode pycode = PyCode()._from_code(code) s = self.space - trace_flag = s.unwrap(s.getitem(s.w_globals, - s.wrap("__pytrace__"))) + trace_flag = s.is_true(s.getitem(s.w_globals, + s.wrap("__pytrace__"))) if trace_flag: s.settrace() @@ -127,23 +115,24 @@ if trace_flag: res = s.getresult() s.settrace() - print_result(res) + print_result(s, res) except baseobjspace.OperationError, operationerr: if trace_flag: res = s.getresult() s.settrace() - print_result(res) + print_result(s, res) # XXX insert exception info into the application-level sys.last_xxx print - operationerr.print_detailed_traceback(self.space) + operationerr.print_application_traceback(self.space) else: print def runsource(self, source, ignored_filename = "", symbol = "single"): - hacked_filename = '\n' + source + hacked_filename = ' ' + source[:80] + "..." + hacked_filename = hacked_filename.replace("\n", r"\n") try: code = self.compile(source, hacked_filename, symbol) @@ -157,9 +146,6 @@ self.runcode(code) return False - -#////////////////////////////////////////////////////////////////////////// - def trace_interactive(space, banner = None): s = space @@ -172,7 +158,6 @@ if have_readline: # Keep here to save windoze tears - readline.set_completer(Completer(s).complete) readline.parse_and_bind("tab: complete") readline.set_history_length(25000) @@ -188,15 +173,11 @@ console.interact(banner) - -#////////////////////////////////////////////////////////////////////////// - if __name__ == '__main__': from pypy.tool import option args = option.process_options(option.get_standard_options(), option.Options) - # Create objspace... space = option.objspace() trace_interactive(space) Modified: pypy/trunk/src/pypy/tool/traceop.py ============================================================================== --- pypy/trunk/src/pypy/tool/traceop.py (original) +++ pypy/trunk/src/pypy/tool/traceop.py Mon Jul 12 14:05:49 2004 @@ -1,33 +1,9 @@ + import autopath from pypy.tool import pydis -from pypy.interpreter.baseobjspace import ObjSpace from pypy.objspace import trace -from pypy.objspace.trace import TraceObjSpace -from pypy.objspace.trivial import TrivialObjSpace -from pypy.objspace.std import StdObjSpace - -from pypy.interpreter.gateway import app2interp - -# Global -operations = dict([(r[0], r[0]) for r in ObjSpace.MethodTable]) - - -def perform_trace(space, app_func, *args, **kwds): - # Wrap up our space, with a trace space - tspace = TraceObjSpace(space) - - # Add our function - func_gw = app2interp(app_func) - func = func_gw.get_function(tspace) - - # Run the func in the trace space and return results - tspace.settrace() - funcres = func(*args, **kwds) - traceres = tspace.getresult() - return funcres, traceres - def getdisresult(obj, _cache={}): """ return dissassemble result for the given obj which can be a pyframe or function or a code object. @@ -40,236 +16,137 @@ disresult = _cache[obj] = pydis.pydis(obj) return disresult -import repr -def get_repr(): - " Our own repr function for pretty print. " - repr_obj = repr.Repr() - repr_obj.maxstring = 120 - repr_obj.maxother = 120 - - def our_repr(*args): - try: - return repr_obj.repr(*args) - - except: - return "ERROR" - - return our_repr -Repr = get_repr() - def line_begin(indent): if indent: return (" " * indent) + "|-" else: return "" -def print_result(traceres): +def print_result(space, traceres, operations_level = 1000): + # XXX Refactor this - make more configurable. indentor = ' ' lastframe = None frame_count = 0 indent = "" + skip_frame_count = None + stack_info = [] for event in traceres.getevents(): + if isinstance(event, trace.EnterFrame): - print line_begin(frame_count) + ("<<<<>>>>>>" % event.frame) + if not skip_frame_count: + print line_begin(frame_count) + ("<<<<>>>>>>" % (event.frame.code.co_filename, event.frame.code.co_firstlineno)) + lastframe = event.frame frame_count += 1 + elif isinstance(event, trace.LeaveFrame): frame_count -= 1 - print line_begin(frame_count) + ("<<<<>>>>>>" % lastframe) - elif isinstance(event, trace.ExecBytecode): - disresult = getdisresult(event.frame) - print line_begin(frame_count), "%2d" % event.index, " ", disresult.getbytecode(event.index) - lastframe = event.frame - elif isinstance(event, trace.CallBegin): - info = event.callinfo - if info.name in operations: - print line_begin(frame_count), " " * 40, info.name, repr_args(lastframe, info.args) - indent += indentor - elif isinstance(event, trace.CallFinished): - indent = indent[:-len(indentor)] - else: - pass - + # No more bytecodes to skip at this level + if frame_count < skip_frame_count: + skip_frame_count = 0 -def trace_function(space, fn, *arg, **kwds): - - funcres, traceres = perform_trace(space, fn, *arg, **kwds) - indentor = ' ' - indent = ' ' - lastframe = None - for event in traceres.getevents(): - if isinstance(event, trace.EnterFrame): - lastframe = event.frame + if not skip_frame_count: + print line_begin(frame_count) + ("<<<<>>>>>>" % lastframe.code.co_filename) + elif isinstance(event, trace.ExecBytecode): + + if frame_count == skip_frame_count: + skip_frame_count = 0 - if isinstance(event, trace.ExecBytecode): disresult = getdisresult(event.frame) - print indent, event.index, " ", disresult.getbytecode(event.index) + bytecode = disresult.getbytecode(event.index) + + if not skip_frame_count: + print line_begin(frame_count), "%2d" % event.index, " ", bytecode lastframe = event.frame + if bytecode.name in ["PRINT_EXPR", "PRINT_ITEM", "PRINT_NEWLINE"]: + print line_begin(frame_count + 1), "..." + skip_frame_count = frame_count + elif isinstance(event, trace.CallBegin): info = event.callinfo - if info.name in operations: - print indent, " " * 40, info.name, repr_args(lastframe, info.args) - indent += indentor + if not skip_frame_count: + stack_info.append(info) + if len(stack_info) <= operations_level: + print line_begin(frame_count), " " * 17 + ">> ", info.name, repr_args(space, lastframe, info.args) + frame_count += 1 + elif isinstance(event, trace.CallFinished): - indent = indent[:-len(indentor)] + info = event.callinfo + if not skip_frame_count: + assert stack_info.pop(-1) == event.callinfo + frame_count -= 1 + if len(stack_info) < operations_level: + print line_begin(frame_count), " " * 20, info.name, "=: ", repr_value(space, event.res) + + elif isinstance(event, trace.CallException): + info = event.callinfo + if not skip_frame_count: + assert stack_info.pop(-1) == event.callinfo + frame_count -= 1 + if len(stack_info) < operations_level: + print line_begin(frame_count), " " * 17 + "x= ", info.name, event.ex else: pass - return funcres, traceres + +def repr_value(space, value): +## try: +## res = str(space.unwrap(value)) +## except: +## res = str(value) + res = str(value) + return res[:240] -def repr_args(frame, args): +def repr_args(space, frame, args): l = [] - - space = frame and frame.space or None for arg in args: if frame and space.is_true(space.is_(arg, frame.w_globals)): l.append('w_globals') elif frame and space.is_true(space.is_(arg, space.w_builtins)): l.append('w_builtins') else: - l.append(Repr(arg) [:50]) - return ", ".join(l) + l.append(repr_value(space, arg)) + + return "(" + ", ".join(l) + ")" -def app_test(): - a = 1 - for i in range(10): - print i - -def test(): - space = TrivialObjSpace() - #space = StdObjSpace() - +def perform_trace(tspace, app_func, *args_w, **kwds_w): + from pypy.interpreter.gateway import app2interp + from pypy.interpreter.argument import Arguments - funcres, traceres = trace_function(space, app_test) - print "function result -->", funcres + # Create our function + func_gw = app2interp(app_func) + func = func_gw.get_function(tspace) + w_func = tspace.wrap(func) + args = Arguments(tspace, args_w, kwds_w) -## from earthenware.utils.stacktrace -## try: -## test() -## except: -## earthenware.utils.stacktrace.print_exception(sys. - -## def rpretty_print(spacedump): -## " Pretty print for rdump() calls to Trace object spaces. " - -## Repr = get_repr() -## for operation, bytecodes in spacedump: -## for opcode, opname, oparg, ins_idx in bytecodes: -## print "\t%s\t%s\t\t%s" % (ins_idx, opname, oparg) - -## if operation is not None: -## op_name = operation[0] -## args = operation[1:] -## print " ***\t", op_name, " ->", -## for a in args: -## print Repr(a), -## print - - -## def add_func(space, func, w_globals): -## """ Add a function to globals. """ -## func_name = func.func_name -## w_func_name = space.wrap(func_name) -## w_func = space.wrap(func) -## space.setitem(w_globals, w_func_name, w_func) - - -## def run_in_space(space, func, *args): -## # Get execution context and globals -## ec = space.getexecutioncontext() -## w_globals = ec.make_standard_w_globals() - -## # Add the function to globals -## add_func(space, func, w_globals) - -## # Create wrapped args -## args_w = [space.wrap(ii) for ii in args] -## code = func.func_code -## code = PyCode()._from_code(code) - -## # Create frame -## frame = code.create_frame(space, w_globals) -## frame.setfastscope(args_w) - -## # start/stop tracing while running frame -## space.start_tracing() -## res = frame.run() -## space.stop_tracing() - -## return res - - -## def pretty_print(spacedump): -## " Pretty print for rdump() calls to Trace object spaces. " -## Repr = get_repr() - -## for line in spacedump: -## ((opcode, opname, arg, ins_idx), spaceops) = line -## start = "%4i %s " % (ins_idx, opname) -## start = start + " " * (20 - len(start)) + str(arg) -## start = start + " " * (30 - len(start)) -## if not spaceops: -## print start -## else: -## op = spaceops.pop(0) -## print start -## for op_name, args in spaceops: -## print " " * 30, op_name, Repr(args) - - -## def _trace_function(space, reverse_pretty_print_flag, fn, *arg, **kwds): -## res = run_in_space(space, fn, *arg, **kwds) -## if reverse_pretty_print_flag: -## # Get reverse dump -## spacedump = space.rdump() - -## # Pretty print dump -## rpretty_print(spacedump) -## else: -## # Get dump -## spacedump = space.dump() - -## # Pretty dump -## pretty_print(spacedump) - -## return res - -## def trace_function(trace_space, fn, *arg, **kwds): -## return _trace_function(trace_space, False, fn, *arg, **kwds) - -## def rtrace_function(trace_space, fn, *arg, **kwds): -## return _trace_function(trace_space, True, fn, *arg, **kwds) - - -## def trace_function2(space, fn, *arg, **kwds): -## return _trace_function(Trace(space), False, fn, *arg, **kwds) - -## def rtrace_function2(space, fn, *arg, **kwds): -## return _trace_function(Trace(space), True, fn, *arg, **kwds) - - - - -## ## # Create space -## ## if __name__ == "__main__": -## ## try: -## ## import readline -## ## except ImportError: -## ## pass - -## ## from pypy.tool import option -## ## from pypy.tool import testit -## ## args = option.process_options(option.get_standard_options(), -## ## option.Options) -## ## objspace = option.objspace() - - -## ## def run(*args, **kwds): -## ## def run_function(space, func, *args): -## ## from pypy.objspace.std import StdObjSpace -## ## space = Trace(StdObjSpace) + # Run the func in the trace space and return results + tspace.settrace() + w_result = tspace.call_args(w_func, args) + trace_result = tspace.getresult() + tspace.settrace() + return w_result, trace_result + + +if __name__ == '__main__': + from pypy.tool import option + args = option.process_options(option.get_standard_options(), + option.Options) + + # Create objspace... + space = option.objspace() + + # Wrap up our space, with a trace space + tspace = trace.create_trace_space(space) + def app_test(x): + count = 0 + for ii in range(x): + count += ii + return count + res, traceres = perform_trace(tspace, app_test, tspace.wrap(5)) + print_result(tspace, traceres) + print "Result", res From rxe at codespeak.net Mon Jul 12 14:06:24 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Mon, 12 Jul 2004 14:06:24 +0200 (MEST) Subject: [pypy-svn] r5534 - pypy/trunk/src/pypy/interpreter Message-ID: <20040712120624.4B8115B3E2@thoth.codespeak.net> Author: rxe Date: Mon Jul 12 14:06:23 2004 New Revision: 5534 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py Log: Cosmetic. Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Mon Jul 12 14:06:23 2004 @@ -494,8 +494,6 @@ except OperationError, e: if not e.match(f.space, f.space.w_KeyError): raise - # rxe Why global??? - #message = "global name '%s' is not defined" % varname message = "name '%s' is not defined" % varname w_exc_type = f.space.w_NameError w_exc_value = f.space.wrap(message) From arigo at codespeak.net Tue Jul 13 11:58:39 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Jul 2004 11:58:39 +0200 (MEST) Subject: [pypy-svn] r5542 - in pypy/trunk/src/pypy/interpreter: . test Message-ID: <20040713095839.1F7775B4A4@thoth.codespeak.net> Author: arigo Date: Tue Jul 13 11:58:37 2004 New Revision: 5542 Modified: pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/test/test_function.py Log: Checking the number of arguments in performance_shortcut_call(). Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Tue Jul 13 11:58:37 2004 @@ -10,7 +10,7 @@ """ -import types +import types, sys from pypy.interpreter import eval, pycode from pypy.interpreter.function import Function, Method from pypy.interpreter.baseobjspace import Wrappable @@ -76,6 +76,11 @@ argnames[i] = a[2:] self.sig = argnames, varargname, kwargname + self.minargs = len(argnames) + if self.starargs: + self.maxargs = sys.maxint + else: + self.maxargs = self.minargs def create_frame(self, space, w_globals, closure=None): return BuiltinFrame(space, self, w_globals) @@ -91,6 +96,8 @@ if self.generalargs or args.kwds_w: return None args_w = args.args_w + if not (self.minargs <= len(args_w) <= self.maxargs): + return None if self.ismethod: if not args_w: return None @@ -114,6 +121,8 @@ else: if args.kwds_w: return None + if not (self.minargs <= 1+len(args.args_w) <= self.maxargs): + return None if self.ismethod: w_obj = space.unwrap(w_obj) # abuse name w_obj if self.spacearg: Modified: pypy/trunk/src/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_function.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_function.py Tue Jul 13 11:58:37 2004 @@ -136,6 +136,18 @@ meth = func.__get__(obj, object) self.assertEquals(meth(), obj) + def test_call_builtin(self): + s = 'hello' + self.assertRaises(TypeError, len) + self.assertEquals(len(s), 5) + self.assertRaises(TypeError, len, s, s) + self.assertRaises(TypeError, len, s, s, s) + self.assertEquals(len(*[s]), 5) + self.assertEquals(len(s, *[]), 5) + self.assertRaises(TypeError, len, some_unknown_keyword=s) + self.assertRaises(TypeError, len, s, some_unknown_keyword=s) + self.assertRaises(TypeError, len, s, s, some_unknown_keyword=s) + class AppTestMethod(testit.AppTestCase): def test_get(self): From arigo at codespeak.net Tue Jul 13 12:13:59 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 13 Jul 2004 12:13:59 +0200 (MEST) Subject: [pypy-svn] r5543 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040713101359.2CC035AA51@thoth.codespeak.net> Author: arigo Date: Tue Jul 13 12:13:58 2004 New Revision: 5543 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: Added two failing tests to point to bugs in string formatting. String formatting is really slow with all this app-level code... Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Tue Jul 13 12:13:58 2004 @@ -83,6 +83,18 @@ self.assertEquals('23', '%s' % 23) self.assertEquals('23', '%r' % 23) + def test_format_list(self): + self.assertEquals('<[1, 2]>', '<%s>' % [1,2]) + self.assertEquals('<[1, 2]-[3, 4]>', '<%s-%s>' % ([1,2], [3,4])) + + def test_format_tuple(self): + self.assertEquals('<(1, 2)>', '<%s>' % ((1,2),)) + self.assertEquals('<(1, 2)-(3, 4)>', '<%s-%s>' % ((1,2), (3,4))) + + def test_format_dict(self): + self.assertEquals('<{1: 2}>', '<%s>' % {1:2}) + self.assertEquals('<{1: 2}-{3: 4}>', '<%s-%s>' % ({1:2}, {3:4})) + def test_format_wrong_char(self): self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) From mwh at codespeak.net Wed Jul 14 12:29:09 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 14 Jul 2004 12:29:09 +0200 (MEST) Subject: [pypy-svn] r5554 - in pypy/trunk/src/pypy: appspace objspace/std Message-ID: <20040714102909.1E0B85A64F@thoth.codespeak.net> Author: mwh Date: Wed Jul 14 12:29:08 2004 New Revision: 5554 Modified: pypy/trunk/src/pypy/appspace/_formatting.py pypy/trunk/src/pypy/objspace/std/stringobject.py Log: make arigo's tests pass (and that's it: i haven't really attempted to understand anything here) Modified: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_formatting.py Wed Jul 14 12:29:08 2004 @@ -203,7 +203,8 @@ except StopIteration: pass else: - raise TypeError('not all arguments converted ' - 'during string formatting') + if valuedict is None: + raise TypeError('not all arguments converted ' + 'during string formatting') return ''.join(r) Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Wed Jul 14 12:29:08 2004 @@ -976,8 +976,9 @@ if isinstance(values, tuple): return _formatting.format(format, values, None) else: - if hasattr(values, '__getitem__') and not isinstance(values, str): - return _formatting.format(format, (), values) + if hasattr(values, '__getitem__') and \ + not isinstance(values, (str, list)): + return _formatting.format(format, (values,), values) else: return _formatting.format(format, (values,), None) From mwh at codespeak.net Wed Jul 14 14:27:03 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 14 Jul 2004 14:27:03 +0200 (MEST) Subject: [pypy-svn] r5555 - in pypy/trunk/src/pypy/interpreter: . test Message-ID: <20040714122703.AD30B5A64F@thoth.codespeak.net> Author: mwh Date: Wed Jul 14 14:27:03 2004 New Revision: 5555 Modified: pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/test/test_class.py pypy/trunk/src/pypy/interpreter/typedef.py Log: fix the fact that methods had no __doc__ i think this is the Right Way to do it, if not, advice appreciated! Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Wed Jul 14 14:27:03 2004 @@ -115,6 +115,12 @@ def descr_method_call(self, __args__): return self.call_args(__args__) + def descr_method_getattribute(self, w_attr): + space = self.space + w_result = space.lookup(space.wrap(self), w_attr) + if w_result is None: + return space.getattr(self.w_function, w_attr) + class StaticMethod(Wrappable): """A static method. Note that there is one class staticmethod at app-level too currently; this is only used for __new__ methods.""" Modified: pypy/trunk/src/pypy/interpreter/test/test_class.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_class.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_class.py Wed Jul 14 14:27:03 2004 @@ -113,5 +113,18 @@ self.assertEquals(type(float(x)), float) self.assertEquals(float(x), 5.5) + def test_meth_doc(self): + class C: + def meth_no_doc(self): + pass + def meth_doc(self): + """this is a docstring""" + pass + c = C() + self.assertEquals(C.meth_no_doc.__doc__, None) + self.assertEquals(c.meth_no_doc.__doc__, None) + self.assertEquals(C.meth_doc.__doc__, """this is a docstring""") + self.assertEquals(c.meth_doc.__doc__, """this is a docstring""") + if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Wed Jul 14 14:27:03 2004 @@ -237,6 +237,7 @@ im_func = attrproperty_w('w_function'), im_self = attrproperty_w('w_instance'), im_class = attrproperty_w('w_class'), + __getattribute__ = interp2app(Method.descr_method_getattribute.im_func), # XXX getattribute/setattribute etc.pp ) From mwh at codespeak.net Wed Jul 14 17:55:12 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 14 Jul 2004 17:55:12 +0200 (MEST) Subject: [pypy-svn] r5563 - pypy/trunk/src/pypy/interpreter Message-ID: <20040714155512.9FC075A64F@thoth.codespeak.net> Author: mwh Date: Wed Jul 14 17:55:12 2004 New Revision: 5563 Modified: pypy/trunk/src/pypy/interpreter/function.py Log: Man, that was broken in a variety of ways! Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Wed Jul 14 17:55:12 2004 @@ -117,9 +117,12 @@ def descr_method_getattribute(self, w_attr): space = self.space - w_result = space.lookup(space.wrap(self), w_attr) + w_self = space.wrap(self) + w_result = space.lookup(w_self, space.unwrap(w_attr)) if w_result is None: return space.getattr(self.w_function, w_attr) + else: + return space.get(w_result, w_self) class StaticMethod(Wrappable): """A static method. Note that there is one class staticmethod at From mwh at codespeak.net Thu Jul 15 12:32:37 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 15 Jul 2004 12:32:37 +0200 (MEST) Subject: [pypy-svn] r5583 - in pypy/trunk/src/pypy: module objspace objspace/std objspace/std/test Message-ID: <20040715103237.615655AFCF@thoth.codespeak.net> Author: mwh Date: Thu Jul 15 12:32:35 2004 New Revision: 5583 Added: pypy/trunk/src/pypy/objspace/std/fake.py Removed: pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/test/test_cpythonobject.py Modified: pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/typeobject.py Log: This is the outcome of the 'die, cpythonobject die!' thread on pypy-dev. Few changes from the last posted version, most of which are in aid of getting faking unicode to work. Now would be a good time to implement basestring and have str inherit from it, methinks. Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 15 12:32:35 2004 @@ -10,8 +10,9 @@ __builtins__['__debug__'] = True object = __interplevel__eval('space.w_object') -basestring = str # XXX until we have unicode - +# XXX these are faked: +basestring = __interplevel__eval('space.wrap(basestring)') +unicode = __interplevel__eval('space.wrap(unicode)') # TODO Fix this later to show Ctrl-D on Unix quit = exit = "Use Ctrl-Z (i.e. EOF) to exit." Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Thu Jul 15 12:32:35 2004 @@ -52,6 +52,8 @@ def descr__init__(space, w_obj, __args__): pass # XXX some strange checking maybe +SlotWrapper = type(None).__repr__ + class DescrOperation: def getdict(space, w_obj): @@ -62,15 +64,17 @@ def get_and_call_args(space, w_descr, w_obj, args): descr = space.unwrap_builtin(w_descr) + # some special cases to avoid infinite recursion if type(descr) is Function: - # special-case Functions to avoid infinite recursion if isinstance(descr.code, BuiltinCode): # this sub-special case is ONLY for performance reasons - w_result = descr.code.performance_shortcut_call_meth(space, - w_obj, args) + w_result = descr.code.performance_shortcut_call_meth( + space, w_obj, args) if w_result is not None: return w_result return descr.call_args(args.prepend(w_obj)) + elif type(descr) is type(space.wrap(SlotWrapper)): + return descr.call_args(args.prepend(w_obj)) else: w_impl = space.get(w_descr, w_obj) return space.call_args(w_impl, args) Deleted: /pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- /pypy/trunk/src/pypy/objspace/std/cpythonobject.py Thu Jul 15 12:32:35 2004 +++ (empty file) @@ -1,380 +0,0 @@ -""" -""" - -from pypy.objspace.std.objspace import * -from pypy.interpreter.function import Function -from pypy.objspace.std.default import UnwrapError -import sys, operator, types - -class W_BuiltinFunctionObject(Function): - """This class wraps cpython-functions much like ordinary 'Function' objects - but it avoids wrapping them into CPythonObject which would go badly - with the descroperations. """ - - def __init__(self, space, cpyfunc): - assert callable(cpyfunc), cpyfunc - self.space = space - self.cpyfunc = cpyfunc - - def call_args(self, args): - space = self.space - try: - unwrappedargs = [space.unwrap(w_arg) for w_arg in args.args_w] - unwrappedkwds = dict([(key, space.unwrap(w_value)) - for key, w_value in args.kwds_w.items()]) - except UnwrapError, e: - raise UnwrapError('calling %s: %s' % (self.cpyfunc, e)) - try: - result = apply(self.cpyfunc, unwrappedargs, unwrappedkwds) - except: - wrap_exception(space) - return space.wrap(result) - -class W_CPythonObject(W_Object): - "This class wraps an arbitrary CPython object." - - def __init__(w_self, space, cpyobj): - W_Object.__init__(w_self, space) - w_self.cpyobj = cpyobj - w_self.w_cpytype = None - - def __repr__(w_self): - """ representation for debugging purposes """ - return "cpyobj(%r)" % (w_self.cpyobj,) - - def getclass(w_self, space): - if w_self.w_cpytype is None: - try: - w_self.w_cpytype = space.wrap(w_self.cpyobj.__class__) - except AttributeError: # no __class__! - w_self.w_cpytype = space.wrap(type(w_self.cpyobj)) - return w_self.w_cpytype - - def lookup(w_self, name): - # hack for wrapped CPython types - cls = w_self.cpyobj - if isinstance(cls, type): - for base in cls.__mro__: - if name in base.__dict__: - return w_self.space.wrap(base.__dict__[name]) - return None - elif isinstance(cls, types.ClassType): - while True: - if name in cls.__dict__: - return w_self.space.wrap(base.__dict__[name]) - if not cls.__bases__: - return None - cls, = cls.__bases__ # no old-style multiple inheritance - else: - raise TypeError, '%r is not a class' % (cls,) - -registerimplementation(W_CPythonObject) - - -def cpython_unwrap(space, w_obj): - cpyobj = w_obj.cpyobj - #if hasattr(type(cpyobj), '__unwrap__'): - # cpyobj = cpyobj.__unwrap__() - return cpyobj - -StdObjSpace.unwrap.register(cpython_unwrap, W_CPythonObject) - -# XXX we hack a bit to delegate ints to longs here -#def hacky_delegate_to_long(space, w_intobj): -# return space.wrap(long(w_intobj.intval)) -#hacky_delegate_to_long.result_class = W_CPythonObject # XXX -#hacky_delegate_to_long.priority = PRIORITY_CHANGE_TYPE + 0.1 # XXX too -#StdObjSpace.delegate.register(hacky_delegate_to_long, W_IntObject) - - -# XXX XXX XXX -# std space lookup now *refers directly* to the cpython descriptors -# so the multimethods implementations here are not reachable -# nor used, except for things implemented as multimethod directly on the space -# not through descriptors in DescrOperation -# -# delegate -# id -# issubtype -# ord -# round -# unwrap -# -# TODO kill - - - -# real-to-wrapped exceptions -def wrap_exception(space): - exc, value, tb = sys.exc_info() - if exc is OperationError: - raise exc, value, tb # just re-raise it - name = exc.__name__ - if hasattr(space, 'w_' + name): - w_exc = getattr(space, 'w_' + name) - w_value = space.call_function(w_exc, - *[space.wrap(a) for a in value.args]) - for key, value in value.__dict__.items(): - if not key.startswith('_'): - space.setattr(w_value, space.wrap(key), space.wrap(value)) - else: - w_exc = space.wrap(exc) - w_value = space.wrap(value) - raise OperationError, OperationError(w_exc, w_value), tb - -# in-place operators -def inplace_pow(x1, x2): - x1 **= x2 - return x1 -def inplace_mul(x1, x2): - x1 *= x2 - return x1 -def inplace_truediv(x1, x2): - x1 /= x2 # XXX depends on compiler flags - return x1 -def inplace_floordiv(x1, x2): - x1 //= x2 - return x1 -def inplace_div(x1, x2): - x1 /= x2 # XXX depends on compiler flags - return x1 -def inplace_mod(x1, x2): - x1 %= x2 - return x1 - -def inplace_add(x1, x2): - x1 += x2 - return x1 -def inplace_sub(x1, x2): - x1 -= x2 - return x1 -def inplace_lshift(x1, x2): - x1 <<= x2 - return x1 -def inplace_rshift(x1, x2): - x1 >>= x2 - return x1 -def inplace_and(x1, x2): - x1 &= x2 - return x1 -def inplace_or(x1, x2): - x1 |= x2 - return x1 -def inplace_xor(x1, x2): - x1 ^= x2 - return x1 - -def getter(o, i, c): - if hasattr(o, '__get__'): - return o.__get__(i, c) - else: - return o - -# regular part of the interface (minus 'next' and 'call') -MethodImplementation = { - 'id': id, - 'type': type, -# 'issubtype': see below, - 'repr': repr, - 'str': str, - 'len': len, - 'hash': hash, - 'getattr': getattr, - 'setattr': setattr, - 'delattr': delattr, -# 'getitem': see below, -# 'setitem': see below, -# 'delitem': see below, - 'pos': operator.pos, - 'neg': operator.neg, - 'abs': operator.abs, - 'hex': hex, - 'oct': oct, - 'ord': ord, - 'invert': operator.invert, - 'add': operator.add, - 'sub': operator.sub, - 'mul': operator.mul, - 'truediv': operator.truediv, - 'floordiv': operator.floordiv, - 'div': operator.div, - 'mod': operator.mod, - 'divmod': divmod, - 'pow': pow, - 'lshift': operator.lshift, - 'rshift': operator.rshift, - 'and_': operator.and_, - 'or_': operator.or_, - 'xor': operator.xor, - 'int': int, - 'float': float, - 'inplace_add': inplace_add, - 'inplace_sub': inplace_sub, - 'inplace_mul': inplace_mul, - 'inplace_truediv': inplace_truediv, - 'inplace_floordiv': inplace_floordiv, - 'inplace_div': inplace_div, - 'inplace_mod': inplace_mod, - 'inplace_pow': inplace_pow, - 'inplace_lshift': inplace_lshift, - 'inplace_rshift': inplace_rshift, - 'inplace_and': inplace_and, - 'inplace_or': inplace_or, - 'inplace_xor': inplace_xor, - 'lt': operator.lt, - 'le': operator.le, - 'eq': operator.eq, - 'ne': operator.ne, - 'gt': operator.gt, - 'ge': operator.ge, - 'contains': operator.contains, - 'iter': iter, - 'get': getter, -# 'set': setter, -# 'delete': deleter, - } - -for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - f = MethodImplementation.get(_name) - if f: - if _arity == 1: - def cpython_f(space, w_1, f=f): - x1 = w_1.cpyobj - type_x1 = type(x1) - try: - y = f(x1) - except: - wrap_exception(space) - return space.wrap(y) - elif _arity == 2: - def cpython_f(space, w_1, w_2, f=f): - x1 = w_1.cpyobj - type_x1 = type(x1) - # XXX do we really want to unwrap unknown objects here? - x2 = space.unwrap(w_2) - try: - y = f(x1, x2) - except: - wrap_exception(space) - return space.wrap(y) - elif _arity == 3: - def cpython_f(space, w_1, w_2, w_3, f=f): - x1 = w_1.cpyobj - type_x1 = type(x1) - x2 = space.unwrap(w_2) - x3 = space.unwrap(w_3) - try: - y = f(x1, x2, x3) - except: - wrap_exception(space) - return space.wrap(y) - else: - raise ValueError, '_arity too large' - - arglist = [W_CPythonObject] + [W_ANY]*(_arity-1) - #if _name == 'getattr': _name = 'getattribute' # XXX hack - multimethod = getattr(StdObjSpace.MM, _name) - multimethod.register(cpython_f, *arglist) - - if len(multimethod.specialnames) > 1 and _arity == 2: - def cpython_f_rev(space, w_1, w_2, f=f): - # XXX do we really want to unwrap unknown objects here? - x1 = space.unwrap(w_1) - x2 = w_2.cpyobj - try: - y = f(x1, x2) - except: - wrap_exception(space) - return space.wrap(y) - multimethod.register(cpython_f_rev, W_ANY, W_CPythonObject) - -def nonzero__CPython(space, w_obj): - obj = space.unwrap(w_obj) - try: - return space.newbool(operator.truth(obj)) - except: - wrap_exception(space) - - -# slicing -def old_slice(index): - # return the (start, stop) indices of the slice, or None - # if the w_index is not a slice or a slice with a step - # this is no longer useful in Python 2.3 - if isinstance(index, types.SliceType): - if index.step is None or index.step == 1: - start, stop = index.start, index.stop - if start is None: start = 0 - if stop is None: stop = sys.maxint - return start, stop - return None - -def getitem__CPython_ANY(space, w_obj, w_index): - obj = space.unwrap(w_obj) - index = space.unwrap(w_index) - sindex = old_slice(index) - try: - if sindex is None: - result = obj[index] - else: - result = operator.getslice(obj, sindex[0], sindex[1]) - except: - wrap_exception(space) - return space.wrap(result) - -def setitem__CPython_ANY_ANY(space, w_obj, w_index, w_value): - obj = space.unwrap(w_obj) - index = space.unwrap(w_index) - value = space.unwrap(w_value) - sindex = old_slice(index) - try: - if sindex is None: - obj[index] = value - else: - operator.setslice(obj, sindex[0], sindex[1], value) - except: - wrap_exception(space) - -def delitem__CPython_ANY(space, w_obj, w_index): - obj = space.unwrap(w_obj) - index = space.unwrap(w_index) - sindex = old_slice(index) - try: - if sindex is None: - del obj[index] - else: - operator.delslice(obj, sindex[0], sindex[1]) - except: - wrap_exception(space) - -def next__CPython(space, w_obj): - obj = space.unwrap(w_obj) - try: - result = obj.next() - except: - wrap_exception(space) - return space.wrap(result) - -def call__CPython(space, w_obj, w_arguments, w_keywords): - # XXX temporary hack similar to objspace.trivial.call() - callable = space.unwrap(w_obj) - args = space.unwrap(w_arguments) - keywords = space.unwrap(w_keywords) - try: - result = apply(callable, args, keywords) - except: - import sys - wrap_exception(space) - return space.wrap(result) - -def issubtype__CPython_ANY(space, w_obj, w_other): - return space.newbool(0) - -def issubtype__ANY_CPython(space, w_obj, w_other): - return space.newbool(0) - -def issubtype__CPython_CPython(space, w_obj, w_other): - return space.newbool(issubclass(space.unwrap(w_obj), - space.unwrap(w_other))) - -register_all(vars()) Added: pypy/trunk/src/pypy/objspace/std/fake.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/fake.py Thu Jul 15 12:32:35 2004 @@ -0,0 +1,77 @@ +from pypy.interpreter.error import OperationError +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objspace import W_Object +from pypy.objspace.std.default import UnwrapError + +# this file automatically generates non-reimplementations of CPython +# types that we do not yet implement in the standard object space +# (files being the biggy) + +import sys + +# real-to-wrapped exceptions +def wrap_exception(space): + exc, value, tb = sys.exc_info() + if exc is OperationError: + raise exc, value, tb # just re-raise it + name = exc.__name__ + if hasattr(space, 'w_' + name): + w_exc = getattr(space, 'w_' + name) + w_value = space.call_function(w_exc, + *[space.wrap(a) for a in value.args]) + for key, value in value.__dict__.items(): + if not key.startswith('_'): + space.setattr(w_value, space.wrap(key), space.wrap(value)) + else: + w_exc = space.wrap(exc) + w_value = space.wrap(value) + raise OperationError, OperationError(w_exc, w_value), tb + +def fake_type(space, cpy_type): + assert type(cpy_type) is type + kw = {} + for s, v in cpy_type.__dict__.items(): + kw[s] = v + def fake__new__(space, w_type, *args_w): + args = [space.unwrap(w_arg) for w_arg in args_w] + try: + r = cpy_type.__new__(cpy_type, *args) + except: + wrap_exception(space) + return W_Fake(space, r) + def fake_unwrap(space, w_obj): + return w_obj.val + kw['__new__'] = gateway.interp2app(fake__new__) + if cpy_type.__base__ is not object: + base = space.wrap(cpy_type.__base__).instancetypedef + else: + base = None + class W_Fake(W_Object): + typedef = StdTypeDef( + cpy_type.__name__, base, **kw) + def __init__(w_self, space, val): + W_Object.__init__(w_self, space) + w_self.val = val + space.__class__.unwrap.register(fake_unwrap, W_Fake) + W_Fake.__name__ = 'W_Fake(%s)'%(cpy_type.__name__) + W_Fake.typedef.fakedcpytype = cpy_type + # XXX obviously this entire file is something of a hack, but it + # manages to get worse here: + if cpy_type is type(type(None).__repr__): + def call_args(self, args): + try: + unwrappedargs = [space.unwrap(w_arg) for w_arg in args.args_w] + unwrappedkwds = dict([(key, space.unwrap(w_value)) + for key, w_value in args.kwds_w.items()]) + except UnwrapError, e: + raise UnwrapError('calling %s: %s' % (cpy_type, e)) + try: + assert callable(self.val), self.val + result = apply(self.val, unwrappedargs, unwrappedkwds) + except: + wrap_exception(space) + return space.wrap(result) + + setattr(W_Fake, "call_args", call_args) + return W_Fake + Modified: pypy/trunk/src/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/std/objspace.py Thu Jul 15 12:32:35 2004 @@ -134,6 +134,8 @@ return done def initialize(self): + self.fake_type_cache = {} + # The object implementations that we want to 'link' into PyPy must be # imported here. This registers them into the multimethod tables, # *before* the type objects are built from these multimethod tables. @@ -150,13 +152,12 @@ from pypy.objspace.std import longobject from pypy.objspace.std import noneobject from pypy.objspace.std import iterobject - from pypy.objspace.std import cpythonobject # hack to avoid imports in the time-critical functions below global W_ObjectObject, W_BoolObject, W_IntObject, W_FloatObject global W_TupleObject, W_ListObject, W_DictObject, W_StringObject global W_TypeObject, W_SliceObject, W_LongObject, W_NoneObject global W_SeqIterObject - global W_CPythonObject, W_BuiltinFunctionObject + global W_FakeFile W_ObjectObject = objectobject.W_ObjectObject W_BoolObject = boolobject.W_BoolObject W_IntObject = intobject.W_IntObject @@ -170,10 +171,7 @@ W_LongObject = longobject.W_LongObject W_NoneObject = noneobject.W_NoneObject W_SeqIterObject = iterobject.W_SeqIterObject - W_CPythonObject = cpythonobject.W_CPythonObject - W_BuiltinFunctionObject = cpythonobject.W_BuiltinFunctionObject # end of hacks - # singletons self.w_None = W_NoneObject(self) self.w_False = W_BoolObject(self, False) @@ -197,6 +195,14 @@ setattr(self, 'w_' + typedef.name, w_type) for_builtins[typedef.name] = w_type + import fake + W_FakeFile = fake.fake_type(self, file) + + self.w_file = self.gettypeobject(W_FakeFile.typedef) + for_builtins['file'] = self.w_file + self.fake_type_cache[file] = W_FakeFile + + # exceptions for_builtins.update(self.clone_exception_hierarchy()) @@ -240,17 +246,26 @@ #print 'wrapping', x, '->', w_result return w_result # anything below this line is implicitly XXX'ed - SlotWrapperType = type(type(None).__repr__) - if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): - return W_BuiltinFunctionObject(self, x) if isinstance(x, type(Exception)) and issubclass(x, Exception): if hasattr(self, 'w_' + x.__name__): return getattr(self, 'w_' + x.__name__) - print "cpython wrapping %r" % (x,) - #if hasattr(x, '__bases__'): - # print "cpython wrapping a class %r (%s)" % (x, type(x)) - #raise TypeError, "cannot wrap classes" - return W_CPythonObject(self, x) + if isinstance(x, type): + if x in self.fake_type_cache: + return self.gettypeobject(self.fake_type_cache[x].typedef) + print 'faking %r'%(x,) + import fake + ft = fake.fake_type(self, x) + self.fake_type_cache[x] = ft + return self.gettypeobject(self.fake_type_cache[x].typedef) + if type(x) in self.fake_type_cache: + ft = self.fake_type_cache[type(x)] + return ft(self, x) + else: + print 'faking %r'%(type(x),) + import fake + ft = fake.fake_type(self, type(x)) + self.fake_type_cache[type(x)] = ft + return ft(self, x) def newint(self, intval): return W_IntObject(self, intval) @@ -335,14 +350,8 @@ def is_(self, w_one, w_two): # XXX a bit of hacking to gain more speed - # if w_one is w_two: return self.w_True - if isinstance(w_one, W_CPythonObject): - if isinstance(w_two, W_CPythonObject): - if w_one.cpyobj is w_two.cpyobj: - return self.w_True - return self.newbool(self.unwrap(w_one) is self.unwrap(w_two)) return self.w_False def is_true(self, w_obj): @@ -353,26 +362,19 @@ return DescrOperation.is_true(self, w_obj) def hash(space, w_obj): - if isinstance(w_obj, W_CPythonObject): - try: - return space.newint(hash(w_obj.cpyobj)) - except: - from pypy.objspace.std import cpythonobject - cpythonobject.wrap_exception(space) - else: - w = space.wrap - eq = '__eq__' - ne = '__ne__' - hash_s = '__hash__' - - for w_t in space.type(w_obj).mro_w: - d = w_t.dict_w - if hash_s in d: - w_descr = d[hash_s] - return space.get_and_call_function(w_descr, w_obj) - if eq in d: - raise OperationError(space.w_TypeError, w("unhashable type")) - return space.id(w_obj) + w = space.wrap + eq = '__eq__' + ne = '__ne__' + hash_s = '__hash__' + + for w_t in space.type(w_obj).mro_w: + d = w_t.dict_w + if hash_s in d: + w_descr = d[hash_s] + return space.get_and_call_function(w_descr, w_obj) + if eq in d: + raise OperationError(space.w_TypeError, w("unhashable type")) + return space.id(w_obj) # add all regular multimethods to StdObjSpace for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: Deleted: /pypy/trunk/src/pypy/objspace/std/test/test_cpythonobject.py ============================================================================== --- /pypy/trunk/src/pypy/objspace/std/test/test_cpythonobject.py Thu Jul 15 12:32:35 2004 +++ (empty file) @@ -1,90 +0,0 @@ -import unittest, sys, array -import autopath -from pypy.tool import testit -from pypy.objspace.std import cpythonobject -from pypy.objspace.std.objspace import OperationError - - -class TestW_CPythonObject(testit.TestCase): - - def setUp(self): - self.space = testit.objspace('std') - # arbitrary always-wrapped object - self.stuff = array.array('b', [5,-2,77]) - - def tearDown(self): - pass - - def test_unary(self): - w1 = self.space.wrap(self.stuff) - for op, expected in [ - ('id', id(self.stuff)), - ('type', array.ArrayType), - ('len', 3), - ('repr', "array('b', [5, -2, 77])"), - ('str', "array('b', [5, -2, 77])"), - ]: - w_result = getattr(self.space, op)(w1) - self.assertEquals(self.space.unwrap(w_result), expected) - - def test_binary(self): - w1 = self.space.wrap(self.stuff) - for op, w_arg, expected in [ -# ('getattr', self.space.wrap('count'), self.stuff.count), - ('getitem', self.space.wrap(1), -2), - ('getitem', self.space.wrap(slice(1,2)), array.array('b', [-2])), - ]: - w_result = getattr(self.space, op)(w1, w_arg) - self.assertEquals(self.space.unwrap(w_result), expected) - - def test_unaryop(self): - w1 = self.space.wrap(3+4j) - for op, expected in [ - ('pos', 3+4j), - ('neg', -3-4j), - ('not_', False), - ('abs', 5.0), - ('hash', hash(3+4j)), - ]: - w_result = getattr(self.space, op)(w1) - self.assertEquals(self.space.unwrap(w_result), expected) - - def test_binaryop(self): - w1 = self.space.wrap(3+4j) - w2 = self.space.wrap(1-2j) - for op, expected in [ - ('add', (3+4j) + (1-2j)), - ('sub', (3+4j) - (1-2j)), - ('mul', (3+4j) * (1-2j)), - ('div', (3+4j) / (1-2j)), - ('eq', False), - ('ne', True), - ]: - w_result = getattr(self.space, op)(w1, w2) - self.assertEquals(self.space.unwrap(w_result), expected) - - def test_unhashable(self): - w1 = self.space.wrap(self.stuff) - self.assertRaises(OperationError, self.space.hash, w1) - try: self.space.hash(w1) - except OperationError, e: - self.assertEquals(e.w_type, self.space.w_TypeError) - - def test_hashable(self): - uw = 3+4j - w1 = self.space.wrap(uw) - hash_result = self.space.hash(w1) - self.assertEquals(self.space.unwrap(hash_result), hash(uw)) - - def test_call(self): - w1 = self.space.wrap(len) - w_result = self.space.call_function(w1, self.space.wrap("hello world")) - self.assertEquals(self.space.unwrap(w_result), 11) - - def test_next(self): - # create something with a next - nx = self.space.wrap(iter(self.stuff)) - self.assertEqual_w(self.space.wrap(5), self.space.next(nx)) - -if __name__ == '__main__': - testit.main() Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/typeobject.py Thu Jul 15 12:32:35 2004 @@ -137,6 +137,11 @@ # XXX __delattr__ # XXX __hash__ ?? +def unwrap__Type(space, w_type): + if hasattr(w_type.instancetypedef, 'fakedcpytype'): + return w_type.instancetypedef.fakedcpytype + raise FailedToImplement + # ____________________________________________________________ def compute_C3_mro(cls): From mwh at codespeak.net Thu Jul 15 12:41:36 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 15 Jul 2004 12:41:36 +0200 (MEST) Subject: [pypy-svn] r5584 - in pypy/trunk/src/pypy: module objspace/std Message-ID: <20040715104136.2D1045AFCF@thoth.codespeak.net> Author: mwh Date: Thu Jul 15 12:41:35 2004 New Revision: 5584 Modified: pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: There's nothing so special about files! Modified: pypy/trunk/src/pypy/module/__builtin__interp.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__interp.py (original) +++ pypy/trunk/src/pypy/module/__builtin__interp.py Thu Jul 15 12:41:35 2004 @@ -8,7 +8,6 @@ _noarg = object() import __builtin__ as cpy_builtin -w_file = space.wrap(cpy_builtin.file) # import useful app-level functions from __applevel__ import execfile, callable, _iter_generator Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 15 12:41:35 2004 @@ -13,6 +13,8 @@ # XXX these are faked: basestring = __interplevel__eval('space.wrap(basestring)') unicode = __interplevel__eval('space.wrap(unicode)') +file = __interplevel__eval('space.wrap(file)') +open = file # TODO Fix this later to show Ctrl-D on Unix quit = exit = "Use Ctrl-Z (i.e. EOF) to exit." @@ -446,9 +448,6 @@ from __interplevel__ import compile, eval from __interplevel__ import globals, locals, _caller_globals, _caller_locals -from __interplevel__ import file -from __interplevel__ import file as open - # The following must be the last import from __interplevel__ because it # overwrites the special __import__ hook with the normal one. from __interplevel__ import __import__ Modified: pypy/trunk/src/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/std/objspace.py Thu Jul 15 12:41:35 2004 @@ -157,7 +157,6 @@ global W_TupleObject, W_ListObject, W_DictObject, W_StringObject global W_TypeObject, W_SliceObject, W_LongObject, W_NoneObject global W_SeqIterObject - global W_FakeFile W_ObjectObject = objectobject.W_ObjectObject W_BoolObject = boolobject.W_BoolObject W_IntObject = intobject.W_IntObject @@ -194,14 +193,6 @@ w_type = self.gettypeobject(typedef) setattr(self, 'w_' + typedef.name, w_type) for_builtins[typedef.name] = w_type - - import fake - W_FakeFile = fake.fake_type(self, file) - - self.w_file = self.gettypeobject(W_FakeFile.typedef) - for_builtins['file'] = self.w_file - self.fake_type_cache[file] = W_FakeFile - # exceptions for_builtins.update(self.clone_exception_hierarchy()) From mwh at codespeak.net Fri Jul 16 15:38:24 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Jul 2004 15:38:24 +0200 (MEST) Subject: [pypy-svn] r5587 - in pypy/trunk/src/pypy: appspace objspace/std/test Message-ID: <20040716133824.5FDFF5A228@thoth.codespeak.net> Author: mwh Date: Fri Jul 16 15:38:23 2004 New Revision: 5587 Modified: pypy/trunk/src/pypy/appspace/_formatting.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: Make the tests in test_stringformat object space agnostic (so, the file should move...). Fix the broken tests running them under the trivial object space revealed (!!). Fix the formatting code to work with the unbroken tests. Modified: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_formatting.py Fri Jul 16 15:38:23 2004 @@ -145,11 +145,21 @@ self.prec = None return self.std_wp(r) +class HexFormatter(Formatter): + def format(self): + i = maybe_int(self.value) + r = hex(i) + if not self.flags.f_alt: + r = r[2:] + if self.char == 'X': + r = r.upper() + return self.std_wp(r) + format_registry = { 's':funcFormatter(str), 'r':funcFormatter(repr), - 'x':funcFormatter(maybe_int, hex), - 'X':funcFormatter(maybe_int, hex, lambda r:r.upper()), + 'x':HexFormatter, + 'X':HexFormatter, 'd':funcFormatter(maybe_int, str), 'f':floatFFormatter, 'g':funcFormatter(str), Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Fri Jul 16 15:38:23 2004 @@ -3,10 +3,6 @@ class TestStringObjectWithDict(testit.AppTestCase): - def setUp(self): - # force testing to use standard objspace - self.space = testit.objspace('std') - def test_format_item(self): d = {'i': 23} self.assertEquals('a23b', 'a%(i)sb' % d) @@ -36,10 +32,6 @@ class TestStringObject(testit.AppTestCase): - def setUp(self): - # force testing to use standard objspace - self.space = testit.objspace('std') - def test_format_item(self): self.assertEquals('a23b', 'a%sb' % 23) self.assertEquals('23b', '%sb' % 23) @@ -67,19 +59,15 @@ def test_format_float(self): self.assertEquals('23', '%d' % 23.456) - self.assertEquals('0x17', '%x' % 23.456) + self.assertEquals('17', '%x' % 23.456) self.assertEquals('23.456', '%s' % 23.456) - # accept either exact or filled-with-9's for %r - r = '%r' % 23.45 - if len(r)==5: - self.assertEquals('23.45', r) - else: - r9 = '23.44' + '9'*(len(r)-5) - self.assertEquals(r9, r) + # for 'r' use a float that has an exact decimal rep: + self.assertEquals('23.125', '%r' % 23.125) def test_format_int(self): self.assertEquals('23', '%d' % 23) - self.assertEquals('0x17', '%x' % 23) + self.assertEquals('17', '%x' % 23) + self.assertEquals('0x17', '%#x' % 23) self.assertEquals('23', '%s' % 23) self.assertEquals('23', '%r' % 23) @@ -102,9 +90,6 @@ self.assertRaises(ValueError, '%'.__mod__, ((23,),)) class TestWidthPrec(testit.AppTestCase): - def setUp(self): - self.space = testit.objspace() - def test_width(self): self.assertEquals("%3s" %'a', ' a') self.assertEquals("%-3s"%'a', 'a ') From mwh at codespeak.net Fri Jul 16 15:47:13 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 16 Jul 2004 15:47:13 +0200 (MEST) Subject: [pypy-svn] r5588 - in pypy/trunk/src/pypy: module objspace/std Message-ID: <20040716134713.BF7F75A228@thoth.codespeak.net> Author: mwh Date: Fri Jul 16 15:47:13 2004 New Revision: 5588 Added: pypy/trunk/src/pypy/objspace/std/basestringtype.py Modified: pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/objspace/std/fake.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/stringtype.py pypy/trunk/src/pypy/objspace/std/typetype.py Log: Say hi to basestring. Make str inherit from same. Tweaks to faking machinery so that unicode and str inherit from the *same* basestring... Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Fri Jul 16 15:47:13 2004 @@ -11,7 +11,6 @@ object = __interplevel__eval('space.w_object') # XXX these are faked: -basestring = __interplevel__eval('space.wrap(basestring)') unicode = __interplevel__eval('space.wrap(unicode)') file = __interplevel__eval('space.wrap(file)') open = file Added: pypy/trunk/src/pypy/objspace/std/basestringtype.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/basestringtype.py Fri Jul 16 15:47:13 2004 @@ -0,0 +1,7 @@ +from pypy.objspace.std.stdtypedef import * + + +# ____________________________________________________________ + +basestring_typedef = StdTypeDef("basestring", + ) Modified: pypy/trunk/src/pypy/objspace/std/fake.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/fake.py (original) +++ pypy/trunk/src/pypy/objspace/std/fake.py Fri Jul 16 15:47:13 2004 @@ -43,7 +43,11 @@ return w_obj.val kw['__new__'] = gateway.interp2app(fake__new__) if cpy_type.__base__ is not object: - base = space.wrap(cpy_type.__base__).instancetypedef + n = 'w_' + cpy_type.__base__.__name__ + if hasattr(space, n): + base = getattr(space, n).instancetypedef + else: + base = space.wrap(cpy_type.__base__).instancetypedef else: base = None class W_Fake(W_Object): Modified: pypy/trunk/src/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/std/objspace.py Fri Jul 16 15:47:13 2004 @@ -58,6 +58,7 @@ from pypy.objspace.std.tupletype import tuple_typedef from pypy.objspace.std.listtype import list_typedef from pypy.objspace.std.dicttype import dict_typedef + from pypy.objspace.std.basestringtype import basestring_typedef from pypy.objspace.std.stringtype import str_typedef from pypy.objspace.std.typetype import type_typedef from pypy.objspace.std.slicetype import slice_typedef Modified: pypy/trunk/src/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringtype.py Fri Jul 16 15:47:13 2004 @@ -1,4 +1,6 @@ from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.basestringtype import basestring_typedef + str_join = MultiMethod('join', 2) str_split = MultiMethod('split', 3, defaults=(None,-1)) @@ -51,7 +53,7 @@ # ____________________________________________________________ -str_typedef = StdTypeDef("str", +str_typedef = StdTypeDef("str", basestring_typedef, __new__ = newmethod(descr__new__), ) str_typedef.registermethods(globals()) Modified: pypy/trunk/src/pypy/objspace/std/typetype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/typetype.py (original) +++ pypy/trunk/src/pypy/objspace/std/typetype.py Fri Jul 16 15:47:13 2004 @@ -26,12 +26,22 @@ def descr__bases(space, w_type): return space.newtuple(w_type.bases_w) +def descr__base(space, w_type): + if w_type is space.w_object: + return space.w_None + b = w_type.instancetypedef.base + if b is not None: + return space.gettypeobject(b) + else: + return space.w_object + # ____________________________________________________________ type_typedef = StdTypeDef("type", __new__ = newmethod(descr__new__), __name__ = attrproperty('name'), __bases__ = GetSetProperty(descr__bases), + __base__ = GetSetProperty(descr__base), __mro__ = GetSetProperty(descr_get__mro__), __dict__ = default_dict_descr, ) From rocco at codespeak.net Fri Jul 16 21:35:12 2004 From: rocco at codespeak.net (rocco at codespeak.net) Date: Fri, 16 Jul 2004 21:35:12 +0200 (MEST) Subject: [pypy-svn] r5592 - in pypy/trunk/src/pypy: scripttest tool Message-ID: <20040716193512.8F3175A228@thoth.codespeak.net> Author: rocco Date: Fri Jul 16 21:35:12 2004 New Revision: 5592 Removed: pypy/trunk/src/pypy/scripttest/ pypy/trunk/src/pypy/tool/app_level_diff.py Log: Remove unsuccessful applevel testing script. This backs out the additions that were commited in rev 5369 Efforts to better abstract the integration with unitests were unsuccessful. Deletion removes "scripttest" directory disk clutter. Sorry for wasting your time. Deleted: /pypy/trunk/src/pypy/tool/app_level_diff.py ============================================================================== --- /pypy/trunk/src/pypy/tool/app_level_diff.py Fri Jul 16 21:35:12 2004 +++ (empty file) @@ -1,123 +0,0 @@ -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, '', w_bookendglobals) - w_scratchglobals = space.newdict([]) - runcode(space, source, filename, w_scratchglobals) - runcode(space, cleanupcode, '', 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 '##! ' lines, - where 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 '' From mwh at codespeak.net Wed Jul 21 12:52:13 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Jul 2004 12:52:13 +0200 (MEST) Subject: [pypy-svn] r5596 - pypy/trunk/src/pypy/appspace Message-ID: <20040721105213.70CCE5AD1A@thoth.codespeak.net> Author: mwh Date: Wed Jul 21 12:52:12 2004 New Revision: 5596 Modified: pypy/trunk/src/pypy/appspace/_formatting.py Log: Tweaks (paying a little attention to flags.f_sign). Armin is right: string formatting is horrendously slow. Not sure what to do about that... Modified: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_formatting.py Wed Jul 21 12:52:12 2004 @@ -131,20 +131,44 @@ raise TypeError, "an integer argument is required" return inter() +def maybe_float(value): + try: + floater = value.__float__ + except AttributeError: + raise TypeError, "float argument is required" + return floater() + class floatFFormatter(Formatter): def format(self): + v = maybe_float(self.value) if self.prec is None: self.prec = 6 - r = str(int(self.value)) + r = str(int(v)) # XXX this is a bit horrid if self.prec > 0: - frac_part = str(self.value%1)[1:2+self.prec] + frac_part = str(v%1)[1:2+self.prec] if len(frac_part) < self.prec + 1: frac_part += (1 + self.prec - len(frac_part)) * '0' r += frac_part + if v >= 0.0 and self.flags.f_sign: + r = '+' + r self.prec = None return self.std_wp(r) +class floatGFormatter(Formatter): + def format(self): + # this needs to be much, much more complicated :-( (perhaps + # should just punt to host Python -- which in turn punts to + # libc) + v = maybe_float(self.value) + if self.prec is None: + self.prec = 6 + r = str(v) + if v > 0 and self.flags.f_sign: + r = '+' + r + return self.std_wp(r) + + class HexFormatter(Formatter): def format(self): i = maybe_int(self.value) @@ -162,7 +186,7 @@ 'X':HexFormatter, 'd':funcFormatter(maybe_int, str), 'f':floatFFormatter, - 'g':funcFormatter(str), + 'g':floatGFormatter, } class FmtIter(object): From mwh at codespeak.net Wed Jul 21 13:05:36 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Jul 2004 13:05:36 +0200 (MEST) Subject: [pypy-svn] r5597 - pypy/trunk/src/pypy/module Message-ID: <20040721110536.D3A915AFC2@thoth.codespeak.net> Author: mwh Date: Wed Jul 21 13:05:36 2004 New Revision: 5597 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: make complex.__description somewhat less insane. add __radd__ (probably should add the other rop's too, but parrotbench doesn't seem to excercise them). Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Wed Jul 21 13:05:36 2004 @@ -610,8 +610,8 @@ Create a complex number from a real part and an optional imaginary part. This is equivalent to (real + imag*1j) where imag defaults to 0.""" - PREC_REPR = 0 # 17 - PREC_STR = 0 # 12 + PREC_REPR = 17 + PREC_STR = 12 def __init__(self, real=0.0, imag=None): if isinstance(real, str) and imag is not None: @@ -651,16 +651,10 @@ def __description(self, precision): - sign = '+' - if self.imag < 0.: - sign = '' if self.real != 0.: - format = "(%%%02dg%%s%%%02dgj)" % (precision, precision) - args = (self.real, sign, self.imag) + return "(%.*g%+.*gj)"%(precision, self.real, precision, self.imag) else: - format = "%%%02dgj" % precision - args = self.imag - return format % args + return "%.*gj"%(precision, self.imag) def __repr__(self): @@ -953,6 +947,9 @@ return self / other + def __radd__(self, other): + return self + other + # def __new__(self, ...): # pass From mwh at codespeak.net Wed Jul 21 13:06:41 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Jul 2004 13:06:41 +0200 (MEST) Subject: [pypy-svn] r5598 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040721110641.2E68E5AFC2@thoth.codespeak.net> Author: mwh Date: Wed Jul 21 13:06:40 2004 New Revision: 5598 Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py Log: reduce gratuitous use of string formatting (i realize the right fix is to make string formatting faster...) Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/dictobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/dictobject.py Wed Jul 21 13:06:40 2004 @@ -240,8 +240,8 @@ def app_str__Dict(d): items = [] for k, v in d.iteritems(): - items.append("%r: %r" % (k, v)) - return "{%s}" % ', '.join(items) + items.append(repr(k) + ": " + repr(v)) + return "{" + ', '.join(items) + "}" repr__Dict = str__Dict = gateway.app2interp(app_str__Dict) from pypy.objspace.std import dicttype From mwh at codespeak.net Wed Jul 21 13:07:57 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Jul 2004 13:07:57 +0200 (MEST) Subject: [pypy-svn] r5599 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040721110757.BBBD85AFC4@thoth.codespeak.net> Author: mwh Date: Wed Jul 21 13:07:57 2004 New Revision: 5599 Modified: pypy/trunk/src/pypy/objspace/std/inttype.py Log: fix for int("too big for an int") or int(too-big-for-an-int.0). not sure this is 100% correct. Modified: pypy/trunk/src/pypy/objspace/std/inttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/inttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/inttype.py Wed Jul 21 13:07:57 2004 @@ -33,9 +33,16 @@ except OverflowError, e: raise OperationError(space.w_OverflowError, space.wrap(str(e))) - w_obj = space.allocate_instance(W_IntObject, w_inttype) - w_obj.__init__(space, value) - return w_obj + if isinstance(value, long): + # XXX is this right?? + from pypy.objspace.std.longobject import W_LongObject + w_obj = space.allocate_instance(W_LongObject, space.w_long) + w_obj.__init__(space, value) + return w_obj + else: + w_obj = space.allocate_instance(W_IntObject, w_inttype) + w_obj.__init__(space, value) + return w_obj # ____________________________________________________________ From mwh at codespeak.net Wed Jul 21 13:10:03 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Jul 2004 13:10:03 +0200 (MEST) Subject: [pypy-svn] r5600 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040721111003.C787F5AFCD@thoth.codespeak.net> Author: mwh Date: Wed Jul 21 13:10:03 2004 New Revision: 5600 Modified: pypy/trunk/src/pypy/objspace/std/test/test_intobject.py Log: test int("something big") Modified: pypy/trunk/src/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_intobject.py Wed Jul 21 13:10:03 2004 @@ -297,6 +297,7 @@ def test_int_string(self): self.assertEquals(42, int("42")) + self.assertEquals(10000000000, int("10000000000")) def test_int_float(self): self.assertEquals(4, int(4.2)) From mwh at codespeak.net Wed Jul 21 13:11:07 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Jul 2004 13:11:07 +0200 (MEST) Subject: [pypy-svn] r5601 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040721111107.D46CA5B00E@thoth.codespeak.net> Author: mwh Date: Wed Jul 21 13:11:07 2004 New Revision: 5601 Modified: pypy/trunk/src/pypy/objspace/std/objspace.py Log: wrap complexs (review welcome!) Modified: pypy/trunk/src/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/std/objspace.py Wed Jul 21 13:11:07 2004 @@ -233,6 +233,12 @@ return W_ListObject(self, wrappeditems) if isinstance(x, long): return W_LongObject(self, x) + if isinstance(x, complex): + # XXX is this right? + c = self.getitem(self.w_builtins, self.wrap("complex")) + return self.call_function(c, + self.wrap(x.real), + self.wrap(x.imag)) if isinstance(x, BaseWrappable): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result From mwh at codespeak.net Wed Jul 21 13:11:33 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 21 Jul 2004 13:11:33 +0200 (MEST) Subject: [pypy-svn] r5602 - pypy/trunk/src/pypy Message-ID: <20040721111133.342C85B00E@thoth.codespeak.net> Author: mwh Date: Wed Jul 21 13:11:32 2004 New Revision: 5602 Modified: pypy/trunk/src/pypy/TODO Log: small updates Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Wed Jul 21 13:11:32 2004 @@ -9,14 +9,18 @@ things too. * cleanup the contents of the tool directory - + +* an oldie: move interpreter/unittest_w.py somewhere more appropriate + and give it a better name. + StdObjSpace =========== * find a way via hacking or elegance to run CPython's unit tests against the StdObjSpace. -* String formatting still needs work (field widths, precision, ...) +* String formatting still needs work. Mostly done, but surely missing + pieces around the edges & it's agonizingly slow. * Provide an importer that can import packages. (we have a limited __import__ builtin defined) <---- done now? From jacob at codespeak.net Wed Jul 21 18:02:19 2004 From: jacob at codespeak.net (jacob at codespeak.net) Date: Wed, 21 Jul 2004 18:02:19 +0200 (MEST) Subject: [pypy-svn] r5603 - pypy/trunk/doc/funding/negotiations Message-ID: <20040721160219.E0CAF5AD1A@thoth.codespeak.net> Author: jacob Date: Wed Jul 21 18:02:19 2004 New Revision: 5603 Added: pypy/trunk/doc/funding/negotiations/A3_draft_individuals.xls (contents, props changed) Log: New A3 draft Added: pypy/trunk/doc/funding/negotiations/A3_draft_individuals.xls ============================================================================== Binary file. No diff available. From jacob at codespeak.net Wed Jul 21 18:06:27 2004 From: jacob at codespeak.net (jacob at codespeak.net) Date: Wed, 21 Jul 2004 18:06:27 +0200 (MEST) Subject: [pypy-svn] r5604 - pypy/trunk/doc/funding/negotiations Message-ID: <20040721160627.D243A5AD1A@thoth.codespeak.net> Author: jacob Date: Wed Jul 21 18:06:27 2004 New Revision: 5604 Modified: pypy/trunk/doc/funding/negotiations/A3_draft_individuals.xls Log: Calculated average MM rate for DFKI Modified: pypy/trunk/doc/funding/negotiations/A3_draft_individuals.xls ============================================================================== Binary files. No diff available. From pedronis at codespeak.net Wed Jul 21 19:19:00 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 21 Jul 2004 19:19:00 +0200 (MEST) Subject: [pypy-svn] r5605 - pypy/trunk/doc/funding/negotiations Message-ID: <20040721171900.EE2135AD1A@thoth.codespeak.net> Author: pedronis Date: Wed Jul 21 19:18:49 2004 New Revision: 5605 Added: pypy/trunk/doc/funding/negotiations/part_b_2004_04_02.sxw - copied unchanged from r5604, pypy/trunk/doc/funding/makedoc/part_b_2004_04_02.sxw Log: copied last base OO doc here From benyoung at codespeak.net Thu Jul 22 14:25:31 2004 From: benyoung at codespeak.net (benyoung at codespeak.net) Date: Thu, 22 Jul 2004 14:25:31 +0200 (MEST) Subject: [pypy-svn] r5606 - in pypy/trunk/src/pypy: module objspace/std Message-ID: <20040722122531.ED57D5A19F@thoth.codespeak.net> Author: benyoung Date: Thu Jul 22 14:25:28 2004 New Revision: 5606 Modified: pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: Added some more of the the __r...__ functions to complex. Made the objectsapce return complex object rather than cpython wrap them. I think this is the correct behaviour. Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 22 14:25:28 2004 @@ -688,13 +688,17 @@ imag = self.imag + other.imag return complex(real, imag) + __radd__ == __add__ def __sub__(self, other): self, other = self.__coerce__(other) real = self.real - other.real imag = self.imag - other.imag return complex(real, imag) - + + def __rsub__(self, other): + self, other = self.__coerce__(other) + return other.__sub__(self) def __mul__(self, other): if other.__class__ != complex: @@ -704,6 +708,7 @@ imag = self.real*other.imag + self.imag*other.real return complex(real, imag) + __rmul__ == __mul__ def __div__(self, other): if other.__class__ != complex: @@ -738,6 +743,10 @@ return complex(real, imag) + def __rdiv__(self, other): + self, other = self.__coerce__(other) + return other.__div__(self) + def __floordiv__(self, other): return self / other @@ -947,9 +956,6 @@ return self / other - def __radd__(self, other): - return self + other - # def __new__(self, ...): # pass Modified: pypy/trunk/src/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/std/objspace.py Thu Jul 22 14:25:28 2004 @@ -243,6 +243,9 @@ w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result + if isinstance(x, complex): + w_complex = self.getitem(self.w_builtins, self.wrap('complex')) + return self.call_function(w_complex, self.newfloat(x.real), self.newfloat(x.imag)) # anything below this line is implicitly XXX'ed if isinstance(x, type(Exception)) and issubclass(x, Exception): if hasattr(self, 'w_' + x.__name__): From arigo at codespeak.net Thu Jul 22 16:44:45 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 22 Jul 2004 16:44:45 +0200 (MEST) Subject: [pypy-svn] r5607 - pypy/trunk/src/pypy/module Message-ID: <20040722144445.B55125A19F@thoth.codespeak.net> Author: arigo Date: Thu Jul 22 16:44:44 2004 New Revision: 5607 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: benyoung: please run the tests before checking in :-) Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 22 16:44:44 2004 @@ -688,7 +688,7 @@ imag = self.imag + other.imag return complex(real, imag) - __radd__ == __add__ + __radd__ = __add__ def __sub__(self, other): self, other = self.__coerce__(other) @@ -708,7 +708,7 @@ imag = self.real*other.imag + self.imag*other.real return complex(real, imag) - __rmul__ == __mul__ + __rmul__ = __mul__ def __div__(self, other): if other.__class__ != complex: From mwh at codespeak.net Thu Jul 22 17:03:49 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 17:03:49 +0200 (MEST) Subject: [pypy-svn] r5608 - pypy/trunk/src/pypy/appspace Message-ID: <20040722150349.9D2175A19F@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 17:03:48 2004 New Revision: 5608 Modified: pypy/trunk/src/pypy/appspace/_formatting.py Log: try a bit harder for %g formatting. anyone pointing out numerical naiveties in this code will be beaten with a stick; anyone *doing something* about said naiveties, on the other hand, will be very popular :-) Modified: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_formatting.py Thu Jul 22 17:03:48 2004 @@ -155,6 +155,8 @@ self.prec = None return self.std_wp(r) +import math + class floatGFormatter(Formatter): def format(self): # this needs to be much, much more complicated :-( (perhaps @@ -163,9 +165,39 @@ v = maybe_float(self.value) if self.prec is None: self.prec = 6 - r = str(v) - if v > 0 and self.flags.f_sign: - r = '+' + r + i = 0 + if v == 0.0: + if self.flags.f_sign: + return '+0' + else: + return '0' + elif v < 0.0: + sign = '-' + v = -v + else: + sign = '+' + p = math.floor(math.log(v, 10)) + if p < 0: + r = ['0', '.'] + ['0'] * (-int(p)) + r = [] + vv = v + tol = abs(v*10.0**-self.prec) + while 1: + d = long(vv/10.0**p) + vv -= d*10.0**p + r.append(str(d)) + if abs(vv) <= tol: + break + p -= 1 + if p == -1: + r.append('.') + while p > 0: + r.append('0') + p -= 1 + r = ''.join(r) + if sign == '-' or self.flags.f_sign: + r = sign + r + self.prec = None return self.std_wp(r) From arigo at codespeak.net Thu Jul 22 17:04:51 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 22 Jul 2004 17:04:51 +0200 (MEST) Subject: [pypy-svn] r5609 - pypy/trunk/src/pypy/module Message-ID: <20040722150451.354745B0F1@thoth.codespeak.net> Author: arigo Date: Thu Jul 22 17:04:50 2004 New Revision: 5609 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: Cleaned up class complex a bit. Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 22 17:04:50 2004 @@ -612,7 +612,9 @@ This is equivalent to (real + imag*1j) where imag defaults to 0.""" PREC_REPR = 17 PREC_STR = 12 - + + # XXX this class is not well tested + def __init__(self, real=0.0, imag=None): if isinstance(real, str) and imag is not None: msg = "complex() can't take second arg if first is a string" @@ -635,9 +637,9 @@ def __setattr__(self, name, value): if name in ('real', 'imag'): - raise TypeError, "readonly attribute" + raise AttributeError, "readonly attribute" else: - raise TypeError, "'complex' object has no attribute %s" % name + raise AttributeError, "'complex' object has no attribute %s" % name def _makeComplexFromString(self, string): import re @@ -675,11 +677,7 @@ # compare equal must have the same hash value, so that # hash(x + 0*j) must equal hash(x). - combined = hashreal + 1000003 * hashimag - if combined == -1: - combined = -2 - - return combined + return hashreal + 1000003 * hashimag def __add__(self, other): @@ -701,9 +699,7 @@ return other.__sub__(self) def __mul__(self, other): - if other.__class__ != complex: - return complex(other*self.real, other*self.imag) - + self, other = self.__coerce__(other) real = self.real*other.real - self.imag*other.imag imag = self.real*other.imag + self.imag*other.real return complex(real, imag) @@ -711,33 +707,21 @@ __rmul__ = __mul__ def __div__(self, other): - if other.__class__ != complex: - return complex(self.real/other, self.imag/other) - - if other.real < 0: - abs_breal = -other.real - else: - abs_breal = other.real - - if other.imag < 0: - abs_bimag = -other.imag - else: - abs_bimag = other.imag - - if abs_breal >= abs_bimag: + self, other = self.__coerce__(other) + if abs(other.real) >= abs(other.imag): # divide tops and bottom by other.real - if abs_breal == 0.0: - real = imag = 0.0 - else: + try: ratio = other.imag / other.real - denom = other.real + other.imag * ratio - real = (self.real + self.imag * ratio) / denom - imag = (self.imag - self.real * ratio) / denom + except ZeroDivisionError: + raise ZeroDivisionError, "complex division" + denom = other.real + other.imag * ratio + real = (self.real + self.imag * ratio) / denom + imag = (self.imag - self.real * ratio) / denom else: # divide tops and bottom by other.imag + assert other.imag != 0.0 ratio = other.real / other.imag denom = other.real * ratio + other.imag - assert other.imag != 0.0 real = (self.real * ratio + self.imag) / denom imag = (self.imag * ratio - self.real) / denom @@ -747,51 +731,43 @@ self, other = self.__coerce__(other) return other.__div__(self) - def __floordiv__(self, other): - return self / other - - - def __truediv__(self, other): - return self / other - + div, mod = self.__divmod__(other) + return div - def __mod__(self, other): - import warnings, math - warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning) - - if other.real == 0. and other.imag == 0.: - raise ZeroDivisionError, "complex remainder" + def __rfloordiv__(self, other): + self, other = self.__coerce__(other) + return other.__floordiv__(self) - div = self/other # The raw divisor value. - div = complex(math.floor(div.real), 0.0) - mod = self - div*other + __truediv__ = __div__ + __rtruediv__ = __rdiv__ - if mod.__class__ == complex: - return mod - else: - return complex(mod) + def __mod__(self, other): + div, mod = self.__divmod__(other) + return mod + def __rmod__(self, other): + self, other = self.__coerce__(other) + return other.__mod__(self) def __divmod__(self, other): + self, other = self.__coerce__(other) + import warnings, math warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning) - if other.real == 0. and other.imag == 0.: + try: + div = self/other # The raw divisor value. + except ZeroDivisionError: raise ZeroDivisionError, "complex remainder" - - div = self/other # The raw divisor value. div = complex(math.floor(div.real), 0.0) mod = self - div*other return div, mod - def __pow__(self, other): + def __pow__(self, other, mod=None): + a, b = self.__coerce__(other) import math - if other.__class__ != complex: - other = complex(other, 0) - - a, b = self, other if b.real == 0. and b.imag == 0.: real = 1. @@ -810,8 +786,14 @@ real = len*math.cos(phase) imag = len*math.sin(phase) - return complex(real, imag) + result = complex(real, imag) + if mod is not None: + result %= mod + return result + def __rpow__(self, other, mod=None): + self, other = self.__coerce__(other) + return other.__pow__(self, mod) def __neg__(self): return complex(-self.real, -self.imag) @@ -832,20 +814,11 @@ def __coerce__(self, other): - typ = type(other) - - if typ is int: - return self, complex(float(other)) - elif typ is long: - return self, complex(float(other)) - elif typ is float: - return self, complex(other) - elif other.__class__ == complex: + if isinstance(other, complex): return self, other - elif typ is complex: - return self, complex(other.real, other.imag) - - raise TypeError, "number %r coercion failed" % typ + if isinstance(other, (int, long, float)): + return self, complex(other) + raise TypeError, "number %r coercion failed" % (type(other),) def conjugate(self): @@ -890,81 +863,6 @@ raise TypeError, "can't convert complex to float; use e.g. float(abs(z))" - def _unsupportedOp(self, other, op): - selfTypeName = type(self).__name__ - otherTypeName = type(other).__name__ - args = (op, selfTypeName, otherTypeName) - msg = "unsupported operand type(s) for %s: '%s' and '%s'" % args - raise TypeError, msg - - - def __and__(self, other): - self._unsupportedOp(self, other, "&") - - - def __or__(self, other): - self._unsupportedOp(self, other, "|") - - - def __xor__(self, other): - self._unsupportedOp(self, other, "^") - - - def __rshift__(self, other): - self._unsupportedOp(self, other, ">>") - - - def __lshift__(self, other): - self._unsupportedOp(self, other, "<<") - - - def __iand__(self, other): - self._unsupportedOp(self, other, "&=") - - - def __ior__(self, other): - self._unsupportedOp(self, other, "|=") - - - def __ixor__(self, other): - self._unsupportedOp(self, other, "^=") - - - def __irshift__(self, other): - self._unsupportedOp(self, other, ">>=") - - - def __ilshift__(self, other): - self._unsupportedOp(self, other, "<<=") - - - # augmented assignment operations - - def __iadd__(self, other): - return self + other - - - def __isub__(self, other): - return self - other - - - def __imul__(self, other): - return self * other - - - def __idiv__(self, other): - return self / other - - -# def __new__(self, ...): -# pass - - -# test mod, divmod - -# add radd, rsub, rmul, rdiv... - - # ________________________________________________________________________ class buffer: From arigo at codespeak.net Thu Jul 22 17:31:41 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 22 Jul 2004 17:31:41 +0200 (MEST) Subject: [pypy-svn] r5610 - in pypy/trunk/src/pypy/module: . test Message-ID: <20040722153141.54E345A19F@thoth.codespeak.net> Author: arigo Date: Thu Jul 22 17:31:40 2004 New Revision: 5610 Modified: pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/module/test/test_builtin.py Log: isinstance() and issubclass() behave better. Tests added. isinstance() now checks with type() first, and with .__class__ next. Modified: pypy/trunk/src/pypy/module/__builtin__interp.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__interp.py (original) +++ pypy/trunk/src/pypy/module/__builtin__interp.py Thu Jul 22 17:31:40 2004 @@ -280,7 +280,7 @@ #XXX works only for new-style classes. #So we have to fix it, when we add support for old-style classes -def issubclass(w_cls1, w_cls2): +def _issubtype(w_cls1, w_cls2): return space.issubtype(w_cls1, w_cls2) def iter(w_collection_or_callable, w_sentinel = _noarg): Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 22 17:31:40 2004 @@ -182,21 +182,26 @@ break return initial +def issubclass(cls, klass_or_tuple): + if _issubtype(type(klass_or_tuple), tuple): + for klass in klass_or_tuple: + if issubclass(cls, klass): + return True + return False + try: + return _issubtype(cls, klass_or_tuple) + except TypeError: + raise TypeError, "arg 2 must be a class or type or a tuple thereof" + def isinstance(obj, klass_or_tuple): + if issubclass(type(obj), klass_or_tuple): + return True try: objcls = obj.__class__ except AttributeError: - objcls = type(obj) - if issubclass(klass_or_tuple.__class__, tuple): - for klass in klass_or_tuple: - if issubclass(objcls, klass): - return 1 - return 0 + return False else: - try: - return issubclass(objcls, klass_or_tuple) - except TypeError: - raise TypeError, "isinstance() arg 2 must be a class or type" + return objcls is not type(obj) and issubclass(objcls, klass_or_tuple) def range(x, y=None, step=1): """ returns a list of integers in arithmetic position from start (defaults @@ -443,7 +448,7 @@ from __interplevel__ import abs, chr, len, ord, pow, repr from __interplevel__ import hash, oct, hex, round from __interplevel__ import getattr, setattr, delattr, iter, hash, id -from __interplevel__ import issubclass +from __interplevel__ import _issubtype from __interplevel__ import compile, eval from __interplevel__ import globals, locals, _caller_globals, _caller_locals Modified: pypy/trunk/src/pypy/module/test/test_builtin.py ============================================================================== --- pypy/trunk/src/pypy/module/test/test_builtin.py (original) +++ pypy/trunk/src/pypy/module/test/test_builtin.py Thu Jul 22 17:31:40 2004 @@ -238,6 +238,27 @@ self.assertRaises(ValueError, compile, '1+2', '?', 'maybenot') self.assertRaises(TypeError, compile, '1+2', 12, 34) + def test_isinstance(self): + self.assert_(isinstance(5, int)) + self.assert_(isinstance(5, object)) + self.assert_(not isinstance(5, float)) + self.assert_(isinstance(True, (int, float))) + self.assert_(not isinstance(True, (type, float))) + self.assert_(isinstance(True, ((type, float), bool))) + self.assertRaises(TypeError, isinstance, 5, 6) + self.assertRaises(TypeError, isinstance, 5, (float, 6)) + + def test_issubclass(self): + self.assert_(issubclass(int, int)) + self.assert_(issubclass(int, object)) + self.assert_(not issubclass(int, float)) + self.assert_(issubclass(bool, (int, float))) + self.assert_(not issubclass(bool, (type, float))) + self.assert_(issubclass(bool, ((type, float), bool))) + self.assertRaises(TypeError, issubclass, 5, int) + self.assertRaises(TypeError, issubclass, int, 6) + self.assertRaises(TypeError, issubclass, int, (float, 6)) + class TestInternal(testit.IntTestCase): From mwh at codespeak.net Thu Jul 22 17:39:52 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 17:39:52 +0200 (MEST) Subject: [pypy-svn] r5611 - in pypy/trunk/src/pypy: interpreter/test module Message-ID: <20040722153952.C0C205A19F@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 17:39:52 2004 New Revision: 5611 Modified: pypy/trunk/src/pypy/interpreter/test/test_class.py pypy/trunk/src/pypy/module/__builtin__module.py Log: harden super against instances that define __getattribute__ (this is actually quite likely, it's good practice for classes that do this to use super() in their implementations...). test for same. Modified: pypy/trunk/src/pypy/interpreter/test/test_class.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_class.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_class.py Thu Jul 22 17:39:52 2004 @@ -126,5 +126,15 @@ self.assertEquals(C.meth_doc.__doc__, """this is a docstring""") self.assertEquals(c.meth_doc.__doc__, """this is a docstring""") + def test_getattribute(self): + class C: + def __getattribute__(self, attr): + if attr == 'one': + return 'two' + return super(C, self).__getattribute__(attr) + c = C() + self.assertEquals(c.one, "two") + self.assertRaises(AttributeError, getattr, c, "two") + if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 22 17:39:52 2004 @@ -581,7 +581,7 @@ self.__thisclass__ = type self.__self__ = obj if obj is not None and isinstance(obj, type): - self.__self_class__ = obj.__class__ + self.__self_class__ = object.__getattribute__(obj, "__class__") else: self.__self_class__ = obj def __get__(self, obj, type=None): From mwh at codespeak.net Thu Jul 22 17:44:42 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 17:44:42 +0200 (MEST) Subject: [pypy-svn] r5612 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040722154442.8DEFA5B00E@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 17:44:42 2004 New Revision: 5612 Modified: pypy/trunk/src/pypy/objspace/std/longobject.py Log: add an assert. yes, it is possible to trip this assert: 10**-10 will do it. current workaround: don't do that :-) Modified: pypy/trunk/src/pypy/objspace/std/longobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/longobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/longobject.py Thu Jul 22 17:44:42 2004 @@ -14,6 +14,7 @@ def __init__(w_self, space, longval=0L): W_Object.__init__(w_self, space) + assert isinstance(longval, long) w_self.longval = longval From mwh at codespeak.net Thu Jul 22 17:51:59 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 17:51:59 +0200 (MEST) Subject: [pypy-svn] r5613 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040722155159.9FBA45B00E@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 17:51:59 2004 New Revision: 5613 Modified: pypy/trunk/src/pypy/objspace/std/longtype.py Log: # XXX implement long("str", base) ok. steals implementation from CPython; in fact this is all copy-paste-changed from stringtype.py... Modified: pypy/trunk/src/pypy/objspace/std/longtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/longtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/longtype.py Thu Jul 22 17:51:59 2004 @@ -1,18 +1,14 @@ from pypy.objspace.std.stdtypedef import * +from pypy.interpreter.error import OperationError from pypy.objspace.std.inttype import int_typedef -def descr__new__(space, w_longtype, w_value=None): +def descr__new__(space, w_longtype, w_value=None, w_base=None): from pypy.objspace.std.longobject import W_LongObject + if w_base is None: + w_base = space.w_None if w_value is None: value = 0L - elif space.is_true(space.isinstance(w_value, space.w_str)): - # XXX implement long("str", base) - try: - value = long(space.unwrap(w_value)) - except ValueError, e: - raise OperationError(space.w_ValueError, - space.wrap(str(e))) - else: + elif w_base == space.w_None and not space.is_true(space.isinstance(w_value, space.w_str)): w_obj = space.long(w_value) if space.is_true(space.is_(w_longtype, space.w_long)): return w_obj # 'long(x)' should return @@ -23,6 +19,24 @@ if not isinstance(value, long): # XXX typechecking in unwrap! raise OperationError(space.w_ValueError, space.wrap("value can't be converted to long")) + + else: + if w_base == space.w_None: + base = -909 # don't blame us!! + else: + base = space.unwrap(w_base) + s = space.unwrap(w_value) + try: + value = long(s, base) + except TypeError, e: + raise OperationError(space.w_TypeError, + space.wrap(str(e))) + except ValueError, e: + raise OperationError(space.w_ValueError, + space.wrap(str(e))) + except OverflowError, e: + raise OperationError(space.w_OverflowError, + space.wrap(str(e))) w_obj = space.allocate_instance(W_LongObject, w_longtype) w_obj.__init__(space, value) return w_obj From mwh at codespeak.net Thu Jul 22 17:57:16 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 17:57:16 +0200 (MEST) Subject: [pypy-svn] r5614 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040722155716.24A605B00E@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 17:57:15 2004 New Revision: 5614 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/stringtype.py Log: str.decode() methods that take optional args but don't take None's as indication of an absent argument are evil, btw Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Thu Jul 22 17:57:15 2004 @@ -984,6 +984,18 @@ mod__String_ANY = gateway.app2interp(app_mod__String_ANY) + +def app_str_decode__String_ANY_ANY(str, encoding=None, errors=None): + if encoding is None and errors is None: + return unicode(str) + elif errors is None: + return unicode(str, encoding) + else: + return unicode(str, encoding, errors) + + +str_decode__String_ANY_ANY = gateway.app2interp(app_str_decode__String_ANY_ANY) + # register all methods from pypy.objspace.std import stringtype register_all(vars(), stringtype) Modified: pypy/trunk/src/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringtype.py Thu Jul 22 17:57:15 2004 @@ -34,6 +34,7 @@ str_splitlines = MultiMethod('splitlines', 2, defaults=(0,)) str_startswith = MultiMethod('startswith', 2) #[optional arguments not supported now] str_translate = MultiMethod('translate', 3, defaults=('',)) #unicode mimic not supported now +str_decode = MultiMethod('decode', 3, defaults=(None, None)) # ____________________________________________________________ From mwh at codespeak.net Thu Jul 22 17:57:41 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 17:57:41 +0200 (MEST) Subject: [pypy-svn] r5615 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040722155741.3D5F05B104@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 17:57:40 2004 New Revision: 5615 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py Log: error checking in ord() Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Thu Jul 22 17:57:40 2004 @@ -969,6 +969,11 @@ def ord__String(space, w_str): + if len(w_str._value) != 1: + raise OperationError( + space.w_TypeError, + space.wrap("ord() expected a character, but string " + "of length %d found"%(len(w_str._value),))) return space.wrap(ord(space.unwrap(w_str))) def app_mod__String_ANY(format, values): From mwh at codespeak.net Thu Jul 22 17:59:33 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 17:59:33 +0200 (MEST) Subject: [pypy-svn] r5616 - pypy/trunk/src/pypy/interpreter Message-ID: <20040722155933.3C1405B00E@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 17:59:32 2004 New Revision: 5616 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py Log: uncomment some necessary softspace code (why was it commented out? from before we had isinstance working??) Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Thu Jul 22 17:59:32 2004 @@ -823,8 +823,8 @@ stream.write(str(x)) # add a softspace unless we just printed a string which ends in a '\t' # or '\n' -- or more generally any whitespace character but ' ' - # if isinstance(x, str) and len(x) and x[-1].isspace() and x[-1]!=' ': - # return + if isinstance(x, str) and len(x) and x[-1].isspace() and x[-1]!=' ': + return # XXX add unicode handling file_softspace(stream, True) From mwh at codespeak.net Thu Jul 22 18:00:40 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 18:00:40 +0200 (MEST) Subject: [pypy-svn] r5617 - pypy/trunk/src/pypy/objspace Message-ID: <20040722160040.365CF5B00E@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 18:00:39 2004 New Revision: 5617 Modified: pypy/trunk/src/pypy/objspace/descroperation.py Log: just putting some spaces in so i can read this function (could happen quite a lot in this file, btw) Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Thu Jul 22 18:00:39 2004 @@ -332,24 +332,24 @@ # regular methods def helpers -def _make_binop_impl(symbol,specialnames): +def _make_binop_impl(symbol, specialnames): left, right = specialnames - def binop_impl(space,w_obj1,w_obj2): + def binop_impl(space, w_obj1, w_obj2): w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) - w_left_impl = space.lookup(w_obj1,left) - if space.is_true(space.is_(w_typ1,w_typ2)): + w_left_impl = space.lookup(w_obj1, left) + if space.is_true(space.is_(w_typ1, w_typ2)): w_right_impl = None else: - w_right_impl = space.lookup(w_obj2,right) - if space.is_true(space.issubtype(w_typ1,w_typ2)): - w_obj1,w_obj2 = w_obj2,w_obj1 - w_left_impl,w_right_impl = w_right_impl,w_left_impl + w_right_impl = space.lookup(w_obj2, right) + if space.is_true(space.issubtype(w_typ1, w_typ2)): + w_obj1, w_obj2 = w_obj2, w_obj1 + w_left_impl, w_right_impl = w_right_impl, w_left_impl - w_res = _invoke_binop(space,w_left_impl,w_obj1,w_obj2) + w_res = _invoke_binop(space, w_left_impl, w_obj1, w_obj2) if w_res is not None: return w_res - w_res = _invoke_binop(space,w_right_impl,w_obj2,w_obj1) + w_res = _invoke_binop(space, w_right_impl, w_obj2, w_obj1) if w_res is not None: return w_res raise OperationError(space.w_TypeError, From arigo at codespeak.net Thu Jul 22 18:14:38 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 22 Jul 2004 18:14:38 +0200 (MEST) Subject: [pypy-svn] r5618 - pypy/trunk/src/pypy/module Message-ID: <20040722161438.3B61D5A19F@thoth.codespeak.net> Author: arigo Date: Thu Jul 22 18:14:37 2004 New Revision: 5618 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: "Clean down" class super to make it behave more precisely like CPython's. Modified: pypy/trunk/src/pypy/module/__builtin__module.py ============================================================================== --- pypy/trunk/src/pypy/module/__builtin__module.py (original) +++ pypy/trunk/src/pypy/module/__builtin__module.py Thu Jul 22 18:14:37 2004 @@ -576,14 +576,21 @@ # http://www.python.org/2.2.3/descrintro.html # it exposes the same special attributes as CPython's. class super(object): - def __init__(self, type, obj=None): - # XXX check the arguments - self.__thisclass__ = type - self.__self__ = obj - if obj is not None and isinstance(obj, type): - self.__self_class__ = object.__getattribute__(obj, "__class__") + def __init__(self, typ, obj=None): + if obj is None: + objcls = None # unbound super object + elif _issubtype(type(obj), type) and _issubtype(obj, type): + objcls = obj # special case for class methods + elif _issubtype(type(obj), typ): + objcls = type(obj) # normal case else: - self.__self_class__ = obj + objcls = getattr(obj, '__class__', type(obj)) + if not _issubtype(objcls, typ): + raise TypeError, ("super(type, obj): " + "obj must be an instance or subtype of type") + self.__thisclass__ = typ + self.__self__ = obj + self.__self_class__ = objcls def __get__(self, obj, type=None): ga = object.__getattribute__ if ga(self, '__self__') is None and obj is not None: @@ -592,23 +599,24 @@ return self def __getattribute__(self, attr): d = object.__getattribute__(self, '__dict__') - if attr in d: - return d[attr] # for __self__, __thisclass__, __self_class__ - mro = iter(d['__self_class__'].__mro__) - for cls in mro: - if cls is d['__thisclass__']: - break - # Note: mro is an iterator, so the second loop - # picks up where the first one left off! - for cls in mro: - try: - x = cls.__dict__[attr] - except KeyError: - continue - if hasattr(x, '__get__'): - x = x.__get__(d['__self__'], type(d['__self__'])) - return x - raise AttributeError, attr + if attr != '__class__' and d['__self_class__'] is not None: + # we want super().__class__ to be the real class + # and we don't do anything for unbound type objects + mro = iter(d['__self_class__'].__mro__) + for cls in mro: + if cls is d['__thisclass__']: + break + # Note: mro is an iterator, so the second loop + # picks up where the first one left off! + for cls in mro: + try: + x = cls.__dict__[attr] + except KeyError: + continue + if hasattr(x, '__get__'): + x = x.__get__(d['__self__'], type(d['__self__'])) + return x + return object.__getattribute__(self, attr) # fall-back class complex(object): """complex(real[, imag]) -> complex number From mwh at codespeak.net Thu Jul 22 18:22:46 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 18:22:46 +0200 (MEST) Subject: [pypy-svn] r5619 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040722162246.6E63E5A19F@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 18:22:45 2004 New Revision: 5619 Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py Log: make dict(aDict) work (yes, that really is how CPython detects a mapping) enable the tests of dict.__new__, adding one for above delete some very dead, long since commented out, tests Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/dictobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/dictobject.py Thu Jul 22 18:22:45 2004 @@ -111,14 +111,20 @@ pass elif len(args) == 1: # XXX do dict({...}) with dict_update__Dict_Dict() - list_of_w_pairs = space.unpackiterable(args[0]) - for w_pair in list_of_w_pairs: - pair = space.unpackiterable(w_pair) - if len(pair)!=2: - raise OperationError(space.w_ValueError, - space.wrap("dict() takes a sequence of pairs")) - w_k, w_v = pair - setitem__Dict_ANY_ANY(space, w_dict, w_k, w_v) + try: + space.getattr(args[0], space.wrap("keys")) + except OperationError: + list_of_w_pairs = space.unpackiterable(args[0]) + for w_pair in list_of_w_pairs: + pair = space.unpackiterable(w_pair) + if len(pair)!=2: + raise OperationError(space.w_ValueError, + space.wrap("dict() takes a sequence of pairs")) + w_k, w_v = pair + setitem__Dict_ANY_ANY(space, w_dict, w_k, w_v) + else: + from pypy.objspace.std.dicttype import dict_update__ANY_ANY + dict_update__ANY_ANY(space, w_dict, args[0]) else: raise OperationError(space.w_TypeError, space.wrap("dict() takes at most 1 argument")) Modified: pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py Thu Jul 22 18:22:45 2004 @@ -47,50 +47,6 @@ self.assertRaises_w(self.space.w_KeyError, space.getitem,d,space.wrap('one')) -## def test_cell(self): -## space = self.space -## wk1 = space.wrap('key') -## d = W_DictObject(space, []) -## w_cell = d.cell(space,wk1) -## cell = space.unwrap(w_cell) -## self.failUnless(cell.is_empty()) -## cell.set(space.wrap(1)) -## self.assertEqual_w(space.getitem(d,wk1),space.wrap(1)) -## wk2 = space.wrap('key2') -## space.setitem(d,wk2,space.wrap(2)) -## cell = space.unwrap(d.cell(space,wk2)) -## self.assertEqual_w(cell.get(),space.wrap(2)) - -## def test_empty_cell(self): -## space = self.space -## d = W_DictObject(space, -## [(space.wrap('colour'), space.wrap(0)), -## (space.wrap('of'), space.wrap(2)), -## (space.wrap('magic'), space.wrap(1))]) -## w_cell = d.cell(space, space.wrap('of')) -## d2 = W_DictObject(space, -## [(space.wrap('colour'), space.wrap(0)), -## (space.wrap('magic'), space.wrap(1))]) -## self.assertNotEqual_w(d, d2) -## space.delitem(d, space.wrap('of')) -## self.assertEqual_w(d, d2) - -## def test_empty_cell2(self): -## space = self.space -## d = W_DictObject(space, -## [(space.wrap('colour'), space.wrap(0)), -## (space.wrap('of'), space.wrap(2)), -## (space.wrap('magic'), space.wrap(1))]) -## w_cell = d.cell(space, space.wrap('of')) -## d2 = W_DictObject(space, -## [(space.wrap('colour'), space.wrap(0)), -## (space.wrap('magic'), space.wrap(1))]) -## self.assertNotEqual_w(d, d2) -## cell = space.unwrap(w_cell) -## cell.make_empty() -## self.assertEqual_w(d, d2) - - def test_wrap_dict(self): self.assert_(isinstance(self.space.wrap({}), W_DictObject)) @@ -320,7 +276,7 @@ self.assertEqual("{'ba': 'bo'}", repr({'ba': 'bo'})) self.assert_(str({1: 2, 'ba': 'bo'}) in ok_reprs) - def tooslow_test_new(self): + def test_new(self): d = dict() self.assertEqual(d, {}) args = [['a',2], [23,45]] @@ -330,6 +286,8 @@ self.assertEqual(d, {'a':33, 'b':44, 23:45}) d = dict(a=33, b=44) self.assertEqual(d, {'a':33, 'b':44}) + d = dict({'a':33, 'b':44}) + self.assertEqual(d, {'a':33, 'b':44}) try: d = dict(23) except (TypeError, ValueError): pass else: self.fail("dict(23) should raise!") From mwh at codespeak.net Thu Jul 22 18:23:58 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 18:23:58 +0200 (MEST) Subject: [pypy-svn] r5620 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040722162358.AD3DC5A19F@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 18:23:58 2004 New Revision: 5620 Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py Log: delattr for types (and if the space.set return value is good for anything, well, it shouldn't be :-) Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/typeobject.py Thu Jul 22 18:23:58 2004 @@ -131,8 +131,16 @@ w_descr = space.lookup(w_type, name) if w_descr is not None: if space.is_data_descr(w_descr): - return space.set(w_descr,w_type,space.type(w_type)) + space.set(w_descr,w_type,space.type(w_type)) w_type.dict_w[name] = w_value + +def delattr__Type_ANY(space, w_type, w_name): + name = space.unwrap(w_name) + w_descr = space.lookup(w_type, name) + if w_descr is not None: + if space.is_data_descr(w_descr): + space.delete(w_descr, space.type(w_type)) + del w_type.dict_w[name] # XXX __delattr__ # XXX __hash__ ?? From mwh at codespeak.net Thu Jul 22 18:31:29 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 22 Jul 2004 18:31:29 +0200 (MEST) Subject: [pypy-svn] r5621 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040722163129.870F85A19F@thoth.codespeak.net> Author: mwh Date: Thu Jul 22 18:31:29 2004 New Revision: 5621 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: use floats with exact decimal expansions in the tests. i'll get to 1ulp stuff eventually, just not yet (in fact, the tests still fail... hopefully i'll get to that sooner :-) Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Thu Jul 22 18:31:29 2004 @@ -108,10 +108,10 @@ self.assertEquals("%02d"%1, "01") self.assertEquals("%05d"%1, "00001") self.assertEquals("%-05d"%1, "1 ") - self.assertEquals("%04f"%2.3, "2.300000") - self.assertEquals("%04g"%2.3, "02.3") - self.assertEquals("%-04g"%2.3,"2.3 ") - self.assertEquals("%04s"%2.3, " 2.3") + self.assertEquals("%04f"%2.25, "2.250000") + self.assertEquals("%05g"%2.25, "02.25") + self.assertEquals("%-05g"%2.25,"2.25 ") + self.assertEquals("%05s"%2.25, " 2.25") def test_star_width(self): From jacob at codespeak.net Thu Jul 22 22:33:31 2004 From: jacob at codespeak.net (jacob at codespeak.net) Date: Thu, 22 Jul 2004 22:33:31 +0200 (MEST) Subject: [pypy-svn] r5624 - pypy/trunk/doc/funding/negotiations Message-ID: <20040722203331.BCA9E5A19F@thoth.codespeak.net> Author: jacob Date: Thu Jul 22 22:33:30 2004 New Revision: 5624 Added: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22.sxw (contents, props changed) pypy/trunk/doc/funding/negotiations/part_b_2004_07_22_individual.sxw (contents, props changed) Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_04_02.sxw Log: Added modified DoW. The one with _individual on the end has DFKI slit up for future use. Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_04_02.sxw ============================================================================== Binary files. No diff available. Added: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22.sxw ============================================================================== Binary file. No diff available. Added: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22_individual.sxw ============================================================================== Binary file. No diff available. From benyoung at codespeak.net Fri Jul 23 12:01:12 2004 From: benyoung at codespeak.net (benyoung at codespeak.net) Date: Fri, 23 Jul 2004 12:01:12 +0200 (MEST) Subject: [pypy-svn] r5625 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040723100112.114805A0F8@thoth.codespeak.net> Author: benyoung Date: Fri Jul 23 12:01:10 2004 New Revision: 5625 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: Small change to stringformat tests to make them the same as what cpython actually does. Has the benefit of making all tests pass for trivial space Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Fri Jul 23 12:01:10 2004 @@ -110,7 +110,7 @@ self.assertEquals("%-05d"%1, "1 ") self.assertEquals("%04f"%2.25, "2.250000") self.assertEquals("%05g"%2.25, "02.25") - self.assertEquals("%-05g"%2.25,"2.25 ") + self.assertEquals("%-05g"%2.25,"2.25 ") self.assertEquals("%05s"%2.25, " 2.25") From mwh at codespeak.net Fri Jul 23 12:02:49 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jul 2004 12:02:49 +0200 (MEST) Subject: [pypy-svn] r5626 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040723100249.E5EA25A0F8@thoth.codespeak.net> Author: mwh Date: Fri Jul 23 12:02:49 2004 New Revision: 5626 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: add an admittedly rather whingy comment about the difference between CPython's documentation and implementation. Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Fri Jul 23 12:02:49 2004 @@ -80,6 +80,18 @@ self.assertEquals('<(1, 2)-(3, 4)>', '<%s-%s>' % ((1,2), (3,4))) def test_format_dict(self): + + # I'll just note that the first of these two completely + # contradicts what CPython's documentation says: + + # When the right argument is a dictionary (or other + # mapping type), then the formats in the string + # \emph{must} include a parenthesised mapping key into + # that dictionary inserted immediately after the + # \character{\%} character. + + # It is what CPython *does*, however. All software sucks. + self.assertEquals('<{1: 2}>', '<%s>' % {1:2}) self.assertEquals('<{1: 2}-{3: 4}>', '<%s-%s>' % ({1:2}, {3:4})) From mwh at codespeak.net Fri Jul 23 12:29:14 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jul 2004 12:29:14 +0200 (MEST) Subject: [pypy-svn] r5627 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040723102914.6BF3C5A0F8@thoth.codespeak.net> Author: mwh Date: Fri Jul 23 12:29:13 2004 New Revision: 5627 Modified: pypy/trunk/src/pypy/objspace/std/fake.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: faked types shouldn't be specific to an instance Modified: pypy/trunk/src/pypy/objspace/std/fake.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/fake.py (original) +++ pypy/trunk/src/pypy/objspace/std/fake.py Fri Jul 23 12:29:13 2004 @@ -1,6 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objspace import W_Object +from pypy.objspace.std.objspace import W_Object, StdObjSpace from pypy.objspace.std.default import UnwrapError # this file automatically generates non-reimplementations of CPython @@ -9,6 +9,8 @@ import sys +_fake_type_cache = {} + # real-to-wrapped exceptions def wrap_exception(space): exc, value, tb = sys.exc_info() @@ -27,8 +29,11 @@ w_value = space.wrap(value) raise OperationError, OperationError(w_exc, w_value), tb -def fake_type(space, cpy_type): +def fake_type(cpy_type): assert type(cpy_type) is type + if cpy_type in _fake_type_cache: + return _fake_type_cache[cpy_type] + print 'faking %r'%(cpy_type,) kw = {} for s, v in cpy_type.__dict__.items(): kw[s] = v @@ -39,24 +44,40 @@ except: wrap_exception(space) return W_Fake(space, r) - def fake_unwrap(space, w_obj): - return w_obj.val kw['__new__'] = gateway.interp2app(fake__new__) if cpy_type.__base__ is not object: - n = 'w_' + cpy_type.__base__.__name__ - if hasattr(space, n): - base = getattr(space, n).instancetypedef - else: - base = space.wrap(cpy_type.__base__).instancetypedef + assert cpy_type.__base__ is basestring + from pypy.objspace.std.basestringtype import basestring_typedef + base = basestring_typedef else: base = None + if cpy_type is unicode: + # XXX no hacks here, oh no, none at all. well maybe a + # XXX little one... + def uni_cmp(space, w_uni, w_other): + try: + return space.wrap(cmp(space.unwrap(w_uni), + space.unwrap(w_other))) + except: + wrap_exception(space) + kw['__cmp__'] = gateway.interp2app(uni_cmp) class W_Fake(W_Object): typedef = StdTypeDef( cpy_type.__name__, base, **kw) def __init__(w_self, space, val): W_Object.__init__(w_self, space) w_self.val = val - space.__class__.unwrap.register(fake_unwrap, W_Fake) + def fake_unwrap(space, w_obj): + return w_obj.val + StdObjSpace.unwrap.register(fake_unwrap, W_Fake) + if cpy_type is unicode: + # more unicode hacks! + def fake_ord(space, w_uni): + try: + return space.wrap(ord(w_uni.val)) + except: + wrap_exception(space) + StdObjSpace.MM.ord.register(fake_ord, W_Fake) W_Fake.__name__ = 'W_Fake(%s)'%(cpy_type.__name__) W_Fake.typedef.fakedcpytype = cpy_type # XXX obviously this entire file is something of a hack, but it @@ -64,8 +85,8 @@ if cpy_type is type(type(None).__repr__): def call_args(self, args): try: - unwrappedargs = [space.unwrap(w_arg) for w_arg in args.args_w] - unwrappedkwds = dict([(key, space.unwrap(w_value)) + unwrappedargs = [self.space.unwrap(w_arg) for w_arg in args.args_w] + unwrappedkwds = dict([(key, self.space.unwrap(w_value)) for key, w_value in args.kwds_w.items()]) except UnwrapError, e: raise UnwrapError('calling %s: %s' % (cpy_type, e)) @@ -73,9 +94,10 @@ assert callable(self.val), self.val result = apply(self.val, unwrappedargs, unwrappedkwds) except: - wrap_exception(space) - return space.wrap(result) + wrap_exception(self.space) + return self.space.wrap(result) setattr(W_Fake, "call_args", call_args) + _fake_type_cache[cpy_type] = W_Fake return W_Fake Modified: pypy/trunk/src/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/std/objspace.py Fri Jul 23 12:29:13 2004 @@ -135,8 +135,6 @@ return done def initialize(self): - self.fake_type_cache = {} - # The object implementations that we want to 'link' into PyPy must be # imported here. This registers them into the multimethod tables, # *before* the type objects are built from these multimethod tables. @@ -243,30 +241,14 @@ w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result - if isinstance(x, complex): - w_complex = self.getitem(self.w_builtins, self.wrap('complex')) - return self.call_function(w_complex, self.newfloat(x.real), self.newfloat(x.imag)) # anything below this line is implicitly XXX'ed if isinstance(x, type(Exception)) and issubclass(x, Exception): if hasattr(self, 'w_' + x.__name__): return getattr(self, 'w_' + x.__name__) + import fake if isinstance(x, type): - if x in self.fake_type_cache: - return self.gettypeobject(self.fake_type_cache[x].typedef) - print 'faking %r'%(x,) - import fake - ft = fake.fake_type(self, x) - self.fake_type_cache[x] = ft - return self.gettypeobject(self.fake_type_cache[x].typedef) - if type(x) in self.fake_type_cache: - ft = self.fake_type_cache[type(x)] - return ft(self, x) - else: - print 'faking %r'%(type(x),) - import fake - ft = fake.fake_type(self, type(x)) - self.fake_type_cache[type(x)] = ft - return ft(self, x) + return self.gettypeobject(fake.fake_type(x).typedef) + return fake.fake_type(type(x))(self, x) def newint(self, intval): return W_IntObject(self, intval) From mwh at codespeak.net Fri Jul 23 12:31:53 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jul 2004 12:31:53 +0200 (MEST) Subject: [pypy-svn] r5628 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040723103153.73C755A0F8@thoth.codespeak.net> Author: mwh Date: Fri Jul 23 12:31:52 2004 New Revision: 5628 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py Log: the reason faked types shouldn't be specific to an instance: turn on string to unicode delegation Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Fri Jul 23 12:31:52 2004 @@ -101,6 +101,16 @@ registerimplementation(W_StringObject) +# string-to-unicode delegation +import fake +def delegate__String(space, w_str): + return space.wrap(unicode(space.unwrap(w_str))) +# XXX needs to change when we stop faking unicode! +delegate__String.result_class = fake.fake_type(unicode) +delegate__String.priority = PRIORITY_CHANGE_TYPE +delegate__String.can_fail = True + + def _isspace(ch): return ord(ch) in (9, 10, 11, 12, 13, 32) @@ -919,18 +929,6 @@ buf[i+len(left)] = right[i] return space.wrap("".join(buf)) -def mod_str_tuple(space, w_format, w_args): - # XXX implement me - format = space.unwrap(w_format) - args = space.unwrap(w_args) - try: - s = format % args - except TypeError, e: - raise OperationError(space.w_TypeError, space.wrap(str(e))) - except ValueError, e: - raise OperationError(space.w_ValueError, space.wrap(str(e))) - return space.wrap(s) - def len__String(space, w_str): return space.wrap(len(space.unwrap(w_str))) @@ -981,8 +979,7 @@ if isinstance(values, tuple): return _formatting.format(format, values, None) else: - if hasattr(values, '__getitem__') and \ - not isinstance(values, (str, list)): + if hasattr(values, 'keys'): return _formatting.format(format, (values,), values) else: return _formatting.format(format, (values,), None) From mwh at codespeak.net Fri Jul 23 12:39:48 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jul 2004 12:39:48 +0200 (MEST) Subject: [pypy-svn] r5629 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040723103948.DEFF85A0F8@thoth.codespeak.net> Author: mwh Date: Fri Jul 23 12:39:48 2004 New Revision: 5629 Modified: pypy/trunk/src/pypy/objspace/std/intobject.py pypy/trunk/src/pypy/objspace/std/longobject.py pypy/trunk/src/pypy/objspace/std/test/test_intobject.py Log: paper over int**(negative int) shaped holes. Modified: pypy/trunk/src/pypy/objspace/std/intobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/intobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/intobject.py Fri Jul 23 12:39:48 2004 @@ -224,6 +224,9 @@ raise OperationError(space.w_TypeError, space.wrap("pow() 2nd argument " "cannot be negative when 3rd argument specified")) + return space.pow(space.float(space.wrap(iv)), + space.float(space.wrap(iw)), + space.w_None) ## bounce it, since it always returns float raise FailedToImplement(space.w_ValueError, space.wrap("integer exponentiation")) @@ -250,7 +253,7 @@ except OverflowError: raise FailedToImplement(space.w_OverflowError, space.wrap("integer exponentiation")) - return ix + return W_IntObject(space, ix) """ def pow__Int_Int_Int(space, w_int1, w_int2, w_int3): @@ -265,14 +268,12 @@ x = w_int1.intval y = w_int2.intval z = w_int3.intval - ret = _impl_int_int_pow(space, x, y, z) - return W_IntObject(space, ret) + return _impl_int_int_pow(space, x, y, z) def pow__Int_Int_None(space, w_int1, w_int2, w_int3): x = w_int1.intval y = w_int2.intval - ret = _impl_int_int_pow(space, x, y) - return W_IntObject(space, ret) + return _impl_int_int_pow(space, x, y) def neg__Int(space, w_int1): a = w_int1.intval Modified: pypy/trunk/src/pypy/objspace/std/longobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/longobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/longobject.py Fri Jul 23 12:39:48 2004 @@ -17,7 +17,6 @@ assert isinstance(longval, long) w_self.longval = longval - registerimplementation(W_LongObject) # int-to-long delegation @@ -38,6 +37,11 @@ delegate__Long.priority = PRIORITY_CHANGE_TYPE delegate__Long.can_fail = True +## # long-to-float delegation +## def delegate__Long(space, w_longobj): +## return W_FloatObject(space, float(w_longobj.longval)) +## delegate__Long.result_class = W_FloatObject +## delegate__Long.priority = PRIORITY_CHANGE_TYPE # long__Long is supposed to do nothing, unless it has # a derived long object, where it should return @@ -145,6 +149,10 @@ def pow__Long_Long_None(space, w_long1, w_long2, w_none3): x = w_long1.longval y = w_long2.longval + if y < 0: + return space.pow(space.float(w_long1), + space.float(w_long2), + space.w_None) z = x ** y return W_LongObject(space, z) Modified: pypy/trunk/src/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_intobject.py Fri Jul 23 12:39:48 2004 @@ -170,9 +170,6 @@ f1, f2 = [iobj.W_IntObject(self.space, i) for i in (10, 20)] self.assertEquals(self.space.w_OverflowError, self._unwrap_nonimpl(iobj.pow__Int_Int_None, self.space, f1, f2, self.space.w_None)) - f1, f2 = [iobj.W_IntObject(self.space, i) for i in (10, -1)] - self.assertEquals(self.space.w_ValueError, - self._unwrap_nonimpl(iobj.pow__Int_Int_None, self.space, f1, f2, self.space.w_None)) def test_neg(self): x = 42 @@ -322,5 +319,8 @@ n = sys.maxint + 1 self.assert_(isinstance(n, long)) + def test_pow(self): + self.assertEquals(pow(2, -10), 1/1024.) + if __name__ == '__main__': testit.main() From mwh at codespeak.net Fri Jul 23 12:46:25 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jul 2004 12:46:25 +0200 (MEST) Subject: [pypy-svn] r5630 - pypy/trunk/src/pypy/appspace Message-ID: <20040723104625.0A0F05A0F8@thoth.codespeak.net> Author: mwh Date: Fri Jul 23 12:46:24 2004 New Revision: 5630 Modified: pypy/trunk/src/pypy/appspace/_formatting.py Log: a completely over-the-top implementation of converting floating point numbers to strings. unfortunately, still not perfect (see XXXes), but much better than what went before.. Modified: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_formatting.py Fri Jul 23 12:46:24 2004 @@ -1,3 +1,7 @@ +# Application level implementation of string formatting. + +# There's some insane stuff in here. Blame CPython. Please. + class _Flags(object): def __repr__(self): return "<%s>"%(', '.join([f for f in self.__dict__ @@ -96,6 +100,43 @@ self.width = width self.prec = prec self.value = value + + def numeric_preprocess(self, v): + # negative zeroes? + # * mwh giggles, falls over + # still, if we can recognize them, here's the place to do it. + if v < 0: + sign = '-' + v = -v + else: + if self.flags.f_sign: + sign = '+' + elif self.flags.f_blank: + sign = ' ' + else: + sign = '' + return v, sign + + def numeric_postprocess(self, r, sign): + assert self.char in 'iduoxXeEfFgG' + + padchar = ' ' + if self.flags.f_zero: + padchar = '0' + + if self.width is not None: + p = self.width - len(r) - len(sign) + if self.flags.f_ljust: + r = sign + r + ' '*p + else: + if self.flags.f_zero: + r = sign+padchar*p + r + else: + r = padchar*p + sign + r + else: + r = sign + r + return r + def format(self): raise NotImplementedError @@ -138,68 +179,222 @@ raise TypeError, "float argument is required" return floater() +import math + +# from the excessive effort department, routines for printing floating +# point numbers from + +# "Printing Floating-Point Numbers Quickly and Accurately" by Burger & +# Dybvig, Proceedings of the SIGPLAN '96 Conference on Programming +# Language Design and Implementation. + +# The paper contains scheme code which has been specialized for IEEE +# doubles and converted into (still somewhat scheme-like) Python by +# Michael Hudson. + +# XXX unfortunately, we need the fixed-format output routines, the source +# for which is not included in the paper... for now, just put up with +# occasionally incorrectly rounded final digits. I'll get to it. + +# XXX should run this at interpreter level, really.... + +## (define flonum->digits +## (lambda (v f e min-e p b B) +## (if (>= e 0) +## (if (not (= f (expt b (- p 1)))) +## (let ([be (expt b e)]) +## (scale (* f be 2) 2 be be 0 B v)) +## (let* ([be (expt b e)] [be1 (* be b)]) +## (scale (* f be1 2) (* b 2) be1 be 0 B v))) +## (if (or (= e min-e) (not (= f (expt b (- p 1))))) +## (scale (* f 2) (* (expt b (- e)) 2) 1 1 0 B v) +## (scale (* f b 2) (* (expt b (- 1 e)) 2) b 1 0 B v))))) + +def flonum2digits(v, f, e, B): + + # sod generality in the extreme: we're working with ieee 754 64 + # bit doubles on any platform I care about. + # this means b == 2, min-e = -1075 (?), p = 53 above + + # in: + # v = f * 2**e + # B is output base + + # out: + # [d0, d1, ..., dn], k + # st 0.[d1][d2]...[dn] * B**k is the "best" representation of v + + if e >= 0: + if not f != 2**52: + be = 2**e + return scale(f*be*2, 2, be, be, 0, B, v) + else: + be = 2**e + be1 = 2*be + return scale(f*be1*2, 4, be1, be, 0, B, v) + else: + if e == -1075 or f != 2**52: + return scale(f*2, 2*2**(-e), 1, 1, 0, B, v) + else: + return scale(f*4, 2*2**(1-e), 2, 1, 0, B, v) + +## (define generate +## (lambda (r s m+ m- B low-ok? high-ok?) +## (let ([q-r (quotient-remainder (* r B) s)] +## [m+ (* m+ B)] +## [m- (* m- B)]) +## (let ([d (car q-r)] +## [r (cdr q-r)]) +## (let ([tc1 ((if low-ok? <= <) r m-)] +## [tc2 ((if high-ok? >= >) (+ r m+) s)]) +## (if (not tc1) +## (if (not tc2) +## (cons d (generate r s m+ m- B low-ok? high-ok?)) +## (list (+ d 1))) +## (if (not tc2) +## (list d) +## (if (< (* r 2) s) +## (list d) +## (list (+ d 1)))))))))) + +# now the above is an example of a pointlessly recursive algorithm if +# ever i saw one... + +def generate(r, s, m_plus, m_minus, B): + rr = [] + while 1: + d, r = divmod(r*B, s) + m_plus *= B + m_minus *= B + tc1 = r < m_minus + tc2 = (r + m_plus) > s + if tc2: + rr.append(d+1) + else: + rr.append(d) + if tc1 or tc2: + break + return rr + +## (define scale +## (lambda (r s m+ m- k B low-ok? high-ok? v) +## (let ([est (inexact->exact (ceiling (- (logB B v) 1e-10)))]) +## (if (>= est 0) +## (fixup r (* s (exptt B est)) m+ m- est B low-ok? high-ok? ) +## (let ([scale (exptt B (- est))]) +## (fixup (* r scale) s (* m+ scale) (* m- scale) est B low-ok? high-ok? )))))) + +def scale(r, s, m_plus, m_minus, k, B, v): + est = long(math.ceil(math.log(v, B) - 1e-10)) + if est >= 0: + return fixup(r, s * B ** est, m_plus, m_minus, est, B) + else: + scale = B ** -est + return fixup(r*scale, s, m_plus*scale, m_minus*scale, est, B) + +## (define fixup +## (lambda (r s m+ m- k B low-ok? high-ok? ) +## (if ((if high-ok? >= >) (+ r m+) s) ; too low? +## (cons (+ k 1) (generate r (* s B) m+ m- B low-ok? high-ok? )) +## (cons k (generate r s m+ m- B low-ok? high-ok? ))))) + +def fixup(r, s, m_plus, m_minus, k, B): + if r + m_plus > s: + return generate(r, s*B, m_plus, m_minus, B), k + 1 + else: + return generate(r, s, m_plus, m_minus, B), k + + +def float_digits(f): + assert f >= 0 + if f == 0.0: + return [], 1 + m, e = math.frexp(f) + m = long(m*2.0**53) + e -= 53 + ds, k = flonum2digits(f, m, e, 10) + ds = map(str, ds) + return ds, k + class floatFFormatter(Formatter): def format(self): v = maybe_float(self.value) + if abs(v)/1e25 > 1e25: + return floatGFormatter('g', self.flags, self.width, + self.prec, self.value).format() + v, sign = self.numeric_preprocess(v) + if self.prec is None: self.prec = 6 - r = str(int(v)) - # XXX this is a bit horrid - if self.prec > 0: - frac_part = str(v%1)[1:2+self.prec] - if len(frac_part) < self.prec + 1: - frac_part += (1 + self.prec - len(frac_part)) * '0' - r += frac_part - if v >= 0.0 and self.flags.f_sign: - r = '+' + r - self.prec = None - return self.std_wp(r) -import math + # we want self.prec digits after the radix point. + + # this is probably more complex than it needs to be: + p = max(self.prec, 0) + ds, k = float_digits(v) + if 0 < k < len(ds): + if len(ds) - k < p: + ds.extend(['0'] * (p - (len(ds) - k))) + else: + ds = ds[:p + k] + ds[k:k] = ['.'] + elif k <= 0: + ds[0:0] = ['0']*(-k) + ds = ds[:p] + ds.extend(['0'] * (p - len(ds))) + ds[0:0]= ['0', '.'] + elif k >= len(ds): + ds.extend((k-len(ds))*['0'] + ['.'] + ['0']*p) + + if self.prec <= 0: + del ds[-1] + + return self.numeric_postprocess(''.join(ds), sign) + +class floatEFormatter(Formatter): + def format(self): + v = maybe_float(self.value) + + v, sign = self.numeric_preprocess(v) + + if self.prec is None: + self.prec = 6 + + ds, k = float_digits(v) + ds = ds[:self.prec + 1] + ['0'] * (self.prec + 1 - len(ds)) + ds[1:1] = ['.'] + + r = ''.join(ds) + self.char + "%+03d"%(k-1,) + + return self.numeric_postprocess(r, sign) class floatGFormatter(Formatter): + # the description of %g in the Python documentation lies. def format(self): - # this needs to be much, much more complicated :-( (perhaps - # should just punt to host Python -- which in turn punts to - # libc) v = maybe_float(self.value) + + v, sign = self.numeric_preprocess(v) + if self.prec is None: self.prec = 6 - i = 0 - if v == 0.0: - if self.flags.f_sign: - return '+0' - else: - return '0' - elif v < 0.0: - sign = '-' - v = -v - else: - sign = '+' - p = math.floor(math.log(v, 10)) - if p < 0: - r = ['0', '.'] + ['0'] * (-int(p)) - r = [] - vv = v - tol = abs(v*10.0**-self.prec) - while 1: - d = long(vv/10.0**p) - vv -= d*10.0**p - r.append(str(d)) - if abs(vv) <= tol: - break - p -= 1 - if p == -1: - r.append('.') - while p > 0: - r.append('0') - p -= 1 - r = ''.join(r) - if sign == '-' or self.flags.f_sign: - r = sign + r - self.prec = None - return self.std_wp(r) + ds, k = float_digits(v) + + ds = ds[:self.prec] # XXX rounding! + + if -4 < k < self.prec: + if 0 < k < len(ds): + ds[k:k] = ['.'] + if k <= 0: + ds[0:0] = ['0', '.'] + ['0']*(-k) + elif k >= len(ds): + ds.extend((k-len(ds))*['0']) + r = ''.join(ds) + else: + ds[1:1] = ['.'] + r = ''.join(ds) + self.char + "%+03d"%(k-1,) + + return self.numeric_postprocess(r, sign) class HexFormatter(Formatter): def format(self): @@ -211,12 +406,23 @@ r = r.upper() return self.std_wp(r) +class OctFormatter(Formatter): + def format(self): + i = maybe_int(self.value) + r = oct(i) + if not self.flags.f_alt: + r = r[1:] + return self.std_wp(r) + format_registry = { 's':funcFormatter(str), 'r':funcFormatter(repr), 'x':HexFormatter, 'X':HexFormatter, + 'o':OctFormatter, 'd':funcFormatter(maybe_int, str), + 'e':floatEFormatter, + 'E':floatEFormatter, 'f':floatFFormatter, 'g':floatGFormatter, } From mwh at codespeak.net Fri Jul 23 12:50:42 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jul 2004 12:50:42 +0200 (MEST) Subject: [pypy-svn] r5631 - pypy/trunk/src/pypy Message-ID: <20040723105042.2E15B5A0F8@thoth.codespeak.net> Author: mwh Date: Fri Jul 23 12:50:41 2004 New Revision: 5631 Modified: pypy/trunk/src/pypy/TODO Log: just move a couple of items out of the StdObjSpace section Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Fri Jul 23 12:50:41 2004 @@ -13,6 +13,19 @@ * an oldie: move interpreter/unittest_w.py somewhere more appropriate and give it a better name. +* (documentation) remove/retire all web-pages referencing e.g. + AnnSpace or other deprecated stuff + +* Review, enhance the new mixed-level module mechanism + (e.g. the module/builtin*.py files comprise the builtin module) + and try to apply the same technique for the application level + type definitions (types.py). Think about a way to split up + especially app-level definitions of __builtin__ into multiple + files. (like allowing __builtin__ to be a directory with files + comprising the complete definition of the builtin module etc.pp) + +* review whatever you like + StdObjSpace =========== @@ -34,19 +47,6 @@ * port pypy's testing framework to std.utest (probably a sprint topic, as some discussion how to do it is required) -* (documentation) remove/retire all web-pages referencing e.g. - AnnSpace or other deprecated stuff - -* Review, enhance the new mixed-level module mechanism - (e.g. the module/builtin*.py files comprise the builtin module) - and try to apply the same technique for the application level - type definitions (types.py). Think about a way to split up - especially app-level definitions of __builtin__ into multiple - files. (like allowing __builtin__ to be a directory with files - comprising the complete definition of the builtin module etc.pp) - -* review whatever you like - * clear out and do a clean implementation of multimethod delegation. The idea is to give 'kinds' to arguments according to their use, e.g. 'numeric argument' or 'object whose identity is preserved'. From mwh at codespeak.net Fri Jul 23 15:30:06 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 23 Jul 2004 15:30:06 +0200 (MEST) Subject: [pypy-svn] r5633 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040723133006.F35F85A0F8@thoth.codespeak.net> Author: mwh Date: Fri Jul 23 15:30:06 2004 New Revision: 5633 Added: pypy/trunk/src/pypy/objspace/std/unicodeobject.py pypy/trunk/src/pypy/objspace/std/unicodetype.py Modified: pypy/trunk/src/pypy/objspace/std/fake.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/stringobject.py Log: less insane way of mostly-faking but slightly not unicode objects. Modified: pypy/trunk/src/pypy/objspace/std/fake.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/fake.py (original) +++ pypy/trunk/src/pypy/objspace/std/fake.py Fri Jul 23 15:30:06 2004 @@ -51,16 +51,6 @@ base = basestring_typedef else: base = None - if cpy_type is unicode: - # XXX no hacks here, oh no, none at all. well maybe a - # XXX little one... - def uni_cmp(space, w_uni, w_other): - try: - return space.wrap(cmp(space.unwrap(w_uni), - space.unwrap(w_other))) - except: - wrap_exception(space) - kw['__cmp__'] = gateway.interp2app(uni_cmp) class W_Fake(W_Object): typedef = StdTypeDef( cpy_type.__name__, base, **kw) @@ -70,14 +60,6 @@ def fake_unwrap(space, w_obj): return w_obj.val StdObjSpace.unwrap.register(fake_unwrap, W_Fake) - if cpy_type is unicode: - # more unicode hacks! - def fake_ord(space, w_uni): - try: - return space.wrap(ord(w_uni.val)) - except: - wrap_exception(space) - StdObjSpace.MM.ord.register(fake_ord, W_Fake) W_Fake.__name__ = 'W_Fake(%s)'%(cpy_type.__name__) W_Fake.typedef.fakedcpytype = cpy_type # XXX obviously this entire file is something of a hack, but it @@ -100,4 +82,4 @@ setattr(W_Fake, "call_args", call_args) _fake_type_cache[cpy_type] = W_Fake return W_Fake - + Modified: pypy/trunk/src/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/std/objspace.py Fri Jul 23 15:30:06 2004 @@ -63,6 +63,7 @@ from pypy.objspace.std.typetype import type_typedef from pypy.objspace.std.slicetype import slice_typedef from pypy.objspace.std.longtype import long_typedef + from pypy.objspace.std.unicodetype import unicode_typedef return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look @@ -151,11 +152,12 @@ from pypy.objspace.std import longobject from pypy.objspace.std import noneobject from pypy.objspace.std import iterobject + from pypy.objspace.std import unicodeobject # hack to avoid imports in the time-critical functions below global W_ObjectObject, W_BoolObject, W_IntObject, W_FloatObject global W_TupleObject, W_ListObject, W_DictObject, W_StringObject global W_TypeObject, W_SliceObject, W_LongObject, W_NoneObject - global W_SeqIterObject + global W_SeqIterObject, W_UnicodeObject W_ObjectObject = objectobject.W_ObjectObject W_BoolObject = boolobject.W_BoolObject W_IntObject = intobject.W_IntObject @@ -169,6 +171,7 @@ W_LongObject = longobject.W_LongObject W_NoneObject = noneobject.W_NoneObject W_SeqIterObject = iterobject.W_SeqIterObject + W_UnicodeObject = unicodeobject.W_UnicodeObject # end of hacks # singletons self.w_None = W_NoneObject(self) @@ -245,7 +248,7 @@ if isinstance(x, type(Exception)) and issubclass(x, Exception): if hasattr(self, 'w_' + x.__name__): return getattr(self, 'w_' + x.__name__) - import fake + from pypy.objspace.std import fake if isinstance(x, type): return self.gettypeobject(fake.fake_type(x).typedef) return fake.fake_type(type(x))(self, x) Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Fri Jul 23 15:30:06 2004 @@ -101,15 +101,6 @@ registerimplementation(W_StringObject) -# string-to-unicode delegation -import fake -def delegate__String(space, w_str): - return space.wrap(unicode(space.unwrap(w_str))) -# XXX needs to change when we stop faking unicode! -delegate__String.result_class = fake.fake_type(unicode) -delegate__String.priority = PRIORITY_CHANGE_TYPE -delegate__String.can_fail = True - def _isspace(ch): return ord(ch) in (9, 10, 11, 12, 13, 32) Added: pypy/trunk/src/pypy/objspace/std/unicodeobject.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/unicodeobject.py Fri Jul 23 15:30:06 2004 @@ -0,0 +1,33 @@ +from pypy.objspace.std.objspace import * +from pypy.objspace.std.fake import fake_type, wrap_exception +from pypy.objspace.std.stringobject import W_StringObject + +W_UnicodeObject = fake_type(unicode) + +# string-to-unicode delegation +def delegate__String(space, w_str): + return W_Unicode(space, unicode(w_str)) +delegate__String.result_class = W_UnicodeObject +delegate__String.priority = PRIORITY_CHANGE_TYPE +delegate__String.can_fail = True + +def eq__Unicode_ANY(space, w_uni, w_other): + try: + return space.newbool(space.unwrap(w_uni) == space.unwrap(w_other)) + except: + wrap_exception(space) + +def lt__Unicode_ANY(space, w_uni, w_other): + try: + return space.newbool(space.unwrap(w_uni) < space.unwrap(w_other)) + except: + wrap_exception(space) + +def ord__Unicode(space, w_uni): + try: + return space.wrap(ord(w_uni.val)) + except: + wrap_exception(space) + + +register_all(vars()) Added: pypy/trunk/src/pypy/objspace/std/unicodetype.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/unicodetype.py Fri Jul 23 15:30:06 2004 @@ -0,0 +1,3 @@ +from pypy.objspace.std.fake import fake_type + +unicode_typedef = fake_type(unicode).typedef From pedronis at codespeak.net Sat Jul 24 13:36:52 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 13:36:52 +0200 (MEST) Subject: [pypy-svn] r5639 - pypy/trunk/doc/funding/negotiations Message-ID: <20040724113652.078A45AE7F@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 13:36:52 2004 New Revision: 5639 Removed: pypy/trunk/doc/funding/negotiations/part_b_2004_04_02.sxw Log: remove spuriously modified doc. Deleted: /pypy/trunk/doc/funding/negotiations/part_b_2004_04_02.sxw ============================================================================== Binary file. No diff available. From pedronis at codespeak.net Sat Jul 24 13:37:17 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 13:37:17 +0200 (MEST) Subject: [pypy-svn] r5640 - pypy/trunk/doc/funding/negotiations Message-ID: <20040724113717.92CC75B104@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 13:37:16 2004 New Revision: 5640 Added: pypy/trunk/doc/funding/negotiations/part_b_2004_04_02.sxw - copied unchanged from r5638, pypy/trunk/doc/funding/makedoc/part_b_2004_04_02.sxw Log: recopy right version From pedronis at codespeak.net Sat Jul 24 17:05:11 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 17:05:11 +0200 (MEST) Subject: [pypy-svn] r5641 - pypy/trunk/doc/funding Message-ID: <20040724150511.907EB5B0F1@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 17:05:10 2004 New Revision: 5641 Modified: pypy/trunk/doc/funding/B0.0_preamble.txt pypy/trunk/doc/funding/B2.relevance_to_IST.txt pypy/trunk/doc/funding/B4.resources.txt pypy/trunk/doc/funding/B6.0_detailed_implementation.txt Log: removed PBF as partner references. Up to table in B4. Going to change that in the next commit. Editing it sucks, after much pain, I wrote a quick hack that generates it, we already had logic to capture the data in man-months.py btw. Modified: pypy/trunk/doc/funding/B0.0_preamble.txt ============================================================================== --- pypy/trunk/doc/funding/B0.0_preamble.txt (original) +++ pypy/trunk/doc/funding/B0.0_preamble.txt Sat Jul 24 17:05:10 2004 @@ -65,8 +65,6 @@ ---------------- --------------------------------------------- ----------------------- 2 University of Southampton USH ---------------- --------------------------------------------- ----------------------- -4 Python Business Forum PBF ----------------- --------------------------------------------- ----------------------- 5 AB Strakt Strakt ---------------- --------------------------------------------- ----------------------- 6 Logilab Logilab Modified: pypy/trunk/doc/funding/B2.relevance_to_IST.txt ============================================================================== --- pypy/trunk/doc/funding/B2.relevance_to_IST.txt (original) +++ pypy/trunk/doc/funding/B2.relevance_to_IST.txt Sat Jul 24 17:05:10 2004 @@ -149,7 +149,8 @@ Participation of SME's in High-Level Research +++++++++++++++++++++++++++++++++++++++++++++ -The consortium includes the Python Business Forum, an international trade +The consortium will closely interact with the Python Business Forum +(of which some members are part), an international trade association of SMEs who develop using the Python programming language, and other SME partners. Since SMEs are the main engines for innovation, growth, and competitiveness Modified: pypy/trunk/doc/funding/B4.resources.txt ============================================================================== --- pypy/trunk/doc/funding/B4.resources.txt (original) +++ pypy/trunk/doc/funding/B4.resources.txt Sat Jul 24 17:05:10 2004 @@ -351,47 +351,12 @@ books into German, is the author of the Stackless Python extension to be merged into PyPy, and is one of the founders of the PyPy project. -Python Business Forum -+++++++++++++++++++++ - -:: - - Role: Dissemination - Country: Europe - Contact: Holger Krekel - -The PBF (http://python-in-business.org) is an industry organisation -of companies where Python is a central part of the business -model. The PBF is registered as a non-profit organisation under -Swedish law. It has approximately 50 SME members. The Forum has a -board, which focuses on administration and strategic issues, while the -main activities occur in Special Interest Groups (SIGs). Each SIG -controls its own activities but reports to the board in financial -matters. - -Activities of the PBF include sharing business leads, marketing Python -as a programming platform and assisting in the quality assurance for -the main implementation of the language. - -The PBF will form a PyPy SIG with **Holger Krekel** as chairman to -handle its involvement in the project. Membership in EU funded activities -will be restricted to Members of the EU and the Candidate countries, as -part of the charter of this SIG. - Sub-Contracting --------------- Some pure accounting and auditing tasks will be subcontracted. No core technical functions or project management will be handed to non-partners. -Other Countries ---------------- - -While this project is of international interest, and while the PBF is -an international Trade organisation, Membership in the PyPy PBF SIG, -where EU funded activity will take place, is restricted to members of -the European Union and the Candidate countries. - Quality of Partnership, Involvement of Users and SMEs ----------------------------------------------------- @@ -460,30 +425,6 @@ With 7 full time employees, Logilab is an SME representative. -**Python Business Forum** -brings a number of SME parties to the project who are eager to apply PyPy -to their various products. They are user Stakeholders, and the primary -intended audience of some of our reports. Many of them, on their own, -have expressed a desire to encorporate PyPy into their products as soon -as it is finished and stable. We will report on their progress to the -Commission as well, even though they are not to be funded by the -Commission, as an extra point of reference. - -The PBF also provides important outreach to the members of Eastern -Europe, and Candidate Countries. Since its founding, it has had -a board member responsible for precisely that: - -- I've been a PBF board member from its founding. I am responsible for - the Eastern Europe liaisons. I am an intermediary of sorts between - the PBF and the businesses located in the candidate countries of - Eastern Europe. The PBF is an important link between businesses in - the EU and the candidate countries. - - Jacek Artymiak - -Extra care will be taken to see that our results will be properly -disseminated to our PBF members in the Candidate Countries. - **Holger Krekel** will have a focus on development, packaging and dissemination tools. He will also be a main contributor in matters of @@ -556,8 +497,8 @@ The second is Finance. We don't need to mobilise outside financial contributions, though we have some excellent connections. AB Strakt, Krekel, Martelli and Tismer have already arranged for bank -guarantees, should they be required by the Commission. The PBF and AB -Strakt both use KPMG as their standard auditor, and a KPMG recommended +guarantees, should they be required by the Commission. AB +Strakt uses KPMG as its standard auditor, and a KPMG recommended bookkeeper who is familiar with EU project funding for their daily business practices. Everybody else has already been involved in successful EU projects, and will simply continue their usual Modified: pypy/trunk/doc/funding/B6.0_detailed_implementation.txt ============================================================================== --- pypy/trunk/doc/funding/B6.0_detailed_implementation.txt (original) +++ pypy/trunk/doc/funding/B6.0_detailed_implementation.txt Sat Jul 24 17:05:10 2004 @@ -469,8 +469,8 @@ adoption of the novel technologies being developed. We expect all developers and participants to openly report to and discuss with their appropriate communities. Reports and summaries will be posted to the relevant mailing -lists as well as archived on both the PyPy and the Python Business Forum -website for universal availability. WP14_ is to support this process at all +lists as well as archived on both the PyPy (and the Python Business Forum +website) for universal availability. WP14_ is to support this process at all levels. Moreover, WP14_ will produce a joint report about agile methodologies From pedronis at codespeak.net Sat Jul 24 17:20:57 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 17:20:57 +0200 (MEST) Subject: [pypy-svn] r5642 - pypy/trunk/doc/funding Message-ID: <20040724152057.7ABAA5B555@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 17:20:56 2004 New Revision: 5642 Added: pypy/trunk/doc/funding/table4.py (contents, props changed) Modified: pypy/trunk/doc/funding/B4.resources.txt Log: removed PBF from table in B4. script for generating the table (don't look at it) Modified: pypy/trunk/doc/funding/B4.resources.txt ============================================================================== --- pypy/trunk/doc/funding/B4.resources.txt (original) +++ pypy/trunk/doc/funding/B4.resources.txt Sat Jul 24 17:20:56 2004 @@ -595,63 +595,62 @@ Full duration of project: 24 months - -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -| |DFKI |USH |PBF |Strakt |Logilab |CM |Krekel |Martelli |Tismer |Total | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Research and | | | | | | | | | | | -|Innovation | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP2: Infrastructure | | | | | | | 8| | | 8| -|and Tools | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP3: Synchronisation | | 3| | | | | | | 6| 9| -|with Standard Python | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP4: PyPy Core | 4| | | 6| 5| | 3| | 4| 22| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP5: PyPy Translation| 2| 8| | 15| | | 1| | 2| 28| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP6: Core | | 12| | | | | | | | 12| -|Optimisations | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP7: Translator | | 3| | | | | 4| | 9 | 16| -|Optimisations | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP8: Dynamic | | 6| | 17| | | | | 2| 25| -|Optimisations | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP9: Search and Logic| 10| | | | 9| | | | | 19| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP10: Aspects and | 3| | | | 9| | | | | 12| -|Contracts | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP11: Specialised | | | | | 5| 1| | | | 6| -|Hardware | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP12: Security, | | 3| | 10| | | | | | | -|Distribution and | | | | | | | | | | 13| -|Persistence | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP13: Integration and| 4| | | | 4| | 4| | | 12| -|Configuration | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP14: Documentaion | | | | | | 11| | 12| | 24| -|and Dissemination | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -| | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Total Research and | 23| 35| 0| 48| 32| 12| 20| 12| 23| 205| -|Innovation | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Management | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP1: Coordination and| 4| | | 4| | 4| | | | 12| -|Management | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -| | | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Total | 27| 35| 0| 52| 32| 16| 20| 12| 23| 217| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +| |DFKI |USH |Strakt |Logilab |CM |Krekel |Martelli |Tismer |Total | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|Research and | | | | | | | | | | +|Innovation | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP2: Infrastructure | | | | | | 8| | | 8| +|and Tools | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP3: Synchronisation | | 3| | | | | | 6| 9| +|with Standard Python | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP4: PyPy Core | 4| | 6| 5| | 3| | 4| 22| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP5: PyPy Translation| 2| 8| 15| | | 1| | 2| 28| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP6: Core | | 12| | | | | | | 12| +|Optimisations | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP7: Translator | | 3| | | | 4| | 9| 16| +|Optimisations | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP8: Dynamic | | 6| 17| | | | | 2| 25| +|Optimisations | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP9: Search and Logic| 10| | | 9| | | | | 19| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP10: Aspects and | 3| | | 9| | | | | 12| +|Contracts | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP11: Specialised | | | | 5| 1| | | | 6| +|Hardware | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP12: Security, | | 3| 10| | | | | | 13| +|Distribution and | | | | | | | | | | +|Persistence | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP13: Integration and| 4| | | 4| | 4| | | 12| +|Configuration | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP14: Documentaion | | | | | 11| | 12| | 23| +|and Dissemination | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +| | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|Total Research and | 23| 35| 48| 32| 12| 20| 12| 23| 205| +|Innovation | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|Management | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|WP1: Coordination and| 4| | 4| | 4| | | | 12| +|Management | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +| | | | | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ +|Total | 27| 35| 52| 32| 16| 20| 12| 23| 217| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ Added: pypy/trunk/doc/funding/table4.py ============================================================================== --- (empty file) +++ pypy/trunk/doc/funding/table4.py Sat Jul 24 17:20:56 2004 @@ -0,0 +1,198 @@ +cols =[21, 14, 14, + #14, + 14, 14, 14, 14, 14, 13, 14] + +col_titles =['', + 'DFKI', + 'USH', + #'PBF', + 'Strakt', + 'Logilab', + 'CM', + 'Krekel', + 'Martelli', + 'Tismer', + 'Total'] + +row_titles = [ + ('Research and', 'Innovation'), + ('WP2: Infrastructure', 'and Tools'), + ('WP3: Synchronisation', 'with Standard Python'), + ('WP4: PyPy Core',), + ('WP5: PyPy Translation',), + ('WP6: Core', 'Optimisations'), + ('WP7: Translator', 'Optimisations'), + ('WP8: Dynamic', 'Optimisations'), + ('WP9: Search and Logic',), + ('WP10: Aspects and', 'Contracts'), + ('WP11: Specialised', 'Hardware'), + ('WP12: Security,', 'Distribution and', 'Persistence'), + ('WP13: Integration and', 'Configuration'), + ('WP14: Documentaion', 'and Dissemination'), + ('',), + ('Total Research and', 'Innovation'), + ('Management',), + ('WP1: Coordination and', 'Management'), + ('',), + ('Total',), +] + +wp_to_title = {} + +for title in row_titles: + fst = title[0] + if fst.startswith('WP'): + wp = "%02d" % int(fst.split(':')[0][2:]) + wp_to_title[wp] = title + + +table_from_files = {} + +import os + +for fn in os.listdir('.'): + if fn.startswith('B6.7.wp') and fn.endswith('.txt'): + wp = fn[7:9] + entry = table_from_files[wp_to_title[wp]] = {} + data = {} + for line in file(fn): + if line.startswith('.. |'): + value = line[21:].strip() + if value != '|e|': + data[line[4:6]] = value + for n in range(1,7): + if ('p%d' % n) in data: + partner = data['p%d' % n].lower().capitalize() + if partner == 'Dkfi': + partner = 'Dfki' + if len(partner) <= 4: + partner = partner.upper() + entry[partner] = int(data['m%d' % n]) + +#print wp_to_title +#print table_from_files + +table = { + ('Research and', 'Innovation'): + None, + ('WP2: Infrastructure', 'and Tools'): + { 'DFKI': 0, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 8, 'Martelli': 0, 'Tismer': 0, }, + ('WP3: Synchronisation', 'with Standard Python'): + { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 6, }, + ('WP4: PyPy Core',): + { 'DFKI': 4, 'USH': 0, 'PBF': 0, 'Strakt': 6, 'Logilab': 5, 'CM': 0, 'Krekel': 3, 'Martelli': 0, 'Tismer': 4, }, + ('WP5: PyPy Translation',): + { 'DFKI': 2, 'USH': 8, 'PBF': 0, 'Strakt': 15, 'Logilab': 0, 'CM': 0, 'Krekel': 1, 'Martelli': 0, 'Tismer': 2, }, + ('WP6: Core', 'Optimisations'): + { 'DFKI': 0, 'USH': 12, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, + ('WP7: Translator', 'Optimisations'): + { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 4, 'Martelli': 0, 'Tismer': 9, }, + ('WP8: Dynamic', 'Optimisations'): + { 'DFKI': 0, 'USH': 6, 'PBF': 0, 'Strakt': 17, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 2, }, + ('WP9: Search and Logic',): + { 'DFKI': 10, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 9, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, + ('WP10: Aspects and', 'Contracts'): + { 'DFKI': 3, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 9, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, + ('WP11: Specialised', 'Hardware'): + { 'DFKI': 0, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 5, 'CM': 1, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, + ('WP12: Security,', 'Distribution and', 'Persistence'): + { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 10, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, + ('WP13: Integration and', 'Configuration'): + { 'DFKI': 4, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 4, 'CM': 0, 'Krekel': 4, 'Martelli': 0, 'Tismer': 0, }, + ('WP14: Documentaion', 'and Dissemination'): + { 'DFKI': 0, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 11, 'Krekel': 0, 'Martelli': 12, 'Tismer': 0, }, + ('Total Research and', 'Innovation'): + (), + ('Management',): + None, + ('WP1: Coordination and', 'Management'): + { 'DFKI': 4, 'USH': 0, 'PBF': 0, 'Strakt': 4, 'Logilab': 0, 'CM': 4, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, + ('',): + None, + ('Total',): + (), +} + +def getdata(title): + if title in table and title not in table_from_files: + return table[title] + data = {} + for col in col_titles[:-1]: + if title in table: + v1 = table[title].get(col,0) + else: + v1 = 0 + if title in table_from_files: + v2 = table_from_files[title].get(col,0) + else: + v2 = 0 + assert v1 == v2 + data[col] = v1 + return data + +import sys + +w=sys.stdout.write + +def outval(v,width): + if isinstance(v,str): + w(v) + w(' '*(width-len(v))) + else: + s = str(v) + w(' '*(width-len(s))) + w(s) + +def sep(): + w('+') + for x in cols: + w("-"*x+"+") + w('\n') + +def row(title,data,zeros,total): + w('|') + outval(title[0],cols[0]) + w('|') + if data is None: + for wid in cols[1:]: + outval('',wid) + w('|') + else: + if total: + data = data + [sum(data)] + for wid,v in zip(cols[1:],data): + if not zeros and v == 0: + v = '' + outval(v,wid) + w('|') + w('\n') + if len(title) >= 2: + for x in title[1:]: + row((x,),None,False,False) + +sep() +row((col_titles[0],),col_titles[1:],False,False) +sep() + +tot = None +def addtot(data): + global tot + if tot is None: + tot = data[:] + else: + for i in range(len(tot)): + tot[i] += data[i] + +for title in row_titles: + data_dict = getdata(title) + if data_dict is None: + row(title,None,False,False) + elif data_dict == (): + row(title,tot,True,True) + else: + data = [] + for col in col_titles[1:-1]: + data.append(data_dict[col]) + row(title,data,False,True) + addtot(data) + sep() From pedronis at codespeak.net Sat Jul 24 17:38:42 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 17:38:42 +0200 (MEST) Subject: [pypy-svn] r5643 - pypy/trunk/doc/funding Message-ID: <20040724153842.E873B5B5EA@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 17:38:42 2004 New Revision: 5643 Modified: pypy/trunk/doc/funding/B4.resources.txt pypy/trunk/doc/funding/B6.0_detailed_implementation.txt Log: oops Modified: pypy/trunk/doc/funding/B4.resources.txt ============================================================================== --- pypy/trunk/doc/funding/B4.resources.txt (original) +++ pypy/trunk/doc/funding/B4.resources.txt Sat Jul 24 17:38:42 2004 @@ -499,7 +499,7 @@ Krekel, Martelli and Tismer have already arranged for bank guarantees, should they be required by the Commission. AB Strakt uses KPMG as its standard auditor, and a KPMG recommended -bookkeeper who is familiar with EU project funding for their daily +bookkeeper who is familiar with EU project funding for its daily business practices. Everybody else has already been involved in successful EU projects, and will simply continue their usual behaviour. Modified: pypy/trunk/doc/funding/B6.0_detailed_implementation.txt ============================================================================== --- pypy/trunk/doc/funding/B6.0_detailed_implementation.txt (original) +++ pypy/trunk/doc/funding/B6.0_detailed_implementation.txt Sat Jul 24 17:38:42 2004 @@ -469,8 +469,8 @@ adoption of the novel technologies being developed. We expect all developers and participants to openly report to and discuss with their appropriate communities. Reports and summaries will be posted to the relevant mailing -lists as well as archived on both the PyPy (and the Python Business Forum -website) for universal availability. WP14_ is to support this process at all +lists as well as archived on both the PyPy (and the Python Business Forum) +website for universal availability. WP14_ is to support this process at all levels. Moreover, WP14_ will produce a joint report about agile methodologies From pedronis at codespeak.net Sat Jul 24 17:41:12 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 17:41:12 +0200 (MEST) Subject: [pypy-svn] r5644 - pypy/trunk/doc/funding/negotiations Message-ID: <20040724154112.6F48A5B604@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 17:41:11 2004 New Revision: 5644 Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22.sxw Log: reflected PBF removal Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22.sxw ============================================================================== Binary files. No diff available. From mwh at codespeak.net Sat Jul 24 17:43:41 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 24 Jul 2004 17:43:41 +0200 (MEST) Subject: [pypy-svn] r5645 - pypy/trunk/src/pypy/appspace Message-ID: <20040724154341.00E0D5B61B@thoth.codespeak.net> Author: mwh Date: Sat Jul 24 17:43:41 2004 New Revision: 5645 Added: pypy/trunk/src/pypy/appspace/_float_formatting.py Modified: pypy/trunk/src/pypy/appspace/_formatting.py Log: Climbing out of the tarpit: take string formatting from 90% to 99%. See comments in _formatting for the remaining problems. Added: pypy/trunk/src/pypy/appspace/_float_formatting.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/_float_formatting.py Sat Jul 24 17:43:41 2004 @@ -0,0 +1,139 @@ +import math + +# from the excessive effort department, routines for printing floating +# point numbers from + +# "Printing Floating-Point Numbers Quickly and Accurately" by Burger & +# Dybvig, Proceedings of the SIGPLAN '96 Conference on Programming +# Language Design and Implementation. + +# The paper contains scheme code which has been specialized for IEEE +# doubles and converted into (still somewhat scheme-like) Python by +# Michael Hudson. + +# XXX unfortunately, we need the fixed-format output routines, the source +# for which is not included in the paper... for now, just put up with +# occasionally incorrectly rounded final digits. I'll get to it. + +# XXX should run this at interpreter level, really.... + + +## (define flonum->digits +## (lambda (v f e min-e p b B) +## (if (>= e 0) +## (if (not (= f (expt b (- p 1)))) +## (let ([be (expt b e)]) +## (scale (* f be 2) 2 be be 0 B v)) +## (let* ([be (expt b e)] [be1 (* be b)]) +## (scale (* f be1 2) (* b 2) be1 be 0 B v))) +## (if (or (= e min-e) (not (= f (expt b (- p 1))))) +## (scale (* f 2) (* (expt b (- e)) 2) 1 1 0 B v) +## (scale (* f b 2) (* (expt b (- 1 e)) 2) b 1 0 B v))))) + +# I reject generality in the extreme: we're working with +# ieee 754 64 bit doubles on any platform I care about. +# This means b == 2, min-e = -1074, p = 53 above. Also, +# specialize for B = 10. + +# in: +# v = f * 2**e +# out: +# [d0, d1, ..., dn], k +# st 0.[d1][d2]...[dn] * 10**k is the "best" representation of v + +def flonum2digits(v, f, e): + if e >= 0: + if not f != 2**52: + be = 2**e + return scale(f*be*2, 2, be, be, 0, v) + else: + be = 2**e + be1 = 2*be + return scale(f*be1*2, 4, be1, be, 0, v) + else: + if e == -1075 or f != 2**52: + return scale(f*2, 2*2**(-e), 1, 1, 0, v) + else: + return scale(f*4, 2*2**(1-e), 2, 1, 0, v) + + +## (define generate +## (lambda (r s m+ m- B low-ok? high-ok?) +## (let ([q-r (quotient-remainder (* r B) s)] +## [m+ (* m+ B)] +## [m- (* m- B)]) +## (let ([d (car q-r)] +## [r (cdr q-r)]) +## (let ([tc1 ((if low-ok? <= <) r m-)] +## [tc2 ((if high-ok? >= >) (+ r m+) s)]) +## (if (not tc1) +## (if (not tc2) +## (cons d (generate r s m+ m- B low-ok? high-ok?)) +## (list (+ d 1))) +## (if (not tc2) +## (list d) +## (if (< (* r 2) s) +## (list d) +## (list (+ d 1)))))))))) + +# now the above is an example of a pointlessly recursive algorithm if +# ever i saw one... + +def generate(r, s, m_plus, m_minus): + rr = [] + while 1: + d, r = divmod(r*10, s) + m_plus *= 10 + m_minus *= 10 + tc1 = r < m_minus + tc2 = (r + m_plus) > s + if tc2: + rr.append(d+1) + else: + rr.append(d) + if tc1 or tc2: + break + return rr + + +## (define scale +## (lambda (r s m+ m- k B low-ok? high-ok? v) +## (let ([est (inexact->exact (ceiling (- (logB B v) 1e-10)))]) +## (if (>= est 0) +## (fixup r (* s (exptt B est)) m+ m- est B low-ok? high-ok? ) +## (let ([scale (exptt B (- est))]) +## (fixup (* r scale) s (* m+ scale) (* m- scale) +## est B low-ok? high-ok? )))))) + +def scale(r, s, m_plus, m_minus, k, v): + est = long(math.ceil(math.log(v, 10) - 1e-10)) + if est >= 0: + return fixup(r, s * 10 ** est, m_plus, m_minus, est) + else: + scale = 10 ** -est + return fixup(r*scale, s, m_plus*scale, m_minus*scale, est) + + +## (define fixup +## (lambda (r s m+ m- k B low-ok? high-ok? ) +## (if ((if high-ok? >= >) (+ r m+) s) ; too low? +## (cons (+ k 1) (generate r (* s B) m+ m- B low-ok? high-ok? )) +## (cons k (generate r s m+ m- B low-ok? high-ok? ))))) + +def fixup(r, s, m_plus, m_minus, k): + if r + m_plus > s: + return generate(r, s*10, m_plus, m_minus), k + 1 + else: + return generate(r, s, m_plus, m_minus), k + + +def float_digits(f): + assert f >= 0 + if f == 0.0: + return ['0'], 1 + m, e = math.frexp(f) + m = long(m*2.0**53) + e -= 53 + ds, k = flonum2digits(f, m, e) + ds = map(str, ds) + return ds, k Modified: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_formatting.py Sat Jul 24 17:43:41 2004 @@ -2,6 +2,11 @@ # There's some insane stuff in here. Blame CPython. Please. +# Known problems: +# (1) rounding isn't always right (see comments in _float_formatting). +# (2) something goes wrong in the f_alt case of %g handling. +# (3) it's really, really slow. + class _Flags(object): def __repr__(self): return "<%s>"%(', '.join([f for f in self.__dict__ @@ -12,12 +17,13 @@ f_alt = 0 f_zero = 0 + def value_next(valueiter): try: return valueiter.next() except StopIteration: - raise TypeError('not enough arguments for format string') - + raise TypeError('not enough arguments for format string') + def peel_num(c, fmtiter, valueiter): if c == '*': @@ -34,6 +40,7 @@ else: return c, 0 + def peel_flags(c, fmtiter): flags = _Flags() while 1: @@ -52,6 +59,7 @@ c = fmtiter.next() return c, flags + def parse_fmt(fmtiter, valueiter, valuedict): """return (char, flags, width, prec, value) partially consumes fmtiter & valueiter""" @@ -93,6 +101,7 @@ value = value_next(valueiter) return (c, flags, width, prec, value) + class Formatter(object): def __init__(self, char, flags, width, prec, value): self.char = char @@ -105,9 +114,10 @@ # negative zeroes? # * mwh giggles, falls over # still, if we can recognize them, here's the place to do it. - if v < 0: + import math + if v < 0 or v == 0 and math.atan2(0, v) != 0: sign = '-' - v = -v + v = -v else: if self.flags.f_sign: sign = '+' @@ -119,11 +129,9 @@ def numeric_postprocess(self, r, sign): assert self.char in 'iduoxXeEfFgG' - padchar = ' ' if self.flags.f_zero: padchar = '0' - if self.width is not None: p = self.width - len(r) - len(sign) if self.flags.f_ljust: @@ -136,16 +144,12 @@ else: r = sign + r return r - def format(self): raise NotImplementedError def std_wp(self, r): - padchar = ' ' - if self.flags.f_zero and self.char in 'iduoxXeEfFgG': - padchar = '0' - + assert self.char not in 'iduoxXeEfFgG' if self.prec is not None: r = r[:self.prec] if self.width is not None: @@ -153,9 +157,10 @@ if self.flags.f_ljust: r = r + ' '*p else: - r = padchar*p + r + r = ' '*p + r return r + def funcFormatter(*funcs): class _F(Formatter): def format(self): @@ -165,6 +170,7 @@ return self.std_wp(r) return _F + def maybe_int(value): try: inter = value.__int__ @@ -172,166 +178,26 @@ raise TypeError, "an integer argument is required" return inter() + def maybe_float(value): try: floater = value.__float__ except AttributeError: - raise TypeError, "float argument is required" + raise TypeError, "a float argument is required" return floater() -import math - -# from the excessive effort department, routines for printing floating -# point numbers from - -# "Printing Floating-Point Numbers Quickly and Accurately" by Burger & -# Dybvig, Proceedings of the SIGPLAN '96 Conference on Programming -# Language Design and Implementation. - -# The paper contains scheme code which has been specialized for IEEE -# doubles and converted into (still somewhat scheme-like) Python by -# Michael Hudson. - -# XXX unfortunately, we need the fixed-format output routines, the source -# for which is not included in the paper... for now, just put up with -# occasionally incorrectly rounded final digits. I'll get to it. - -# XXX should run this at interpreter level, really.... - -## (define flonum->digits -## (lambda (v f e min-e p b B) -## (if (>= e 0) -## (if (not (= f (expt b (- p 1)))) -## (let ([be (expt b e)]) -## (scale (* f be 2) 2 be be 0 B v)) -## (let* ([be (expt b e)] [be1 (* be b)]) -## (scale (* f be1 2) (* b 2) be1 be 0 B v))) -## (if (or (= e min-e) (not (= f (expt b (- p 1))))) -## (scale (* f 2) (* (expt b (- e)) 2) 1 1 0 B v) -## (scale (* f b 2) (* (expt b (- 1 e)) 2) b 1 0 B v))))) - -def flonum2digits(v, f, e, B): - - # sod generality in the extreme: we're working with ieee 754 64 - # bit doubles on any platform I care about. - # this means b == 2, min-e = -1075 (?), p = 53 above - - # in: - # v = f * 2**e - # B is output base - - # out: - # [d0, d1, ..., dn], k - # st 0.[d1][d2]...[dn] * B**k is the "best" representation of v - - if e >= 0: - if not f != 2**52: - be = 2**e - return scale(f*be*2, 2, be, be, 0, B, v) - else: - be = 2**e - be1 = 2*be - return scale(f*be1*2, 4, be1, be, 0, B, v) - else: - if e == -1075 or f != 2**52: - return scale(f*2, 2*2**(-e), 1, 1, 0, B, v) - else: - return scale(f*4, 2*2**(1-e), 2, 1, 0, B, v) - -## (define generate -## (lambda (r s m+ m- B low-ok? high-ok?) -## (let ([q-r (quotient-remainder (* r B) s)] -## [m+ (* m+ B)] -## [m- (* m- B)]) -## (let ([d (car q-r)] -## [r (cdr q-r)]) -## (let ([tc1 ((if low-ok? <= <) r m-)] -## [tc2 ((if high-ok? >= >) (+ r m+) s)]) -## (if (not tc1) -## (if (not tc2) -## (cons d (generate r s m+ m- B low-ok? high-ok?)) -## (list (+ d 1))) -## (if (not tc2) -## (list d) -## (if (< (* r 2) s) -## (list d) -## (list (+ d 1)))))))))) -# now the above is an example of a pointlessly recursive algorithm if -# ever i saw one... +from _float_formatting import float_digits -def generate(r, s, m_plus, m_minus, B): - rr = [] - while 1: - d, r = divmod(r*B, s) - m_plus *= B - m_minus *= B - tc1 = r < m_minus - tc2 = (r + m_plus) > s - if tc2: - rr.append(d+1) - else: - rr.append(d) - if tc1 or tc2: - break - return rr - -## (define scale -## (lambda (r s m+ m- k B low-ok? high-ok? v) -## (let ([est (inexact->exact (ceiling (- (logB B v) 1e-10)))]) -## (if (>= est 0) -## (fixup r (* s (exptt B est)) m+ m- est B low-ok? high-ok? ) -## (let ([scale (exptt B (- est))]) -## (fixup (* r scale) s (* m+ scale) (* m- scale) est B low-ok? high-ok? )))))) - -def scale(r, s, m_plus, m_minus, k, B, v): - est = long(math.ceil(math.log(v, B) - 1e-10)) - if est >= 0: - return fixup(r, s * B ** est, m_plus, m_minus, est, B) - else: - scale = B ** -est - return fixup(r*scale, s, m_plus*scale, m_minus*scale, est, B) - -## (define fixup -## (lambda (r s m+ m- k B low-ok? high-ok? ) -## (if ((if high-ok? >= >) (+ r m+) s) ; too low? -## (cons (+ k 1) (generate r (* s B) m+ m- B low-ok? high-ok? )) -## (cons k (generate r s m+ m- B low-ok? high-ok? ))))) - -def fixup(r, s, m_plus, m_minus, k, B): - if r + m_plus > s: - return generate(r, s*B, m_plus, m_minus, B), k + 1 - else: - return generate(r, s, m_plus, m_minus, B), k - - -def float_digits(f): - assert f >= 0 - if f == 0.0: - return [], 1 - m, e = math.frexp(f) - m = long(m*2.0**53) - e -= 53 - ds, k = flonum2digits(f, m, e, 10) - ds = map(str, ds) - return ds, k - -class floatFFormatter(Formatter): - def format(self): - v = maybe_float(self.value) - if abs(v)/1e25 > 1e25: - return floatGFormatter('g', self.flags, self.width, - self.prec, self.value).format() - v, sign = self.numeric_preprocess(v) - - if self.prec is None: - self.prec = 6 - - # we want self.prec digits after the radix point. +class FloatFormatter(Formatter): + def eDigits(self, ds): + ds = ds[:self.prec + 1] + ['0'] * (self.prec + 1 - len(ds)) + if self.prec > 0 or self.flags.f_alt: + ds[1:1] = ['.'] + return ''.join(ds) - # this is probably more complex than it needs to be: + def fDigits(self, ds, k): p = max(self.prec, 0) - ds, k = float_digits(v) if 0 < k < len(ds): if len(ds) - k < p: ds.extend(['0'] * (p - (len(ds) - k))) @@ -345,94 +211,140 @@ ds[0:0]= ['0', '.'] elif k >= len(ds): ds.extend((k-len(ds))*['0'] + ['.'] + ['0']*p) + return ''.join(ds) - if self.prec <= 0: - del ds[-1] - - return self.numeric_postprocess(''.join(ds), sign) - -class floatEFormatter(Formatter): def format(self): v = maybe_float(self.value) - v, sign = self.numeric_preprocess(v) - if self.prec is None: self.prec = 6 + r = self._format(v) + return self.numeric_postprocess(r, sign) + +class FloatFFormatter(FloatFormatter): + def _format(self, v): + if v/1e25 > 1e25: + return floatGFormatter('g', self.flags, self.width, + self.prec, self.value).format() ds, k = float_digits(v) - ds = ds[:self.prec + 1] + ['0'] * (self.prec + 1 - len(ds)) - ds[1:1] = ['.'] - - r = ''.join(ds) + self.char + "%+03d"%(k-1,) - - return self.numeric_postprocess(r, sign) + digits = self.fDigits(ds, k) + if not self.flags.f_alt: + digits = digits.rstrip('.') + return digits -class floatGFormatter(Formatter): - # the description of %g in the Python documentation lies. - def format(self): - v = maybe_float(self.value) - v, sign = self.numeric_preprocess(v) +class FloatEFormatter(FloatFormatter): + def _format(self, v): + ds, k = float_digits(v) + digits = self.eDigits(ds) + return "%s%c%+03d"%(digits, self.char, k-1) - if self.prec is None: - self.prec = 6 +class FloatGFormatter(FloatFormatter): + # The description of %g in the Python documentation lies + # in a variety of minor ways. + # Gah, this still isn't quite right in the f_alt case. + # (One has to wonder who might care). + def _format(self, v): ds, k = float_digits(v) - ds = ds[:self.prec] # XXX rounding! - - if -4 < k < self.prec: - if 0 < k < len(ds): - ds[k:k] = ['.'] - if k <= 0: - ds[0:0] = ['0', '.'] + ['0']*(-k) - elif k >= len(ds): - ds.extend((k-len(ds))*['0']) - r = ''.join(ds) + if -4 < k <= self.prec: + digits = self.fDigits(ds, k) + if not self.flags.f_alt: + digits = digits.rstrip('0').rstrip('.') + r = digits else: - ds[1:1] = ['.'] - r = ''.join(ds) + self.char + "%+03d"%(k-1,) - - return self.numeric_postprocess(r, sign) + digits = self.eDigits(ds) + if not self.flags.f_alt: + digits = digits.rstrip('0').rstrip('.') + r = "%se%+03d"%(digits, k-1) + return r + class HexFormatter(Formatter): + # NB: this has 2.4 semantics wrt. negative values def format(self): - i = maybe_int(self.value) - r = hex(i) - if not self.flags.f_alt: - r = r[2:] + v, sign = self.numeric_preprocess(maybe_int(self.value)) + r = hex(v)[2:] + if self.prec is not None and len(r) < self.prec: + r = '0'*(self.prec - len(r)) + r + if self.flags.f_alt: + r = '0x' + r if self.char == 'X': r = r.upper() - return self.std_wp(r) + return self.numeric_postprocess(r, sign) + class OctFormatter(Formatter): + # NB: this has 2.4 semantics wrt. negative values def format(self): - i = maybe_int(self.value) - r = oct(i) + v, sign = self.numeric_preprocess(maybe_int(self.value)) + r = oct(v) if not self.flags.f_alt: r = r[1:] - return self.std_wp(r) + if self.prec is not None and len(r) < self.prec: + r = '0'*(self.prec - len(r)) + r + return self.numeric_postprocess(r, sign) + + +class IntFormatter(Formatter): + # NB: this has 2.4 semantics wrt. negative values (for %u) + def format(self): + v, sign = self.numeric_preprocess(maybe_int(self.value)) + r = str(v) + if self.prec is not None and len(r) < self.prec: + r = '0'*(self.prec - len(r)) + r + return self.numeric_postprocess(r, sign) + + +class CharFormatter(Formatter): + def format(self): + if isinstance(self.value, str): + v = self.value + if len(v) != 1: + raise TypeError, "%c requires int or char" + else: + i = maybe_int(self.value) + if not 0 <= i <= 255: + raise OverflowError("OverflowError: unsigned byte " + "integer is greater than maximum") + v = chr(i) + self.prec = None + return self.std_wp(v) + format_registry = { - 's':funcFormatter(str), - 'r':funcFormatter(repr), + 'd':IntFormatter, + 'i':IntFormatter, + 'o':OctFormatter, + 'u':IntFormatter, 'x':HexFormatter, 'X':HexFormatter, - 'o':OctFormatter, - 'd':funcFormatter(maybe_int, str), - 'e':floatEFormatter, - 'E':floatEFormatter, - 'f':floatFFormatter, - 'g':floatGFormatter, + 'e':FloatEFormatter, + 'E':FloatEFormatter, + 'f':FloatFFormatter, + 'F':FloatFFormatter, + 'g':FloatGFormatter, + 'G':FloatGFormatter, + 'c':CharFormatter, + 's':funcFormatter(str), + 'r':funcFormatter(repr), + # this *can* get accessed, by e.g. '%()4%'%{'':1}. + # The usual %% case has to be handled specially as it + # doesn't consume a value. + '%':funcFormatter(lambda x:'%'), } + class FmtIter(object): def __init__(self, fmt): self.fmt = fmt self.i = 0 + def __iter__(self): return self + def next(self): try: c = self.fmt[self.i] @@ -440,6 +352,7 @@ raise StopIteration self.i += 1 return c + def skip_to_fmt(self): i = self.i j = self.fmt.find('%', i) @@ -450,6 +363,7 @@ self.i = j return self.fmt[i:j] + def format(fmt, values, valuedict=None): fmtiter = FmtIter(fmt) valueiter = iter(values) From pedronis at codespeak.net Sat Jul 24 17:54:49 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 17:54:49 +0200 (MEST) Subject: [pypy-svn] r5646 - pypy/trunk/doc/funding Message-ID: <20040724155449.8B6DA5BDEA@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 17:54:48 2004 New Revision: 5646 Modified: pypy/trunk/doc/funding/B6.7.wp04_core.txt pypy/trunk/doc/funding/B6.7.wp05_translation.txt pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt Log: back porting changes as in part_b_2004_07_22_individual.sxw Modified: pypy/trunk/doc/funding/B6.7.wp04_core.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp04_core.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp04_core.txt Sat Jul 24 17:54:48 2004 @@ -12,7 +12,7 @@ .. |p4| replace:: Logilab .. |m4| replace:: 5 .. |p5| replace:: Krekel -.. |m5| replace:: 3 +.. |m5| replace:: 4 .. |p6| replace:: |e| .. |m6| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp05_translation.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp05_translation.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp05_translation.txt Sat Jul 24 17:54:48 2004 @@ -12,7 +12,7 @@ .. |p4| replace:: Tismer .. |m4| replace:: 2 .. |p5| replace:: Krekel -.. |m5| replace:: 1 +.. |m5| replace:: 2 .. |p6| replace:: |e| .. |m6| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt Sat Jul 24 17:54:48 2004 @@ -5,8 +5,8 @@ .. |start| replace:: 9 .. |p1| replace:: USH .. |m1| replace:: 12 -.. |p2| replace:: |e| -.. |m2| replace:: |e| +.. |p2| replace:: Tismer +.. |m2| replace:: 1 .. |p3| replace:: |e| .. |m3| replace:: |e| .. |p4| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt Sat Jul 24 17:54:48 2004 @@ -6,7 +6,7 @@ .. |p1| replace:: Tismer .. |m1| replace:: 9 .. |p2| replace:: Krekel -.. |m2| replace:: 4 +.. |m2| replace:: 6 .. |p3| replace:: USH .. |m3| replace:: 3 .. |p4| replace:: |e| From pedronis at codespeak.net Sat Jul 24 18:01:16 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 18:01:16 +0200 (MEST) Subject: [pypy-svn] r5647 - pypy/trunk/doc/funding Message-ID: <20040724160116.9037D5BFD3@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 18:01:15 2004 New Revision: 5647 Modified: pypy/trunk/doc/funding/B4.resources.txt pypy/trunk/doc/funding/table4.py Log: regenerated B4 table to also reflects part_b_2004_07_22_individual.sxw Modified: pypy/trunk/doc/funding/B4.resources.txt ============================================================================== --- pypy/trunk/doc/funding/B4.resources.txt (original) +++ pypy/trunk/doc/funding/B4.resources.txt Sat Jul 24 18:01:15 2004 @@ -607,14 +607,14 @@ |WP3: Synchronisation | | 3| | | | | | 6| 9| |with Standard Python | | | | | | | | | | +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP4: PyPy Core | 4| | 6| 5| | 3| | 4| 22| +|WP4: PyPy Core | 4| | 6| 5| | 4| | 4| 23| +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP5: PyPy Translation| 2| 8| 15| | | 1| | 2| 28| +|WP5: PyPy Translation| 2| 8| 15| | | 2| | 2| 29| +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP6: Core | | 12| | | | | | | 12| +|WP6: Core | | 12| | | | | | 1| 13| |Optimisations | | | | | | | | | | +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP7: Translator | | 3| | | | 4| | 9| 16| +|WP7: Translator | | 3| | | | 6| | 9| 18| |Optimisations | | | | | | | | | | +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ |WP8: Dynamic | | 6| 17| | | | | 2| 25| @@ -640,7 +640,7 @@ +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ | | | | | | | | | | | +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Total Research and | 23| 35| 48| 32| 12| 20| 12| 23| 205| +|Total Research and | 23| 35| 48| 32| 12| 24| 12| 24| 210| |Innovation | | | | | | | | | | +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ |Management | | | | | | | | | | @@ -650,7 +650,5 @@ +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ | | | | | | | | | | | +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Total | 27| 35| 52| 32| 16| 20| 12| 23| 217| +|Total | 27| 35| 52| 32| 16| 24| 12| 24| 222| +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ - - Modified: pypy/trunk/doc/funding/table4.py ============================================================================== --- pypy/trunk/doc/funding/table4.py (original) +++ pypy/trunk/doc/funding/table4.py Sat Jul 24 18:01:15 2004 @@ -80,13 +80,13 @@ ('WP3: Synchronisation', 'with Standard Python'): { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 6, }, ('WP4: PyPy Core',): - { 'DFKI': 4, 'USH': 0, 'PBF': 0, 'Strakt': 6, 'Logilab': 5, 'CM': 0, 'Krekel': 3, 'Martelli': 0, 'Tismer': 4, }, + { 'DFKI': 4, 'USH': 0, 'PBF': 0, 'Strakt': 6, 'Logilab': 5, 'CM': 0, 'Krekel': 4, 'Martelli': 0, 'Tismer': 4, }, ('WP5: PyPy Translation',): - { 'DFKI': 2, 'USH': 8, 'PBF': 0, 'Strakt': 15, 'Logilab': 0, 'CM': 0, 'Krekel': 1, 'Martelli': 0, 'Tismer': 2, }, + { 'DFKI': 2, 'USH': 8, 'PBF': 0, 'Strakt': 15, 'Logilab': 0, 'CM': 0, 'Krekel': 2, 'Martelli': 0, 'Tismer': 2, }, ('WP6: Core', 'Optimisations'): - { 'DFKI': 0, 'USH': 12, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, + { 'DFKI': 0, 'USH': 12, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 1, }, ('WP7: Translator', 'Optimisations'): - { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 4, 'Martelli': 0, 'Tismer': 9, }, + { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 6, 'Martelli': 0, 'Tismer': 9, }, ('WP8: Dynamic', 'Optimisations'): { 'DFKI': 0, 'USH': 6, 'PBF': 0, 'Strakt': 17, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 2, }, ('WP9: Search and Logic',): From pedronis at codespeak.net Sat Jul 24 18:35:14 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 18:35:14 +0200 (MEST) Subject: [pypy-svn] r5648 - pypy/trunk/doc/funding Message-ID: <20040724163514.AE6255B68E@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 18:35:13 2004 New Revision: 5648 Modified: pypy/trunk/doc/funding/B0.0_preamble.txt pypy/trunk/doc/funding/B6.7.wp02_maintenance.txt pypy/trunk/doc/funding/B6.7.wp03_synchronisation.txt pypy/trunk/doc/funding/B6.7.wp04_core.txt pypy/trunk/doc/funding/B6.7.wp05_translation.txt pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt pypy/trunk/doc/funding/B6.7.wp08_dynamic_optimisation.txt pypy/trunk/doc/funding/B6.7.wp13_integration_config.txt pypy/trunk/doc/funding/B6.7.wp14_documentation.txt pypy/trunk/doc/funding/table4.py Log: port back changes that gave part_b_2004_07_22.sxw (i.e parking MMs to DFKI). Modified: pypy/trunk/doc/funding/B0.0_preamble.txt ============================================================================== --- pypy/trunk/doc/funding/B0.0_preamble.txt (original) +++ pypy/trunk/doc/funding/B0.0_preamble.txt Sat Jul 24 18:35:13 2004 @@ -70,12 +70,6 @@ 6 Logilab Logilab ---------------- --------------------------------------------- ----------------------- 7 ChangeMaker ChangeMaker ----------------- --------------------------------------------- ----------------------- -8 Krekel Krekel ----------------- --------------------------------------------- ----------------------- -9 Martelli Martelli ----------------- --------------------------------------------- ----------------------- -10 Tismer Tismer ================ ============================================= ======================= :DELETE:BEGIN Modified: pypy/trunk/doc/funding/B6.7.wp02_maintenance.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp02_maintenance.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp02_maintenance.txt Sat Jul 24 18:35:13 2004 @@ -3,7 +3,7 @@ .. |title| replace:: Infrastructure and Tools .. |wp| replace:: WP02 .. |start| replace:: 0 -.. |p1| replace:: Krekel +.. |p1| replace:: DFKI .. |m1| replace:: 8 .. |p2| replace:: |e| .. |m2| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp03_synchronisation.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp03_synchronisation.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp03_synchronisation.txt Sat Jul 24 18:35:13 2004 @@ -5,7 +5,7 @@ .. |start| replace:: 0 .. |p1| replace:: USH .. |m1| replace:: 3 -.. |p2| replace:: Tismer +.. |p2| replace:: DFKI .. |m2| replace:: 6 .. |p3| replace:: |e| .. |m3| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp04_core.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp04_core.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp04_core.txt Sat Jul 24 18:35:13 2004 @@ -5,14 +5,14 @@ .. |start| replace:: 0 .. |p1| replace:: Strakt .. |m1| replace:: 6 -.. |p2| replace:: Tismer -.. |m2| replace:: 4 -.. |p3| replace:: DFKI -.. |m3| replace:: 4 -.. |p4| replace:: Logilab -.. |m4| replace:: 5 -.. |p5| replace:: Krekel -.. |m5| replace:: 4 +.. |p2| replace:: DFKI +.. |m2| replace:: 12 +.. |p3| replace:: Logilab +.. |m3| replace:: 5 +.. |p4| replace:: |e| +.. |m4| replace:: |e| +.. |p5| replace:: |e| +.. |m5| replace:: |e| .. |p6| replace:: |e| .. |m6| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp05_translation.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp05_translation.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp05_translation.txt Sat Jul 24 18:35:13 2004 @@ -6,13 +6,13 @@ .. |p1| replace:: STRAKT .. |m1| replace:: 15 .. |p2| replace:: DFKI -.. |m2| replace:: 2 +.. |m2| replace:: 6 .. |p3| replace:: USH .. |m3| replace:: 8 -.. |p4| replace:: Tismer -.. |m4| replace:: 2 -.. |p5| replace:: Krekel -.. |m5| replace:: 2 +.. |p4| replace:: |e| +.. |m4| replace:: |e| +.. |p5| replace:: |e| +.. |m5| replace:: |e| .. |p6| replace:: |e| .. |m6| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp06_core_optimisations.txt Sat Jul 24 18:35:13 2004 @@ -5,7 +5,7 @@ .. |start| replace:: 9 .. |p1| replace:: USH .. |m1| replace:: 12 -.. |p2| replace:: Tismer +.. |p2| replace:: DFKI .. |m2| replace:: 1 .. |p3| replace:: |e| .. |m3| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp07_translator_optimisations.txt Sat Jul 24 18:35:13 2004 @@ -3,12 +3,12 @@ .. |title| replace:: Translator Optimisations .. |wp| replace:: WP07 .. |start| replace:: 9 -.. |p1| replace:: Tismer -.. |m1| replace:: 9 -.. |p2| replace:: Krekel -.. |m2| replace:: 6 -.. |p3| replace:: USH -.. |m3| replace:: 3 +.. |p1| replace:: DFKI +.. |m1| replace:: 15 +.. |p2| replace:: USH +.. |m2| replace:: 3 +.. |p3| replace:: |e| +.. |m3| replace:: |e| .. |p4| replace:: |e| .. |m4| replace:: |e| .. |p5| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp08_dynamic_optimisation.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp08_dynamic_optimisation.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp08_dynamic_optimisation.txt Sat Jul 24 18:35:13 2004 @@ -5,10 +5,10 @@ .. |start| replace:: 9 .. |p1| replace:: STRAKT .. |m1| replace:: 17 -.. |p2| replace:: Tismer -.. |m2| replace:: 2 -.. |p3| replace:: USH -.. |m3| replace:: 6 +.. |p2| replace:: USH +.. |m2| replace:: 6 +.. |p3| replace:: DFKI +.. |m3| replace:: 2 .. |p4| replace:: |e| .. |m4| replace:: |e| .. |p5| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp13_integration_config.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp13_integration_config.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp13_integration_config.txt Sat Jul 24 18:35:13 2004 @@ -3,12 +3,12 @@ .. |title| replace:: Integration and Configuration .. |wp| replace:: WP13 .. |start| replace:: 18 -.. |p1| replace:: Krekel -.. |m1| replace:: 4 +.. |p1| replace:: DFKI +.. |m1| replace:: 8 .. |p2| replace:: Logilab .. |m2| replace:: 4 -.. |p3| replace:: DFKI -.. |m3| replace:: 4 +.. |p3| replace:: |e| +.. |m3| replace:: |e| .. |p4| replace:: |e| .. |m4| replace:: |e| .. |p5| replace:: |e| Modified: pypy/trunk/doc/funding/B6.7.wp14_documentation.txt ============================================================================== --- pypy/trunk/doc/funding/B6.7.wp14_documentation.txt (original) +++ pypy/trunk/doc/funding/B6.7.wp14_documentation.txt Sat Jul 24 18:35:13 2004 @@ -5,7 +5,7 @@ .. |start| replace:: 0 .. |p1| replace:: CM .. |m1| replace:: 11 -.. |p2| replace:: Martelli +.. |p2| replace:: DFKI .. |m2| replace:: 12 .. |p3| replace:: |e| .. |m3| replace:: |e| Modified: pypy/trunk/doc/funding/table4.py ============================================================================== --- pypy/trunk/doc/funding/table4.py (original) +++ pypy/trunk/doc/funding/table4.py Sat Jul 24 18:35:13 2004 @@ -1,6 +1,8 @@ cols =[21, 14, 14, #14, - 14, 14, 14, 14, 14, 13, 14] + 14, 14, 14, + #14, 14, 13, + 14] col_titles =['', 'DFKI', @@ -9,9 +11,9 @@ 'Strakt', 'Logilab', 'CM', - 'Krekel', - 'Martelli', - 'Tismer', + #'Krekel', + #'Martelli', + #'Tismer', 'Total'] row_titles = [ @@ -76,19 +78,19 @@ ('Research and', 'Innovation'): None, ('WP2: Infrastructure', 'and Tools'): - { 'DFKI': 0, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 8, 'Martelli': 0, 'Tismer': 0, }, + { 'DFKI': 8, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP3: Synchronisation', 'with Standard Python'): - { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 6, }, + { 'DFKI': 6, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP4: PyPy Core',): - { 'DFKI': 4, 'USH': 0, 'PBF': 0, 'Strakt': 6, 'Logilab': 5, 'CM': 0, 'Krekel': 4, 'Martelli': 0, 'Tismer': 4, }, + { 'DFKI': 12, 'USH': 0, 'PBF': 0, 'Strakt': 6, 'Logilab': 5, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP5: PyPy Translation',): - { 'DFKI': 2, 'USH': 8, 'PBF': 0, 'Strakt': 15, 'Logilab': 0, 'CM': 0, 'Krekel': 2, 'Martelli': 0, 'Tismer': 2, }, + { 'DFKI': 6, 'USH': 8, 'PBF': 0, 'Strakt': 15, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP6: Core', 'Optimisations'): - { 'DFKI': 0, 'USH': 12, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 1, }, + { 'DFKI': 1, 'USH': 12, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP7: Translator', 'Optimisations'): - { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 6, 'Martelli': 0, 'Tismer': 9, }, + { 'DFKI': 15, 'USH': 3, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP8: Dynamic', 'Optimisations'): - { 'DFKI': 0, 'USH': 6, 'PBF': 0, 'Strakt': 17, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 2, }, + { 'DFKI': 2, 'USH': 6, 'PBF': 0, 'Strakt': 17, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP9: Search and Logic',): { 'DFKI': 10, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 9, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP10: Aspects and', 'Contracts'): @@ -98,9 +100,9 @@ ('WP12: Security,', 'Distribution and', 'Persistence'): { 'DFKI': 0, 'USH': 3, 'PBF': 0, 'Strakt': 10, 'Logilab': 0, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP13: Integration and', 'Configuration'): - { 'DFKI': 4, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 4, 'CM': 0, 'Krekel': 4, 'Martelli': 0, 'Tismer': 0, }, + { 'DFKI': 8, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 4, 'CM': 0, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('WP14: Documentaion', 'and Dissemination'): - { 'DFKI': 0, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 11, 'Krekel': 0, 'Martelli': 12, 'Tismer': 0, }, + { 'DFKI': 12, 'USH': 0, 'PBF': 0, 'Strakt': 0, 'Logilab': 0, 'CM': 11, 'Krekel': 0, 'Martelli': 0, 'Tismer': 0, }, ('Total Research and', 'Innovation'): (), ('Management',): From mwh at codespeak.net Sat Jul 24 18:39:02 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 24 Jul 2004 18:39:02 +0200 (MEST) Subject: [pypy-svn] r5649 - pypy/trunk/src/pypy Message-ID: <20040724163902.506395BFE4@thoth.codespeak.net> Author: mwh Date: Sat Jul 24 18:39:01 2004 New Revision: 5649 Modified: pypy/trunk/src/pypy/TODO Log: Random updates. In my working tree I've commented out the code that prints interpreter- level tracebacks and have yet to miss them. Should I check this in? Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Sat Jul 24 18:39:01 2004 @@ -32,8 +32,7 @@ * find a way via hacking or elegance to run CPython's unit tests against the StdObjSpace. -* String formatting still needs work. Mostly done, but surely missing - pieces around the edges & it's agonizingly slow. +* String formatting is agonizingly slow. * Provide an importer that can import packages. (we have a limited __import__ builtin defined) <---- done now? @@ -68,11 +67,17 @@ Tools ===== -* add web server thread (!) that allows inspection of e.g. app-level - tracebacks (and stop clogging the user's terminal with them). - --> there is some preliminary working code in tool/tb_server +* add web server thread (!) that allows inspection of e.g. + interpreter-level tracebacks (and stop clogging the user's terminal + with them). --> there is some preliminary working code in + tool/tb_server + +* Interpreter level tracebacks are spectacular in their uselessness, + especially since the advent of descroperation. It should be + possible to construct something like an app-level traceback even + when there's no OperationError. * improve traceobjectspace! currently it only catches calls from outside the space into the space but not the ones where space operations involve calling more space - operations (the latter are not traced)! + operations (the latter are not traced)! (fixed?) From pedronis at codespeak.net Sat Jul 24 18:39:09 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 18:39:09 +0200 (MEST) Subject: [pypy-svn] r5650 - pypy/trunk/doc/funding Message-ID: <20040724163909.A6CFA5C17E@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 18:39:09 2004 New Revision: 5650 Modified: pypy/trunk/doc/funding/B4.resources.txt Log: generate B4 table matching part_b_2004_07_22.sxw Modified: pypy/trunk/doc/funding/B4.resources.txt ============================================================================== --- pypy/trunk/doc/funding/B4.resources.txt (original) +++ pypy/trunk/doc/funding/B4.resources.txt Sat Jul 24 18:39:09 2004 @@ -595,60 +595,61 @@ Full duration of project: 24 months -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -| |DFKI |USH |Strakt |Logilab |CM |Krekel |Martelli |Tismer |Total | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Research and | | | | | | | | | | -|Innovation | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP2: Infrastructure | | | | | | 8| | | 8| -|and Tools | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP3: Synchronisation | | 3| | | | | | 6| 9| -|with Standard Python | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP4: PyPy Core | 4| | 6| 5| | 4| | 4| 23| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP5: PyPy Translation| 2| 8| 15| | | 2| | 2| 29| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP6: Core | | 12| | | | | | 1| 13| -|Optimisations | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP7: Translator | | 3| | | | 6| | 9| 18| -|Optimisations | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP8: Dynamic | | 6| 17| | | | | 2| 25| -|Optimisations | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP9: Search and Logic| 10| | | 9| | | | | 19| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP10: Aspects and | 3| | | 9| | | | | 12| -|Contracts | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP11: Specialised | | | | 5| 1| | | | 6| -|Hardware | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP12: Security, | | 3| 10| | | | | | 13| -|Distribution and | | | | | | | | | | -|Persistence | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP13: Integration and| 4| | | 4| | 4| | | 12| -|Configuration | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP14: Documentaion | | | | | 11| | 12| | 23| -|and Dissemination | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -| | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Total Research and | 23| 35| 48| 32| 12| 24| 12| 24| 210| -|Innovation | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Management | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|WP1: Coordination and| 4| | 4| | 4| | | | 12| -|Management | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -| | | | | | | | | | | -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ -|Total | 27| 35| 52| 32| 16| 24| 12| 24| 222| -+---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+-------------+--------------+ ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +| |DFKI |USH |Strakt |Logilab |CM |Total | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|Research and | | | | | | | +|Innovation | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP2: Infrastructure | 8| | | | | 8| +|and Tools | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP3: Synchronisation | 6| 3| | | | 9| +|with Standard Python | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP4: PyPy Core | 12| | 6| 5| | 23| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP5: PyPy Translation| 6| 8| 15| | | 29| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP6: Core | 1| 12| | | | 13| +|Optimisations | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP7: Translator | 15| 3| | | | 18| +|Optimisations | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP8: Dynamic | 2| 6| 17| | | 25| +|Optimisations | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP9: Search and Logic| 10| | | 9| | 19| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP10: Aspects and | 3| | | 9| | 12| +|Contracts | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP11: Specialised | | | | 5| 1| 6| +|Hardware | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP12: Security, | | 3| 10| | | 13| +|Distribution and | | | | | | | +|Persistence | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP13: Integration and| 8| | | 4| | 12| +|Configuration | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP14: Documentaion | 12| | | | 11| 23| +|and Dissemination | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +| | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|Total Research and | 83| 35| 48| 32| 12| 210| +|Innovation | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|Management | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|WP1: Coordination and| 4| | 4| | 4| 12| +|Management | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +| | | | | | | | ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ +|Total | 87| 35| 52| 32| 16| 222| ++---------------------+--------------+--------------+--------------+--------------+--------------+--------------+ + From mwh at codespeak.net Sat Jul 24 18:39:59 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 24 Jul 2004 18:39:59 +0200 (MEST) Subject: [pypy-svn] r5651 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040724163959.EFCA25C185@thoth.codespeak.net> Author: mwh Date: Sat Jul 24 18:39:58 2004 New Revision: 5651 Modified: pypy/trunk/src/pypy/objspace/std/floatobject.py Log: implement str/repr for real. Modified: pypy/trunk/src/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/floatobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/floatobject.py Sat Jul 24 18:39:58 2004 @@ -1,4 +1,5 @@ from pypy.objspace.std.objspace import * +from pypy.interpreter import gateway from pypy.objspace.std.noneobject import W_NoneObject ############################################################## @@ -45,15 +46,21 @@ def unwrap__Float(space, w_float): return w_float.floatval -def repr__Float(space, w_float): - ## %reimplement% - # uses CPython "repr" builtin function - return space.wrap(repr(w_float.floatval)) +def app_repr__Float(f): + r = "%.17g"%f + for c in r: + if c not in '-0123456789': + return r + else: + return r + '.0' -def str__Float(space, w_float): - ## %reimplement% - # uses CPython "str" builtin function - return space.wrap(str(w_float.floatval)) +def app_str__Float(f): + r = "%.12g"%f + for c in r: + if c not in '-0123456789': + return r + else: + return r + '.0' def lt__Float_Float(space, w_float1, w_float2): i = w_float1.floatval @@ -256,5 +263,5 @@ StdObjSpace.coerce.register(float_coerce, W_FloatObject) """ - +gateway.importall(globals()) register_all(vars()) From pedronis at codespeak.net Sat Jul 24 18:45:10 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 24 Jul 2004 18:45:10 +0200 (MEST) Subject: [pypy-svn] r5652 - pypy/trunk/doc/funding Message-ID: <20040724164510.DC3FC5BFD7@thoth.codespeak.net> Author: pedronis Date: Sat Jul 24 18:45:10 2004 New Revision: 5652 Modified: pypy/trunk/doc/funding/B6.5_workpackage_list.txt Log: substituted also here virtually in wp list, lead contractor Krekel/Tismer with DFKI Modified: pypy/trunk/doc/funding/B6.5_workpackage_list.txt ============================================================================== --- pypy/trunk/doc/funding/B6.5_workpackage_list.txt (original) +++ pypy/trunk/doc/funding/B6.5_workpackage_list.txt Sat Jul 24 18:45:10 2004 @@ -16,7 +16,7 @@ ===== ==================================================== ===== ==== ==== ==== ==== ======== WP01_ Coordination and Management 1 12 0 24 DFKI ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- -WP02_ Infrastructure and Tools 8 8 0 24 Krekel +WP02_ Infrastructure and Tools 1 8 0 24 Krekel ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- WP03_ Synchronisation with Standard Python 2 9 0 24 USH ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- @@ -26,7 +26,7 @@ ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- WP06_ Core Optimisations 2 12 9 24 USH ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- -WP07_ Translator Optimisations 10 16 9 18 Tismer +WP07_ Translator Optimisations 1 16 9 18 Tismer ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- WP08_ Dynamic Optimisations 5 25 9 18 Strakt ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- @@ -38,7 +38,7 @@ ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- WP12_ Implement Security, Distribution and Persistence 5 13 18 24 Strakt ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- -WP13_ Integration and Configuration 8 12 18 24 Krekel +WP13_ Integration and Configuration 1 12 18 24 Krekel ----- ---------------------------------------------------- ----- ---- ---- ---- ---- -------- WP14_ Project Documentation and Dissemination 7 23 0 24 ChangeMaker ===== ==================================================== ===== ==== ==== ==== ==== ======== From pedronis at codespeak.net Sun Jul 25 14:10:20 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 25 Jul 2004 14:10:20 +0200 (MEST) Subject: [pypy-svn] r5668 - pypy/trunk/doc/funding Message-ID: <20040725121020.B721E5AAFA@thoth.codespeak.net> Author: pedronis Date: Sun Jul 25 14:10:19 2004 New Revision: 5668 Added: pypy/trunk/doc/funding/project_gantt_parking.png (contents, props changed) Log: my not too subtle attempt at this. Added: pypy/trunk/doc/funding/project_gantt_parking.png ============================================================================== Binary file. No diff available. From rxe at codespeak.net Sun Jul 25 22:56:24 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 25 Jul 2004 22:56:24 +0200 (MEST) Subject: [pypy-svn] r5669 - in pypy/trunk/src/pypy: objspace objspace/test tool Message-ID: <20040725205624.36F2E5AAFF@thoth.codespeak.net> Author: rxe Date: Sun Jul 25 22:56:23 2004 New Revision: 5669 Modified: pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py pypy/trunk/src/pypy/objspace/trace.py pypy/trunk/src/pypy/tool/traceinteractive.py pypy/trunk/src/pypy/tool/traceop.py Log: Various refactors and fixes. Completer class was completely broken in traceinteractive.py. printer in traceop.py broken up into a class. Stole yet more code from interpreter/interactive.py :-) TraceObjectSpace can wrap any arbitrary object space by extending its class and then can return to its original form by calling reset_trace(). To see in action : $ python tool/traceinteractive.py -S and set __pytrace__ to in int > 0. The higher the value, the more tracing it will do. Modified: pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py (original) +++ pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py Sun Jul 25 22:56:23 2004 @@ -5,19 +5,16 @@ from pypy.tool import pydis class Test_TraceObjSpace(testit.IntTestCase): - tspace = None - + def setUp(self): - # XXX hack so we only have one trace space - if Test_TraceObjSpace.tspace is None: - newspace = testit.objspace().__class__() - Test_TraceObjSpace.tspace = trace.create_trace_space(newspace) + self.space = testit.objspace() + trace.create_trace_space(self.space) def tearDown(self): - pass + self.space.reset_trace() def perform_trace(self, app_func): - tspace = self.tspace + tspace = self.space func_gw = app2interp(app_func) func = func_gw.get_function(tspace) tspace.settrace() @@ -26,7 +23,7 @@ return res def test_traceobjspace_basic(self): - tspace = self.tspace + tspace = self.space self.assert_(tspace.is_true(tspace.w_builtins)) #for name, value in vars(self.space).items(): # if not name.startswith('_'): @@ -65,7 +62,7 @@ 1 + 1 res = self.perform_trace(app_f) disresult = pydis.pydis(app_f) - uw = self.tspace.unwrap + uw = self.space.unwrap ops = res.getoperations() op_start = self.get_operation(ops, trace.CallBegin, "add") args = [uw(x) for x in op_start.callinfo.args] Modified: pypy/trunk/src/pypy/objspace/trace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trace.py (original) +++ pypy/trunk/src/pypy/objspace/trace.py Sun Jul 25 22:56:23 2004 @@ -28,6 +28,14 @@ def __init__(self, frame): self.frame = frame +class CallInfo(object): + """ encapsulates a function call with its arguments. """ + def __init__(self, name, func, args, kwargs): + self.name = name + self.func = func + self.args = args + self.kwargs = kwargs + class CallBegin(object): def __init__(self, callinfo): self.callinfo = callinfo @@ -105,19 +113,6 @@ """ called just before execution of a bytecode. """ self.__result.append(ExecBytecode(frame)) - #def exception_trace(self, operror): - # "called if the current frame raises an operation error. " - # print "exception trace", operror - # return self.__ec.exception_trace(operror) - -class CallInfo(object): - """ encapsulates a function call with its arguments. """ - def __init__(self, name, func, args, kwargs): - self.name = name - self.func = func - self.args = args - self.kwargs = kwargs - class CallableTracer(object): def __init__(self, result, name, func): self.__result = result @@ -164,7 +159,11 @@ def create_trace_space(space = None, operations = None): """ Will create a trace object space if no space supplied. Otherwise - the object.""" + will turn the supplied into a tracable space by extending its class.""" + + # Don't trace an already tracable space + if hasattr(space, "__pypytrace___"): + return space if space is None: # make up a TrivialObjSpace by default @@ -175,29 +174,42 @@ if operations is None: operations = get_operations() - class TraceObjSpace(space.__class__): + class Trace(space.__class__): + def __getattribute__(self, name): - obj = super(TraceObjSpace, self).__getattribute__(name) - if callable(obj) and name in operations: - return CallableTracer(self.__result, name, obj) + obj = super(Trace, self).__getattribute__(name) + if name in operations: + assert callable(obj) + obj = CallableTracer(self._result, name, obj) return obj + def __pypytrace___(self): + pass + def settrace(self): - self.__result = TraceResult(self) + self._result = TraceResult(self) def getresult(self): - return self.__result - + return self._result + def getexecutioncontext(self): - ec = super(TraceObjSpace, self).getexecutioncontext() + ec = super(Trace, self).getexecutioncontext() assert not isinstance(ec, ExecutionContextTracer) - return ExecutionContextTracer(self.__result, ec) - space.__class__ = TraceObjSpace + return ExecutionContextTracer(self._result, ec) + + def reset_trace(self): + """ Returns the class to it's original form. """ + space.__class__ = space.__oldclass___ + del space.__oldclass___ + + if hasattr(self, "_result"): + del self._result + + trace_clz = type("Trace" + space.__class__.__name__, (Trace,), {}) + space.__oldclass___, space.__class__ = space.__class__, trace_clz space.settrace() return space -TraceObjSpace = Space = create_trace_space - # ______________________________________________________________________ # End of trace.py Modified: pypy/trunk/src/pypy/tool/traceinteractive.py ============================================================================== --- pypy/trunk/src/pypy/tool/traceinteractive.py (original) +++ pypy/trunk/src/pypy/tool/traceinteractive.py Sun Jul 25 22:56:23 2004 @@ -1,4 +1,5 @@ # Standard imports +import re import sys import code import keyword @@ -11,93 +12,158 @@ except: have_readline = False - + + # PyPy imports import autopath from pypy.tool import pydis -from pypy.tool.traceop import print_result +from pypy.tool.traceop import ResultPrinter from pypy.interpreter import executioncontext, pyframe, baseobjspace from pypy.interpreter.baseobjspace import ObjSpace from pypy.objspace import trace -if have_readline: +class Completer: + """ Stolen mostly from CPython's rlcompleter.py """ + def __init__(self, space): + self.space = space + + def complete(self, text, state): + if state == 0: + if "." in text: + self.matches = self.attr_matches(text) + else: + self.matches = self.global_matches(text) + try: + return self.matches[state] - class Completer: - def __init__(self, space): - self.space = space - - def complete(self, text, state): - - if state == 0: - if "." in text: - self.matches = self.attr_matches(text) - else: - self.matches = self.global_matches(text) - try: - return self.matches[state] + except IndexError: + return None - except IndexError: - return None + def global_matches(self, text): - def global_matches(self, text): - - import __builtin__ + w_res = self.space.call_method(self.space.w_globals, "keys") + namespace_keys = self.space.unwrap(w_res) - w_res = self.space.call_method(self.space.w_globals, "keys") - namespace_keys = self.space.unwrap(w_res) + w_res = self.space.call_method(self.space.w_builtins, "keys") + builtin_keys = self.space.unwrap(w_res) - matches = [] - n = len(text) - - for l in [namespace_keys, __builtin__.__dict__.keys(), keyword.kwlist]: - for word in l: - if word[:n] == text and word != "__builtins__": - matches.append(word) - - return matches + matches = [] + n = len(text) - def attr_matches(self, text): - import re - m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) - if not m: - return + for l in [namespace_keys, builtin_keys, keyword.kwlist]: + for word in l: + if word[:n] == text and word != "__builtins__": + matches.append(word) - expr, attr = m.group(1, 3) - s = self.space - w_obj = s.getitem(s.w_globals, s.wrap(expr)) - w_func = s.getitem(s.w_builtins, s.wrap("dir")) - w_res = s.call_function(w_func, w_obj) - words = s.unwrap(w_res) - matches = [] - n = len(attr) - for word in words: + return matches - if word[:n] == attr and word != "__builtins__": - matches.append("%s.%s" % (expr, word)) + def attr_matches(self, text): + m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) + if not m: + return + + expr, attr = m.group(1, 3) + s = self.space + w_obj = s.eval(expr, s.w_globals, s.w_globals) + words = self.get_words(w_obj) + + w_clz = s.getattr(w_obj, s.wrap("__class__")) + words += self.get_class_members(w_clz) + + matches = [] + n = len(attr) + for word in words: + if word[:n] == attr and word != "__builtins__": + matches.append("%s.%s" % (expr, word)) + + return matches + + def get_words(self, w_clz): + s = self.space + w_dir_func = s.getitem(s.w_builtins, s.wrap("dir")) + w_res = s.call_function(w_dir_func, w_clz) + return s.unwrap(w_res) + + def get_class_members(self, w_clz): + s = self.space + words = self.get_words(w_clz) + try: + w_bases = s.getattr(w_clz, s.wrap("__bases__")) + bases_w = s.unpacktuple(w_bases) - return matches + except OperationError: + return words + + for w_clz in bases_w: + words += self.get_class_members(w_clz) + + return words class TraceConsole(code.InteractiveConsole): def __init__(self, space): code.InteractiveConsole.__init__(self) - s = self.space = trace.create_trace_space(space) - s.setitem(s.w_globals, s.wrap("__pytrace__"), s.w_True) - self.objspacename = space.__class__.__bases__[0].__name__ - + s = self.space = space + s.setitem(s.w_globals, s.wrap("__pytrace__"), s.wrap(0)) + # Trace is binary (on or off), but we have different print levels + # for tracelevel > 0 + self.tracelevel = 0 + self.resprinter = ResultPrinter() + def interact(self, banner=None): if banner is None: - banner = "PyPy in TraceObjSpace(%s) on top of %s\n%s" % ( - self.objspacename, sys.version.split()[0], - " [Use __pytrace__ flag to turn off tracing]" ) + banner = self.get_banner() code.InteractiveConsole.interact(self, banner) + def get_banner(self): + banner = "PyPy in %s on top of CPython %s\n%s" % ( + space.__class__.__name__, sys.version.split()[0], + " [Use __pytrace__ to set trace level (zero is default and does no tracing)]" ) + return banner + def raw_input(self, prompt=""): # add a character to the PyPy prompt so that you know where you # are when you debug it with "python -i py.py" - return code.InteractiveConsole.raw_input(self, prompt[0] + prompt) + try: + return code.InteractiveConsole.raw_input(self, prompt[0] + prompt) + + except KeyboardInterrupt: + s = self.space + # fires into an interpreter-level console + print + banner = ("Python %s on %s\n" % (sys.version, sys.platform) + + "*** Entering interpreter-level console ***") + local = self.__dict__.copy() + for w_name in s.unpackiterable(s.w_globals): + local['w_' + s.unwrap(w_name)] = ( + s.getitem(s.w_globals, w_name)) + code.interact(banner=banner, local=local) + # copy back 'w_' names + for name in local: + if name.startswith('w_'): + s.setitem(s.w_globals, + s.wrap(name[2:]), + local[name]) + print '*** Leaving interpreter-level console ***' + raise + + def set_tracelevel(self, tracelevel): + # Disable tracing altogether? + if self.tracelevel > 0 and tracelevel == 0: + self.space.reset_trace() + print self.get_banner() + + if self.tracelevel == 0 and tracelevel > 0: + trace.create_trace_space(self.space) + print self.get_banner() + + self.tracelevel = tracelevel + + # XXX Do something better than this - I'm not really sure what is useful + # and what is (rxe) + self.resprinter.operations_level = tracelevel def runcode(self, code): # 'code' is a CPython code object @@ -105,23 +171,33 @@ pycode = PyCode()._from_code(code) s = self.space - trace_flag = s.is_true(s.getitem(s.w_globals, - s.wrap("__pytrace__"))) - if trace_flag: - s.settrace() try: + if self.tracelevel: + s.settrace() + pycode.exec_code(s, s.w_globals, s.w_globals) - if trace_flag: + + res = None + if self.tracelevel: res = s.getresult() + + # Did we modify __pytrace__ + tracelevel = s.unwrap(s.getitem(s.w_globals, + s.wrap("__pytrace__"))) + + if tracelevel != self.tracelevel: + self.set_tracelevel(tracelevel) + + if res is not None and self.tracelevel: s.settrace() - print_result(s, res) + self.resprinter.print_result(s, res) except baseobjspace.OperationError, operationerr: - if trace_flag: + if self.tracelevel: res = s.getresult() s.settrace() - print_result(s, res) + self.resprinter.print_result(s, res) # XXX insert exception info into the application-level sys.last_xxx print @@ -172,8 +248,9 @@ atexit.register(readline.write_history_file) console.interact(banner) - + if __name__ == '__main__': + from pypy.tool import option args = option.process_options(option.get_standard_options(), option.Options) @@ -181,4 +258,3 @@ # Create objspace... space = option.objspace() trace_interactive(space) - Modified: pypy/trunk/src/pypy/tool/traceop.py ============================================================================== --- pypy/trunk/src/pypy/tool/traceop.py (original) +++ pypy/trunk/src/pypy/tool/traceop.py Sun Jul 25 22:56:23 2004 @@ -16,86 +16,195 @@ disresult = _cache[obj] = pydis.pydis(obj) return disresult -def line_begin(indent): - if indent: - return (" " * indent) + "|-" - else: - return "" - -def print_result(space, traceres, operations_level = 1000): - # XXX Refactor this - make more configurable. - indentor = ' ' - lastframe = None - frame_count = 0 - indent = "" - skip_frame_count = None - stack_info = [] - for event in traceres.getevents(): +class Stack(list): + push = list.append + + def pop(self): + return super(Stack, self).pop(-1) + + def top(self): + try: + return self[-1] + except IndexError: + return None + +class ResultPrinter: + + def __init__(self, + skip_all_below_op = True, + operations_level = 2, + indentor = ' ', + skip_bytecodes = ["PRINT_EXPR", "PRINT_ITEM", "PRINT_NEWLINE"], + ): - if isinstance(event, trace.EnterFrame): - if not skip_frame_count: - print line_begin(frame_count) + ("<<<<>>>>>>" % (event.frame.code.co_filename, event.frame.code.co_firstlineno)) - - lastframe = event.frame - frame_count += 1 - - elif isinstance(event, trace.LeaveFrame): - frame_count -= 1 - - # No more bytecodes to skip at this level - if frame_count < skip_frame_count: - skip_frame_count = 0 - - if not skip_frame_count: - print line_begin(frame_count) + ("<<<<>>>>>>" % lastframe.code.co_filename) - elif isinstance(event, trace.ExecBytecode): - - if frame_count == skip_frame_count: - skip_frame_count = 0 - - disresult = getdisresult(event.frame) - bytecode = disresult.getbytecode(event.index) - - if not skip_frame_count: - print line_begin(frame_count), "%2d" % event.index, " ", bytecode - lastframe = event.frame - - if bytecode.name in ["PRINT_EXPR", "PRINT_ITEM", "PRINT_NEWLINE"]: - print line_begin(frame_count + 1), "..." - skip_frame_count = frame_count - - elif isinstance(event, trace.CallBegin): - info = event.callinfo - if not skip_frame_count: - stack_info.append(info) - if len(stack_info) <= operations_level: - print line_begin(frame_count), " " * 17 + ">> ", info.name, repr_args(space, lastframe, info.args) - frame_count += 1 - - elif isinstance(event, trace.CallFinished): - info = event.callinfo - if not skip_frame_count: - assert stack_info.pop(-1) == event.callinfo - frame_count -= 1 - if len(stack_info) < operations_level: - print line_begin(frame_count), " " * 20, info.name, "=: ", repr_value(space, event.res) + # Configurable stuff + self.indentor = indentor + self.skip_bytecodes = skip_bytecodes + self.operations_level = operations_level + self.skip_all_below_op = skip_all_below_op - elif isinstance(event, trace.CallException): - info = event.callinfo - if not skip_frame_count: - assert stack_info.pop(-1) == event.callinfo - frame_count -= 1 - if len(stack_info) < operations_level: - print line_begin(frame_count), " " * 17 + "x= ", info.name, event.ex - else: - pass - + self.reset() + + def reset(self): + # State stuff + self.ops = Stack() + self.frames = Stack() + self.frame_count = 0 + self.skip_frame_count = None + + def print_line(self, line, additional_indent = 0): + if self.skip_frame_count is not None: + return + + if self.frame_count: + indent = self.frame_count + additional_indent - 1 + assert (indent >= 0) + line = (self.indentor * indent) + "|-" + line + + print line + + def print_line_operations(self, line, additional_indent = 0): + # Don't allow operations to be exposed if operations level is up + # but do allow operations to be printed + if len(self.ops) > self.operations_level: + return + + self.print_line(line, additional_indent = additional_indent) + + def print_frame(self, print_type, frame): + + # Don't allow frames to be exposed if operations level is up + if len(self.ops) >= self.operations_level: + return + + code = getattr(frame, 'code', None) + filename = getattr(code, 'co_filename', "") + lineno = getattr(code, 'co_firstlineno', "") + + s = "<<<<<%s %s @ %s>>>>>>>" % (print_type, filename, lineno) + self.print_line(s) + + def print_bytecode(self, index, bytecode): + # Don't allow bytecodes to be exposed if operations level is up + if len(self.ops) >= self.operations_level: + return + + s = "%2d%s%s" % (index, (self.indentor * 2), bytecode) + self.print_line(s) + + + def print_op_enter(self, name, str_args): + s = " " * 17 + s += ">> %s%s" % (name, str_args) + self.print_line_operations(s) + + + def print_op_leave(self, name, str_res): + s = " " * 20 + s += "%s =: %s" % (name, str_res) + self.print_line_operations(s) + + + def print_op_exc(self, name, exc): + s = " " * 17 + s += "x= %s %s" % (name, exc) + self.print_line_operations(s) + + + def print_result(self, space, traceres): + + self.reset() + + for event in traceres.getevents(): + + if isinstance(event, trace.EnterFrame): + frame = event.frame + self.print_frame("enter", frame) + + self.frames.push(frame) + self.frame_count += 1 + + elif isinstance(event, trace.LeaveFrame): + lastframe = self.frames.pop() + self.frame_count -= 1 + + # Reset skip frame count? + if self.frame_count < self.skip_frame_count: + self.skip_frame_count = None + + self.print_frame("leave", lastframe) + + elif isinstance(event, trace.ExecBytecode): + + # Reset skip frame count? + if self.frame_count == self.skip_frame_count: + self.skip_frame_count = None + + frame = event.frame + assert (frame == self.frames.top()) + + # Get bytecode from frame + disresult = getdisresult(frame) + bytecode = disresult.getbytecode(event.index) + self.print_bytecode(event.index, bytecode) + + # When operations_level > 1, some bytecodes produce high number of + # operations / bytecodes (usually because they have been written at app + # level) - this hack avoids them recursing on them selves + if bytecode.name in self.skip_bytecodes: + self.print_line("...", 1) + self.skip_frame_count = self.frame_count + + elif isinstance(event, trace.CallBegin): + info = event.callinfo + + self.ops.push(info) + lastframe = self.frames.top() + self.print_op_enter(info.name, repr_args(space, lastframe, info.args)) + self.frame_count += 1 + + elif isinstance(event, trace.CallFinished): + info = event.callinfo + + self.frame_count -= 1 + self.print_op_leave(info.name, repr_value(space, event.res)) + + assert self.ops.pop() == event.callinfo + + elif isinstance(event, trace.CallException): + info = event.callinfo + self.frame_count -= 1 + + self.print_op_exc(info.name, event.ex) + + assert self.ops.pop() == event.callinfo + + else: + pass + +print_result = ResultPrinter().print_result + def repr_value(space, value): -## try: -## res = str(space.unwrap(value)) -## except: -## res = str(value) + """ representations for debugging purposes """ res = str(value) + try: + # XXX Sure this won't go down well - didn't really want + # to clutter up the interpeter code + from pypy.interpreter.argument import Arguments + from pypy.interpreter.function import Function, Method + + if isinstance(value, Function): + res = "Function(%s, %s)" % (value.name, value.code) + + if isinstance(value, Method): + res = "Method(%s, %s)" % (value.w_function.name, value.w_function.code) + + if isinstance(value, Arguments): + res = "Argument(%s, %s)" % (value.args_w, value.kwds_w) + + except Exception, exc: + pass + return res[:240] def repr_args(space, frame, args): From rxe at codespeak.net Sun Jul 25 22:58:39 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 25 Jul 2004 22:58:39 +0200 (MEST) Subject: [pypy-svn] r5670 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040725205839.47CD85AB33@thoth.codespeak.net> Author: rxe Date: Sun Jul 25 22:58:38 2004 New Revision: 5670 Modified: pypy/trunk/src/pypy/objspace/std/boolobject.py Log: representation for debugging purposes. (Mainly for traceobjectspace's benefit) Modified: pypy/trunk/src/pypy/objspace/std/boolobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/boolobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/boolobject.py Sun Jul 25 22:58:38 2004 @@ -12,6 +12,10 @@ def __nonzero__(w_self): raise Exception, "you cannot do that, you must use space.is_true()" + def __repr__(w_self): + """ representation for debugging purposes """ + return "%s(%s)" % (w_self.__class__.__name__, w_self.boolval) + registerimplementation(W_BoolObject) # bool-to-int delegation requires translating the .boolvar attribute From rxe at codespeak.net Sun Jul 25 23:04:16 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 25 Jul 2004 23:04:16 +0200 (MEST) Subject: [pypy-svn] r5671 - pypy/trunk/src/pypy/tool Message-ID: <20040725210416.47D4A5AC83@thoth.codespeak.net> Author: rxe Date: Sun Jul 25 23:04:15 2004 New Revision: 5671 Modified: pypy/trunk/src/pypy/tool/testit.py Log: Seemed there was a hack in here to use tracespace for debugging. Fixed up I think (review welcome :-)) Use -p option to enable trace space on any tests - probably best to use it on individual files rather than whole suite. Modified: pypy/trunk/src/pypy/tool/testit.py ============================================================================== --- pypy/trunk/src/pypy/tool/testit.py (original) +++ pypy/trunk/src/pypy/tool/testit.py Sun Jul 25 23:04:15 2004 @@ -64,7 +64,7 @@ class MyTextTestResult(unittest._TextTestResult): ignored = 0 - trace_information = () + trace_information = [] def record_trace(self, test): # XXX hack for TraceObjSpace @@ -73,7 +73,7 @@ except AttributeError: pass else: - self.trace_information += result + self.trace_information.append((test, result)) test.space.settrace() def addError(self, test, err): @@ -116,8 +116,8 @@ def printErrors(self): if self.trace_information: from pypy.tool.traceop import print_result - for trace in self.trace_information: - print_result(trace) + for test, trace in self.trace_information: + print_result(test.space, trace) sys.stdout.flush() if Options.interactive: print @@ -277,6 +277,7 @@ spacename = '' individualtime = 0 interactive = 0 + trace_flag = 0 #XXX what's the purpose of this? def ensure_value(*args): return 0 @@ -286,15 +287,28 @@ class TestSkip(Exception): pass -def objspace(name=''): +def objspace(name='', new_flag=False): if name and Options.spacename and name != Options.spacename: raise TestSkip - return option.objspace(name) + + if new_flag: + space = option.objspace(name, _spacecache={}) + else: + space = option.objspace(name) + + if Options.trace_flag: + # XXX This really sucks as a means to turn on tracing for a sole unit + # test (esp at app level). I can't see an obvious way to do this + # better. Don't think it is worth any mental energy given the new + # testing framework is just around the corner. + from pypy.objspace.trace import create_trace_space + create_trace_space(space) + space.settrace() + + return space def new_objspace(name=''): - if name and Options.spacename and name != Options.spacename: - raise TestSkip - return option.objspace(name,_spacecache={}) + return objspace(name=name, new_flag=True) class RegexFilterFunc: """ @@ -324,6 +338,10 @@ def get_test_options(): options = option.get_standard_options() + + options.append(make_option( + '-p', action="store_true", dest="trace_flag", + help="augment object space with tracing capabilities")) options.append(make_option( '-r', action="store_true", dest="testreldir", help="gather only tests relative to current dir")) @@ -347,6 +365,7 @@ run_tests_on_space(suite, spacename) def run_tests_on_space(suite, spacename=''): + """Run the suite on the given space.""" if Options.runcts: runner = CtsTestRunner() # verbosity=Options.verbose+1) From rxe at codespeak.net Sun Jul 25 23:08:09 2004 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 25 Jul 2004 23:08:09 +0200 (MEST) Subject: [pypy-svn] r5672 - pypy/trunk/src/pypy/tool Message-ID: <20040725210809.B0EED5B0CF@thoth.codespeak.net> Author: rxe Date: Sun Jul 25 23:08:09 2004 New Revision: 5672 Modified: pypy/trunk/src/pypy/tool/testit.py Log: Cosmetic - please ignore. Modified: pypy/trunk/src/pypy/tool/testit.py ============================================================================== --- pypy/trunk/src/pypy/tool/testit.py (original) +++ pypy/trunk/src/pypy/tool/testit.py Sun Jul 25 23:08:09 2004 @@ -290,12 +290,10 @@ def objspace(name='', new_flag=False): if name and Options.spacename and name != Options.spacename: raise TestSkip - if new_flag: space = option.objspace(name, _spacecache={}) else: - space = option.objspace(name) - + space = option.objspace(name) if Options.trace_flag: # XXX This really sucks as a means to turn on tracing for a sole unit # test (esp at app level). I can't see an obvious way to do this @@ -304,7 +302,6 @@ from pypy.objspace.trace import create_trace_space create_trace_space(space) space.settrace() - return space def new_objspace(name=''): @@ -338,7 +335,6 @@ def get_test_options(): options = option.get_standard_options() - options.append(make_option( '-p', action="store_true", dest="trace_flag", help="augment object space with tracing capabilities")) @@ -365,7 +361,6 @@ run_tests_on_space(suite, spacename) def run_tests_on_space(suite, spacename=''): - """Run the suite on the given space.""" if Options.runcts: runner = CtsTestRunner() # verbosity=Options.verbose+1) From lac at codespeak.net Mon Jul 26 10:59:09 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Mon, 26 Jul 2004 10:59:09 +0200 (MEST) Subject: [pypy-svn] r5673 - in pypy/trunk/src/pypy/tool: . test Message-ID: <20040726085909.8A6905A2EE@thoth.codespeak.net> Author: lac Date: Mon Jul 26 10:59:08 2004 New Revision: 5673 Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert.py pypy/trunk/src/pypy/tool/test/test_utestconvert2.py pypy/trunk/src/pypy/tool/utestconvert.py Log: In a different program I found a person in the habit of writing two unittests per line, when they can fit: self.assertEquals(dog, cat); self.assertEquals(mouse, rat) (actually they are a firm believer that whitespace after argument separating commas are deadly poison, but you get the idea.) The program converts the first one, and takes the rest as a trailing comment, which it passes unchanged. I have no plans to change this behaviour at the moment, only document it, but will do so if you think it is worth it. Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/test/test_utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert.py Mon Jul 26 10:59:08 2004 @@ -394,6 +394,18 @@ "is not in sys.modules.") """ ) + + # two unittests on the same line separated by a semi-colon is + # only half-converted. Just so you know. + assert rewrite_utest( + """ + self.assertEquals(0, 0); self.assertEquals(1, 1) #not 2 per line! + """ + ) == ( + """ + assert 0 == 0; self.assertEquals(1, 1) #not 2 per line! + """ + ) if __name__ == '__main__': Modified: pypy/trunk/src/pypy/tool/test/test_utestconvert2.py ============================================================================== --- pypy/trunk/src/pypy/tool/test/test_utestconvert2.py (original) +++ pypy/trunk/src/pypy/tool/test/test_utestconvert2.py Mon Jul 26 10:59:08 2004 @@ -369,19 +369,31 @@ self.assertEquals(rewrite_utest( """ - self.assertAlmostEquals(now do something reasonable ..() + self.assertAlmostEquals(now do something reasonable ..() oops, I am inside a comment as a ''' string, and the fname was mentioned in passing, leaving us with something that isn't an expression ... will this blow up? """ ), """ - self.assertAlmostEquals(now do something reasonable ..() + self.assertAlmostEquals(now do something reasonable ..() oops, I am inside a comment as a ''' string, and the fname was mentioned in passing, leaving us with something that isn't an expression ... will this blow up? """ ) + + self.assertEquals(rewrite_utest( + """ + happily inside a comment I write self.assertEquals(0, badger) + now will this one get rewritten? + """ + ), + """ + happily inside a comment I write self.assertEquals(0, badger) + now will this one get rewritten? + """ + ) self.assertEquals(rewrite_utest( """ @@ -394,9 +406,19 @@ "is not in sys.modules.") """ ) + + # two unittests on the same line separated by a semi-colon is + # only half-converted. Just so you know. + self.assertEquals(rewrite_utest( + """ + self.assertEquals(0, 0); self.assertEquals(1, 1) #not 2 per line! + """ + ), + """ + assert 0 == 0; self.assertEquals(1, 1) #not 2 per line! + """ + ) if __name__ == '__main__': unittest.main() - - Modified: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- pypy/trunk/src/pypy/tool/utestconvert.py (original) +++ pypy/trunk/src/pypy/tool/utestconvert.py Mon Jul 26 10:59:08 2004 @@ -132,7 +132,7 @@ trailer -- any extra junk after the closing paren, such as #commment ''' - indent = re.search(r'^(\s*)', block).group() + indent = re.match(r'(\s*)', block).group() pat = re.search('self.' + old + r'\(', block) args, trailer = get_expr(block[pat.end():], ')') From mwh at codespeak.net Tue Jul 27 13:39:31 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 27 Jul 2004 13:39:31 +0200 (MEST) Subject: [pypy-svn] r5707 - pypy/trunk/src/pypy/appspace Message-ID: <20040727113931.20A7A5A955@thoth.codespeak.net> Author: mwh Date: Tue Jul 27 13:39:30 2004 New Revision: 5707 Modified: pypy/trunk/src/pypy/appspace/_float_formatting.py Log: rewrite the float formatting stuff in Python as opposed to scheme dressed as Python. Modified: pypy/trunk/src/pypy/appspace/_float_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_float_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_float_formatting.py Tue Jul 27 13:39:30 2004 @@ -8,8 +8,7 @@ # Language Design and Implementation. # The paper contains scheme code which has been specialized for IEEE -# doubles and converted into (still somewhat scheme-like) Python by -# Michael Hudson. +# doubles and converted into Python by Michael Hudson. # XXX unfortunately, we need the fixed-format output routines, the source # for which is not included in the paper... for now, just put up with @@ -17,69 +16,80 @@ # XXX should run this at interpreter level, really.... +def decode_float(f): + """decode_float(float) -> int, int -## (define flonum->digits -## (lambda (v f e min-e p b B) -## (if (>= e 0) -## (if (not (= f (expt b (- p 1)))) -## (let ([be (expt b e)]) -## (scale (* f be 2) 2 be be 0 B v)) -## (let* ([be (expt b e)] [be1 (* be b)]) -## (scale (* f be1 2) (* b 2) be1 be 0 B v))) -## (if (or (= e min-e) (not (= f (expt b (- p 1))))) -## (scale (* f 2) (* (expt b (- e)) 2) 1 1 0 B v) -## (scale (* f b 2) (* (expt b (- 1 e)) 2) b 1 0 B v))))) - -# I reject generality in the extreme: we're working with -# ieee 754 64 bit doubles on any platform I care about. -# This means b == 2, min-e = -1074, p = 53 above. Also, -# specialize for B = 10. - -# in: -# v = f * 2**e -# out: -# [d0, d1, ..., dn], k -# st 0.[d1][d2]...[dn] * 10**k is the "best" representation of v + Return (m, e), the mantissa and exponent respectively of + f (assuming f is an IEEE double), i.e. f == m * 2**e and + 2**52 <= m < 2**53.""" + m, e = math.frexp(f) + m = long(m*2.0**53) + e -= 53 + return m, e + +def decompose(f): + """decompose(float) -> int, int, int, int -def flonum2digits(v, f, e): + Return r, s, m_plus, m_minus for f, in the terms of + Burger and Dybvig's paper (see Table 1). + + To spell this out: f = r/s, (r+m+)/s is halfway to the + next largest floating point number, (r-m-) halfway to + the next smallest.""" + m, e = decode_float(f) if e >= 0: - if not f != 2**52: + if not m != 2**52: be = 2**e - return scale(f*be*2, 2, be, be, 0, v) + return m*be*2, 2, be, be else: be = 2**e be1 = 2*be - return scale(f*be1*2, 4, be1, be, 0, v) + return m*be1*2, 4, be1, be else: - if e == -1075 or f != 2**52: - return scale(f*2, 2*2**(-e), 1, 1, 0, v) + if e == -1075 or m != 2**52: + return m*2, 2**(-e+1), 1, 1 else: - return scale(f*4, 2*2**(1-e), 2, 1, 0, v) + return m*4, 2**(-e+2), 2, 1 + + +def flonum2digits(f): + """flonum2digits(float) -> [int], int + + Given a float f return [d1, ..., dn], k such that + 0.[d1][d2]...[dn] * 10**k -## (define generate -## (lambda (r s m+ m- B low-ok? high-ok?) -## (let ([q-r (quotient-remainder (* r B) s)] -## [m+ (* m+ B)] -## [m- (* m- B)]) -## (let ([d (car q-r)] -## [r (cdr q-r)]) -## (let ([tc1 ((if low-ok? <= <) r m-)] -## [tc2 ((if high-ok? >= >) (+ r m+) s)]) -## (if (not tc1) -## (if (not tc2) -## (cons d (generate r s m+ m- B low-ok? high-ok?)) -## (list (+ d 1))) -## (if (not tc2) -## (list d) -## (if (< (* r 2) s) -## (list d) -## (list (+ d 1)))))))))) + is the shortest decimal representation that will + reproduce f when read in by a correctly rounding input + routine (under any strategy for breaking ties).""" + + assert f >= 0 + if f == 0.0: + return ['0'], 1 + + # See decompose's docstring for what these mean. + r, s, m_plus, m_minus = decompose(f) -# now the above is an example of a pointlessly recursive algorithm if -# ever i saw one... + # k is the index, relative to the radix point of the + # most-significant non-zero digit of the infinite + # decimal expansion of f. This calculation has the + # potential to underestimate by one (handled below). + k = long(math.ceil(math.log10(f) - 1e-10)) + + if k >= 0: + s *= 10 ** k + else: + scale = 10 ** -k + r *= scale + m_plus *= scale + m_minus *= scale + + # Check that we got k right above. + if r + m_plus > s: + s *= 10 + k += 1 -def generate(r, s, m_plus, m_minus): + # Generate the digits. rr = [] while 1: d, r = divmod(r*10, s) @@ -93,47 +103,8 @@ rr.append(d) if tc1 or tc2: break - return rr + + assert max(rr) < 10 + assert min(rr) >= 0 - -## (define scale -## (lambda (r s m+ m- k B low-ok? high-ok? v) -## (let ([est (inexact->exact (ceiling (- (logB B v) 1e-10)))]) -## (if (>= est 0) -## (fixup r (* s (exptt B est)) m+ m- est B low-ok? high-ok? ) -## (let ([scale (exptt B (- est))]) -## (fixup (* r scale) s (* m+ scale) (* m- scale) -## est B low-ok? high-ok? )))))) - -def scale(r, s, m_plus, m_minus, k, v): - est = long(math.ceil(math.log(v, 10) - 1e-10)) - if est >= 0: - return fixup(r, s * 10 ** est, m_plus, m_minus, est) - else: - scale = 10 ** -est - return fixup(r*scale, s, m_plus*scale, m_minus*scale, est) - - -## (define fixup -## (lambda (r s m+ m- k B low-ok? high-ok? ) -## (if ((if high-ok? >= >) (+ r m+) s) ; too low? -## (cons (+ k 1) (generate r (* s B) m+ m- B low-ok? high-ok? )) -## (cons k (generate r s m+ m- B low-ok? high-ok? ))))) - -def fixup(r, s, m_plus, m_minus, k): - if r + m_plus > s: - return generate(r, s*10, m_plus, m_minus), k + 1 - else: - return generate(r, s, m_plus, m_minus), k - - -def float_digits(f): - assert f >= 0 - if f == 0.0: - return ['0'], 1 - m, e = math.frexp(f) - m = long(m*2.0**53) - e -= 53 - ds, k = flonum2digits(f, m, e) - ds = map(str, ds) - return ds, k + return map(str, rr), k From mwh at codespeak.net Tue Jul 27 13:40:15 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 27 Jul 2004 13:40:15 +0200 (MEST) Subject: [pypy-svn] r5708 - pypy/trunk/src/pypy/appspace Message-ID: <20040727114015.018555C199@thoth.codespeak.net> Author: mwh Date: Tue Jul 27 13:40:15 2004 New Revision: 5708 Modified: pypy/trunk/src/pypy/appspace/_formatting.py Log: Oops, should have checked this in along with the last revision. Modified: pypy/trunk/src/pypy/appspace/_formatting.py ============================================================================== --- pypy/trunk/src/pypy/appspace/_formatting.py (original) +++ pypy/trunk/src/pypy/appspace/_formatting.py Tue Jul 27 13:40:15 2004 @@ -187,7 +187,7 @@ return floater() -from _float_formatting import float_digits +from _float_formatting import flonum2digits class FloatFormatter(Formatter): def eDigits(self, ds): @@ -227,7 +227,7 @@ if v/1e25 > 1e25: return floatGFormatter('g', self.flags, self.width, self.prec, self.value).format() - ds, k = float_digits(v) + ds, k = flonum2digits(v) digits = self.fDigits(ds, k) if not self.flags.f_alt: digits = digits.rstrip('.') @@ -236,7 +236,7 @@ class FloatEFormatter(FloatFormatter): def _format(self, v): - ds, k = float_digits(v) + ds, k = flonum2digits(v) digits = self.eDigits(ds) return "%s%c%+03d"%(digits, self.char, k-1) @@ -247,7 +247,7 @@ # Gah, this still isn't quite right in the f_alt case. # (One has to wonder who might care). def _format(self, v): - ds, k = float_digits(v) + ds, k = flonum2digits(v) ds = ds[:self.prec] # XXX rounding! if -4 < k <= self.prec: digits = self.fDigits(ds, k) From mwh at codespeak.net Tue Jul 27 14:09:26 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 27 Jul 2004 14:09:26 +0200 (MEST) Subject: [pypy-svn] r5710 - pypy/trunk/src/pypy/objspace Message-ID: <20040727120926.8FBDF5C19A@thoth.codespeak.net> Author: mwh Date: Tue Jul 27 14:09:26 2004 New Revision: 5710 Modified: pypy/trunk/src/pypy/objspace/descroperation.py Log: Remove extra definition of contains(). Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Tue Jul 27 14:09:26 2004 @@ -181,13 +181,6 @@ return space.get_and_call_function(w_descr,w_obj) # XXX PyObject_Repr() probably checks that the result is a string - def contains(space,w_obj,w_val): - w_descr = space.lookup(w_obj,'__contains__') - if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("object doesn't know about contains")) - return space.get_and_call_function(w_descr,w_obj,w_val) - def iter(space,w_obj): w_descr = space.lookup(w_obj,'__iter__') if w_descr is None: From mwh at codespeak.net Tue Jul 27 14:22:41 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 27 Jul 2004 14:22:41 +0200 (MEST) Subject: [pypy-svn] r5712 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040727122241.5A5785C19B@thoth.codespeak.net> Author: mwh Date: Tue Jul 27 14:22:40 2004 New Revision: 5712 Added: pypy/trunk/src/pypy/objspace/std/test/test_unicodestring.py Modified: pypy/trunk/src/pypy/objspace/std/fake.py pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringobject.py pypy/trunk/src/pypy/objspace/std/unicodeobject.py Log: Sundry changes to strings, unicode and the interaction betwixt the two. In particular: Robustify str.join against non-strings in the passed list. DTRT when unicode is found. Implement 2.3 semantics for str.__contains__. Unbreak string->unicode delegation. Make mixing strings and unicode in addition work. Also make '' in u'' and u'' in '' work. Tests for the above. All this meant I needed to special case unicode in fake.py a little more again. Oh well.. Modified: pypy/trunk/src/pypy/objspace/std/fake.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/fake.py (original) +++ pypy/trunk/src/pypy/objspace/std/fake.py Tue Jul 27 14:22:40 2004 @@ -36,7 +36,8 @@ print 'faking %r'%(cpy_type,) kw = {} for s, v in cpy_type.__dict__.items(): - kw[s] = v + if cpy_type is not unicode or s not in ['__add__', '__contains__']: + kw[s] = v def fake__new__(space, w_type, *args_w): args = [space.unwrap(w_arg) for w_arg in args_w] try: @@ -60,7 +61,7 @@ def fake_unwrap(space, w_obj): return w_obj.val StdObjSpace.unwrap.register(fake_unwrap, W_Fake) - W_Fake.__name__ = 'W_Fake(%s)'%(cpy_type.__name__) + W_Fake.__name__ = 'W_Fake%s'%(cpy_type.__name__.capitalize()) W_Fake.typedef.fakedcpytype = cpy_type # XXX obviously this entire file is something of a hack, but it # manages to get worse here: Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/stringobject.py Tue Jul 27 14:22:40 2004 @@ -328,10 +328,18 @@ self = u(w_self) firstelem = 1 listlen = 0 - reslen = 0 + reslen = 0 #compute the length of the resulting string - for w_item in list: - reslen = reslen + len(u(w_item)) + for i in range(len(list)): + if not space.is_true(space.isinstance(list[i], space.w_str)): + if space.is_true(space.isinstance(list[i], space.w_unicode)): + w_u = space.call_function(space.w_unicode, w_self) + return space.call_method(w_u, "join", w_list) + raise OperationError( + space.w_TypeError, + space.wrap("sequence item %d: expected string, %s " + "found"%(i, space.type(list[i]).name))) + reslen = reslen + len(u(list[i])) listlen = listlen + 1 reslen = reslen + (listlen - 1) * len(self) @@ -346,8 +354,8 @@ if firstelem: for i in range(len(item)): res[i+pos] = item[i] - firstelem = 0 pos = pos + len(item) + firstelem = 0 else: for i in range(len(self)): res[i+pos] = self[i] @@ -931,6 +939,10 @@ from pypy.objspace.std import iterobject return iterobject.W_SeqIterObject(space, w_list) +def app_contains__String_String(self, sub): + return self.find(sub) >= 0 + +contains__String_String = gateway.app2interp(app_contains__String_String) def app_repr__String(s): quote = "'" Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringobject.py Tue Jul 27 14:22:40 2004 @@ -366,6 +366,9 @@ self.assertEquals(", ".join(['a', 'b', 'c']), "a, b, c") self.assertEquals("".join([]), "") self.assertEquals("-".join(['a', 'b']), 'a-b') + self.assertRaises(TypeError, ''.join, 1) + self.assertRaises(TypeError, ''.join, [1]) + self.assertRaises(TypeError, ''.join, [[1]]) def test_lower(self): self.assertEquals("aaa AAA".lower(), "aaa aaa") @@ -472,6 +475,13 @@ self.assertEquals(repr("'''\"") ,'\'\\\'\\\'\\\'"\'') self.assertEquals(repr(chr(19)) ,"'\\x13'") self.assertEquals(repr(chr(2)) ,"'\\x02'") + + def test_contains(self): + self.failUnless('' in 'abc') + self.failUnless('a' in 'abc') + self.failUnless('ab' in 'abc') + self.failIf('d' in 'abc') + self.assertRaises(TypeError, 'a'.__contains__, 1) if __name__ == '__main__': Added: pypy/trunk/src/pypy/objspace/std/test/test_unicodestring.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/test/test_unicodestring.py Tue Jul 27 14:22:40 2004 @@ -0,0 +1,37 @@ +# test the integration of unicode and strings (even though we don't +# really implement unicode yet). + +import autopath +from pypy.tool import testit + + +class TestUnicodeString(testit.AppTestCase): + def test_compares(self): + self.assertEqual(u'a', 'a') + self.assertEqual('a', u'a') + self.assertNotEqual(u'a', 'b') + self.assertNotEqual('a', u'b') + + def test_addition(self): + def check(a, b): + self.assertEqual(a, b) + self.assertEqual(type(a), type(b)) + check(u'a' + 'b', u'ab') + check('a' + u'b', u'ab') + + def test_join(self): + def check(a, b): + self.assertEqual(a, b) + self.assertEqual(type(a), type(b)) + check(', '.join([u'a']), u'a') + check(', '.join(['a', u'b']), u'a, b') + check(u', '.join(['a', 'b']), u'a, b') + + def test_contains(self): + self.failUnless(u'' in 'abc') + self.failUnless(u'a' in 'abc') + self.failUnless('a' in u'abc') + + +if __name__ == '__main__': + testit.main() Modified: pypy/trunk/src/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/unicodeobject.py Tue Jul 27 14:22:40 2004 @@ -6,7 +6,7 @@ # string-to-unicode delegation def delegate__String(space, w_str): - return W_Unicode(space, unicode(w_str)) + return W_UnicodeObject(space, unicode(space.unwrap(w_str))) delegate__String.result_class = W_UnicodeObject delegate__String.priority = PRIORITY_CHANGE_TYPE delegate__String.can_fail = True @@ -28,6 +28,14 @@ return space.wrap(ord(w_uni.val)) except: wrap_exception(space) - + +def add__Unicode_Unicode(space, w_left, w_right): + return space.wrap(space.unwrap(w_left) + space.unwrap(w_right)) + +def contains__String_Unicode(space, w_left, w_right): + return space.wrap(space.unwrap(w_right) in space.unwrap(w_left)) + +def contains__Unicode_Unicode(space, w_left, w_right): + return space.wrap(space.unwrap(w_right) in space.unwrap(w_left)) register_all(vars()) From arigo at codespeak.net Tue Jul 27 15:21:04 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 27 Jul 2004 15:21:04 +0200 (MEST) Subject: [pypy-svn] r5723 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040727132104.F052A5C19C@thoth.codespeak.net> Author: arigo Date: Tue Jul 27 15:21:04 2004 New Revision: 5723 Added: pypy/trunk/src/pypy/objspace/std/autopath.py (props changed) - copied unchanged from r5711, pypy/trunk/src/pypy/tool/autopath.py pypy/trunk/src/pypy/objspace/std/dump_multimethod.py Modified: pypy/trunk/src/pypy/objspace/std/multimethod.py Log: A first draft at dump_multimethod.py, which dumps to stdout the complete multimethod tables. Added: pypy/trunk/src/pypy/objspace/std/dump_multimethod.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/dump_multimethod.py Tue Jul 27 15:21:04 2004 @@ -0,0 +1,135 @@ +from __future__ import generators +import autopath +import sys +from pypy.objspace.std import StdObjSpace +from pypy.objspace.std.multimethod import * + +# TODO: local multimethods + +IMPLEMENTATIONS = [ + "pypy.objspace.std.objectobject.W_ObjectObject", + "pypy.objspace.std.boolobject.W_BoolObject", + "pypy.objspace.std.intobject.W_IntObject", + "pypy.objspace.std.floatobject.W_FloatObject", + "pypy.objspace.std.tupleobject.W_TupleObject", + "pypy.objspace.std.listobject.W_ListObject", + "pypy.objspace.std.dictobject.W_DictObject", + "pypy.objspace.std.stringobject.W_StringObject", + "pypy.objspace.std.typeobject.W_TypeObject", + "pypy.objspace.std.sliceobject.W_SliceObject", + "pypy.objspace.std.longobject.W_LongObject", + "pypy.objspace.std.noneobject.W_NoneObject", + "pypy.objspace.std.iterobject.W_SeqIterObject", + "pypy.objspace.std.unicodeobject.W_UnicodeObject", + ] + +def import_implementations(): + # populate the multimethod tables by importing all object implementations + from pypy.objspace.std import default + result = [] + for fullpath in IMPLEMENTATIONS: + i = fullpath.rfind('.') + assert i>=0 + modname, clsname = fullpath[:i], fullpath[i+1:] + module = __import__(modname, globals(), {}, [clsname]) + result.append(getattr(module, clsname)) + return result + +def list_multimethods(): + result = [] + for name, value in StdObjSpace.MM.__dict__.iteritems(): + if isinstance(value, MultiMethod): + result.append((name, value)) + result.sort() + return result + +def cartesian_prod(lstlst): + if len(lstlst) == 0: + yield () + else: + for first in lstlst[0]: + for rest in cartesian_prod(lstlst[1:]): + yield (first,) + rest + +def dump_table(mm, impls): + print 'multimethod %r of arity %d.' % (mm.operatorsymbol, mm.arity) + delegate = StdObjSpace.delegate + versions = {} + for argclasses in cartesian_prod([impls] * mm.arity): + calllist = [] + mm.internal_buildcalllist(argclasses, delegate, calllist) + src, glob = mm.internal_sourcecalllist(argclasses, calllist) + if 'FailedToImplement' in glob: + del glob['FailedToImplement'] + order = len(glob) + else: + order = 0.5 + glob = glob.items() + glob.sort() + glob = tuple(glob) + versions.setdefault((order, src, glob), []).append(argclasses) + versions = versions.items() + versions.sort() + versions.reverse() + for (order, src, glob), lstargclasses in versions: + print + # collapse ranges within argclasses where the last arg is not + # relevant + i = len(lstargclasses)-1 + m = mm.arity-1 + while i >= 0: + if i+len(impls) <= len(lstargclasses): + model = lstargclasses[i][:m] + for next in lstargclasses[i+1:i+len(impls)]: + if next[:m] == model and next[m+1:] == (W_ANY,)*(mm.arity-1-m): + pass + else: + break + else: + lstargclasses[i:i+len(impls)] = [model + (W_ANY,)*(mm.arity-m)] + if m > 0: + m -= 1 + continue + i -= 1 + m = mm.arity-1 + + for argclasses in lstargclasses: + print '#', + for cls in argclasses: + if cls is W_ANY: + print '*', + else: + print cls.__name__, + print + print + + # prettify src + if not src: + src = 'directly using do' + lines = src.split('\n') + for j in range(len(lines)): + line = lines[j] + i = 1 + while line[:i] == ' '*i: + i += 1 + i -= 1 + lines[j] = ' '*i + line[i:] + src = '\n'.join(lines) + src = src.replace(',', ', ') + for key, value in glob: + try: + s = value.__name__ + except AttributeError: + s = repr(value) + src = src.replace(key, s) + print src + +if __name__ == '__main__': + impls = import_implementations() + print impls + for name, mm in list_multimethods(): + print + print '==========', name, '==========' + print >> sys.stderr, name # progress bar + print + dump_table(mm, impls) Modified: pypy/trunk/src/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/multimethod.py (original) +++ pypy/trunk/src/pypy/objspace/std/multimethod.py Tue Jul 27 15:21:04 2004 @@ -68,6 +68,12 @@ return result def internal_compilecalllist(self, argclasses, calllist): + source, glob = self.internal_sourcecalllist(argclasses, calllist) + # compile the function + exec source in glob + return glob['do'] + + def internal_sourcecalllist(self, argclasses, calllist): """Translate a call list into the source of a Python function which is optimized and doesn't do repeated conversions on the same arguments.""" @@ -76,7 +82,7 @@ if conversions.count([]) == len(conversions): # no conversion, just calling a single function: return # that function directly - return fn + return '', {'do': fn} #print '**** compile **** ', self.operatorsymbol, [ # t.__name__ for t in argclasses] @@ -137,16 +143,10 @@ source.append(' raise FailedToImplement()') source.append('') - # compile the function glob = {'FailedToImplement': FailedToImplement} for fn, fname in all_functions.items(): glob[fname] = fn - #for key, value in glob.items(): - # print key, '=', value - #for line in source: - # print line - exec '\n'.join(source) in glob - return glob['do'] + return '\n'.join(source), glob def internal_buildcalllist(self, argclasses, delegate, calllist): """Build a list of calls to try for the given classes of the From arigo at codespeak.net Tue Jul 27 15:26:31 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 27 Jul 2004 15:26:31 +0200 (MEST) Subject: [pypy-svn] r5726 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040727132631.CC1F05C19D@thoth.codespeak.net> Author: arigo Date: Tue Jul 27 15:26:31 2004 New Revision: 5726 Modified: pypy/trunk/src/pypy/objspace/std/dump_multimethod.py Log: Use command-line arguments to only dump selected multimethods. Modified: pypy/trunk/src/pypy/objspace/std/dump_multimethod.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/dump_multimethod.py (original) +++ pypy/trunk/src/pypy/objspace/std/dump_multimethod.py Tue Jul 27 15:26:31 2004 @@ -126,10 +126,15 @@ if __name__ == '__main__': impls = import_implementations() - print impls + total = 0 + restrict = sys.argv[1:] for name, mm in list_multimethods(): - print - print '==========', name, '==========' - print >> sys.stderr, name # progress bar - print - dump_table(mm, impls) + if not restrict or name in restrict: + print + print '==========', name, '==========' + print >> sys.stderr, name # progress bar + print + dump_table(mm, impls) + total += 1 + if not total: + print >> sys.stderr, "no matching multimethod name" From alastair at codespeak.net Wed Jul 28 00:14:13 2004 From: alastair at codespeak.net (alastair at codespeak.net) Date: Wed, 28 Jul 2004 00:14:13 +0200 (MEST) Subject: [pypy-svn] r5739 - pypy/trunk/doc/funding/negotiations Message-ID: <20040727221413.40A215AA20@thoth.codespeak.net> Author: alastair Date: Wed Jul 28 00:14:12 2004 New Revision: 5739 Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22_individual.sxw Log: Added description of proposed amendments. Deleted the last vestiges of the PBF as partner. Fixed numerous typos. Added "Some documentation and tutoring tasks may be subcontracted" to cover the case that Alex does not form his own company. Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22_individual.sxw ============================================================================== Binary files. No diff available. From pedronis at codespeak.net Thu Jul 29 12:38:31 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 29 Jul 2004 12:38:31 +0200 (MEST) Subject: [pypy-svn] r5776 - pypy/trunk/doc/funding/negotiations Message-ID: <20040729103831.DE3BB5C1A4@thoth.codespeak.net> Author: pedronis Date: Thu Jul 29 12:38:31 2004 New Revision: 5776 Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22_individual.sxw Log: fixed ld contractor nrs (and added abbrev for sanity) Modified: pypy/trunk/doc/funding/negotiations/part_b_2004_07_22_individual.sxw ============================================================================== Binary files. No diff available. From jacob at codespeak.net Thu Jul 29 21:16:21 2004 From: jacob at codespeak.net (jacob at codespeak.net) Date: Thu, 29 Jul 2004 21:16:21 +0200 (MEST) Subject: [pypy-svn] r5796 - pypy/trunk/doc/funding/negotiations Message-ID: <20040729191621.8F0795AE7F@thoth.codespeak.net> Author: jacob Date: Thu Jul 29 21:16:20 2004 New Revision: 5796 Modified: pypy/trunk/doc/funding/negotiations/IST-2-004779-STP.cpf Log: CPF updated with PO's requests. Number of reporting periods changed from 4 to 2. Turnover figures from Logilab added. Modified: pypy/trunk/doc/funding/negotiations/IST-2-004779-STP.cpf ============================================================================== --- pypy/trunk/doc/funding/negotiations/IST-2-004779-STP.cpf (original) +++ pypy/trunk/doc/funding/negotiations/IST-2-004779-STP.cpf Thu Jul 29 21:16:20 2004 @@ -1,8 +1,8 @@ - + - @@ -125,7 +125,7 @@ - @@ -479,8 +479,8 @@ FR09 432 746 19 - - + 316676 + 131081 10 @@ -561,7 +561,7 @@ - @@ -1038,7 +1038,7 @@ - @@ -1245,7 +1245,7 @@ - @@ -1424,6 +1424,24 @@ 17405 + 630737 + 0 + 503683 + 586810 + 1095220 + 0 + 39200 + 1134420 + 1 of 1 + 2237810 + 1258600 + 0 + 0 + 94400 + 94400 + 0 + 2332210 + 1353000 @@ -1445,6 +1463,24 @@ + 279390 + 0 + 0 + 279390 + 279390 + 0 + 0 + 279390 + 1 of 1 + 2237810 + 1258600 + 0 + 0 + 94400 + 94400 + 0 + 2332210 + 1353000 @@ -1466,6 +1502,24 @@ 6700 + 422300 + 0 + 87300 + 271800 + 475600 + 0 + 34000 + 509600 + 1 of 1 + 2237810 + 1258600 + 0 + 0 + 94400 + 94400 + 0 + 2332210 + 1353000 @@ -1487,6 +1541,24 @@ + 229460 + 0 + 66540 + 148000 + 296000 + 0 + 0 + 296000 + 1 of 1 + 2237810 + 1258600 + 0 + 0 + 94400 + 94400 + 0 + 2332210 + 1353000 @@ -1508,6 +1580,24 @@ 750 + 109890 + 0 + 2910 + 67000 + 91600 + 0 + 21200 + 112800 + 1 of 1 + 2237810 + 1258600 + 0 + 0 + 94400 + 94400 + 0 + 2332210 + 1353000 @@ -1525,7 +1615,7 @@ - @@ -1605,69 +1695,76 @@ PYPY 1 1 - 6 + 12 862538 862538 + Reporting Period 1 004779 PYPY 2 - 7 - 12 - - + 13 + 24 + 490463 + 388988 + Reporting Period 2 004779 PYPY 3 - 13 - 18 - 388988 - 388988 + 0 + 0 + 0 + 0 + Reporting Period 3 004779 PYPY 4 - 19 - 24 - 101475 + 0 + 0 + 0 + Reporting Period 4 004779 PYPY 5 - - + 0 + 0 + Reporting Period 5 004779 PYPY 6 - - + 0 + 0 + Reporting Period 6 004779 PYPY 7 - - + 0 + 0 + Reporting Period 7 @@ -1685,7 +1782,7 @@ - @@ -1949,7 +2046,7 @@ - @@ -2135,7 +2232,7 @@ - @@ -2525,6 +2622,26 @@ 282781 222645 110478 + 6424779 + 7122649 + 23846376 + 17999674 + 30271155 + 25122323 + 5016425 + 4820614 + 25254730 + 20301708 + 30271155 + 25122322 + 1242392 + 1203463 + 221814 + 47215 + 256590 + 331206 + 186230 + 503509 @@ -2595,6 +2712,26 @@ + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 @@ -2665,6 +2802,26 @@ + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 @@ -2735,6 +2892,26 @@ + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 @@ -2805,6 +2982,26 @@ + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 From jacob at codespeak.net Thu Jul 29 21:37:49 2004 From: jacob at codespeak.net (jacob at codespeak.net) Date: Thu, 29 Jul 2004 21:37:49 +0200 (MEST) Subject: [pypy-svn] r5797 - pypy/trunk/doc/funding/negotiations Message-ID: <20040729193749.9C0965B104@thoth.codespeak.net> Author: jacob Date: Thu Jul 29 21:37:49 2004 New Revision: 5797 Added: pypy/trunk/doc/funding/negotiations/part_b_2004_07_29.sxw (contents, props changed) Log: Version submitted to PO today. Based on part_b_2004_07_22.sxw with WP information pasted in from part_b_2004_07_22_individual.sxw. Some minor graphical changes made. One last reference to the PBF removed. Added: pypy/trunk/doc/funding/negotiations/part_b_2004_07_29.sxw ============================================================================== Binary file. No diff available.