From hpk at codespeak.net Tue Jun 1 10:24:44 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 10:24:44 +0200 (MEST) Subject: [pypy-svn] r4785 - in pypy/trunk/src/pypy: module/test/impsubdir/pkg translator/test Message-ID: <20040601082444.3D0275BFCA@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 10:24:43 2004 New Revision: 4785 Modified: pypy/trunk/src/pypy/module/test/impsubdir/pkg/relative_a.py (props changed) pypy/trunk/src/pypy/translator/test/test_translator.py (props changed) Log: fixel From hpk at codespeak.net Tue Jun 1 10:25:09 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 10:25:09 +0200 (MEST) Subject: [pypy-svn] r4786 - pypy/trunk/src/goal Message-ID: <20040601082509.1828C5BFCB@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 10:25:07 2004 New Revision: 4786 Modified: pypy/trunk/src/goal/ (props changed) pypy/trunk/src/goal/compiler-hack.py (contents, props changed) pypy/trunk/src/goal/http-and-html.py (props changed) pypy/trunk/src/goal/pydoc-goal.py (props changed) pypy/trunk/src/goal/pydoc-pregoal.py (props changed) Log: fixel Modified: pypy/trunk/src/goal/compiler-hack.py ============================================================================== --- pypy/trunk/src/goal/compiler-hack.py (original) +++ pypy/trunk/src/goal/compiler-hack.py Tue Jun 1 10:25:07 2004 @@ -1,13 +1,13 @@ -# Hacks to import compiler package -# As of revision 3865 - -import os -os.error = OSError -import __builtin__ -__builtin__.reload = lambda x: x -import ihooks -ihooks.install() -import compiler -c = compiler.compile('a=1', '', 'exec') -import dis -dis.dis(c) +# Hacks to import compiler package +# As of revision 3865 + +import os +os.error = OSError +import __builtin__ +__builtin__.reload = lambda x: x +import ihooks +ihooks.install() +import compiler +c = compiler.compile('a=1', '', 'exec') +import dis +dis.dis(c) From hpk at codespeak.net Tue Jun 1 10:40:20 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 10:40:20 +0200 (MEST) Subject: [pypy-svn] r4790 - in pypy/trunk/doc: devel funding funding/makedoc funding/negotiations irclog objspace sprintinfo translation Message-ID: <20040601084020.5890C5BE07@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 10:40:19 2004 New Revision: 4790 Modified: pypy/trunk/doc/devel/ (props changed) pypy/trunk/doc/funding/ (props changed) pypy/trunk/doc/funding/makedoc/ (props changed) pypy/trunk/doc/funding/negotiations/ (props changed) pypy/trunk/doc/irclog/ (props changed) pypy/trunk/doc/objspace/ (props changed) pypy/trunk/doc/sprintinfo/ (props changed) pypy/trunk/doc/translation/ (props changed) Log: removed unwanted ignores From pedronis at codespeak.net Tue Jun 1 11:01:52 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 1 Jun 2004 11:01:52 +0200 (MEST) Subject: [pypy-svn] r4791 - in pypy/trunk/src/pypy/module: . test test/impsubdir test/impsubdir/notapackage test/impsubdir/pkg test/impsubdir/pkg_r test/impsubdir/pkg_r/x test/impsubdir/pkg_relative_a test/impsubdir/x Message-ID: <20040601090152.E2F7D5BFCB@thoth.codespeak.net> Author: pedronis Date: Tue Jun 1 11:01:52 2004 New Revision: 4791 Added: pypy/trunk/src/pypy/module/test/impsubdir/b.py pypy/trunk/src/pypy/module/test/impsubdir/notapackage/ pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_b.py pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_x_y.py pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/ pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/__init__.py pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/inpkg.py pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/ pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.py pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.pyc (contents, props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/ pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/__init__.py pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/a.py pypy/trunk/src/pypy/module/test/impsubdir/x/ pypy/trunk/src/pypy/module/test/impsubdir/x/__init__.py pypy/trunk/src/pypy/module/test/impsubdir/x/y.py Modified: pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/test/test_import.py Log: more import tests more relative import tests better rel import support (still to fix(?) rel import shortcut None setting, 1 test failing about that) 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 Tue Jun 1 11:01:52 2004 @@ -56,6 +56,15 @@ raise return None +def try_getitem(w_obj,w_key): + try: + return space.getitem(w_obj, w_key) + except OperationError, e: + if not e.match(space, space.w_KeyError): + raise + return None + + def check_sys_modules(w_modulename): try: w_mod = space.getitem(space.sys.w_modules, w_modulename) @@ -67,6 +76,8 @@ raise return None +il_len = len + def __import__(w_modulename, w_globals=None, w_locals=None, w_fromlist=None): modulename = space.unwrap(w_modulename) @@ -78,63 +89,105 @@ raise OperationError(space.w_TypeError, space.wrap("__import__() argument 1 must be string" + helper)) w = space.wrap - w_mod = check_sys_modules(w_modulename) - if w_mod is not None: - return w_mod - - w_mod = space.get_builtin_module(modulename) - if w_mod is not None: - return w_mod - import os + ctxt_w_name = None + ctxt_w_path = None + if w_globals is not None: + ctxt_w_name = try_getitem(w_globals,w('__name__')) + ctxt_w_path = try_getitem(w_globals,w('__path__')) + + rel_modulename = None + if ctxt_w_name is not None: + + ctxt_name_prefix_parts = space.unwrap(ctxt_w_name).split('.') + if ctxt_w_path is None: # context is a plain module + ctxt_name_prefix_parts = ctxt_name_prefix_parts[:-1] + if ctxt_name_prefix_parts: + rel_modulename = '.'.join(ctxt_name_prefix_parts+[modulename]) + else: # context is a package module + rel_modulename = space.unwrap(ctxt_w_name)+'.'+modulename + if rel_modulename is not None: + w_mod = check_sys_modules(w(rel_modulename)) + if (w_mod is None or + not space.is_true(space.is_(w_mod,space.w_None))): + + w_mod = absolute_import(rel_modulename, + il_len(ctxt_name_prefix_parts), + w_fromlist, tentative=1) + if w_mod is not None: + return w_mod + else: + rel_modulename = None + + w_mod = absolute_import(modulename,0,w_fromlist, tentative=0) + if rel_modulename is not None: + space.setitem(space.sys.w_modules, w(rel_modulename),space.w_None) + return w_mod +def absolute_import(modulename, baselevel, w_fromlist, tentative): + w = space.wrap + + w_mod = None parts = modulename.split('.') prefix = [] w_path = space.sys.w_path first = None + level = 0 for part in parts: - w_mod = load_part(w_path, prefix, part, w_mod) + w_mod = load_part(w_path, prefix, part, w_mod, tentative=tentative) if w_mod is None: - # ImportError - w_failing = w('.'.join(prefix+[part])) - w_exc = space.call_function(space.w_ImportError, w_failing) - raise OperationError(space.w_ImportError, w_exc) - if first is None: + return None + + if baselevel == level: first = w_mod + tentative = 0 prefix.append(part) w_path = try_getattr(w_mod,w('__path__')) - + level += 1 if w_fromlist is not None and space.is_true(w_fromlist): if w_path is not None: for w_name in space.unpackiterable(w_fromlist): - load_part(w_path, prefix, space.unwrap(w_name), w_mod) + load_part(w_path, prefix, space.unwrap(w_name), w_mod, + tentative=1) return w_mod else: return first -def load_part(w_path, prefix, partname, w_parent): +def load_part(w_path, prefix, partname, w_parent, tentative): w = space.wrap - w_modulename = w('.'.join(prefix+[partname])) + modulename = '.'.join(prefix+[partname]) + w_modulename = w(modulename) w_mod = check_sys_modules(w_modulename) if w_mod is not None: - return w_mod - for path in space.unpackiterable(w_path): - dir = os.path.join(space.unwrap(path), partname) - if os.path.isdir(dir): - f = os.path.join(dir,'__init__.py') - w_mod = try_import_mod(w_modulename, f, w_parent, w(partname), - pkgdir=dir) - if w_mod is not None: - return w_mod - f = os.path.join(space.unwrap(path), partname + '.py') - w_mod = try_import_mod(w_modulename, f, w_parent, w(partname)) + if not space.is_true(space.is_(w_mod,space.w_None)): + return w_mod + else: + w_mod = space.get_builtin_module(modulename) if w_mod is not None: return w_mod + for path in space.unpackiterable(w_path): + dir = os.path.join(space.unwrap(path), partname) + if os.path.isdir(dir): + f = os.path.join(dir,'__init__.py') + w_mod = try_import_mod(w_modulename, f, w_parent, w(partname), + pkgdir=dir) + if w_mod is not None: + return w_mod + f = os.path.join(space.unwrap(path), partname + '.py') + w_mod = try_import_mod(w_modulename, f, w_parent, w(partname)) + if w_mod is not None: + return w_mod - return None + if tentative: + return None + else: + # ImportError + w_failing = w_modulename + w_exc = space.call_function(space.w_ImportError, w_failing) + raise OperationError(space.w_ImportError, w_exc) def compile(w_str, w_filename, w_startstr, Added: pypy/trunk/src/pypy/module/test/impsubdir/b.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/b.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1,3 @@ +# b.py +imamodule = 1 +inpackage = 0 Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_b.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_b.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1 @@ +import b Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_x_y.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_x_y.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1 @@ +import x.y Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/__init__.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1 @@ +# pkg Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/inpkg.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/inpkg.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1 @@ +import x.y Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1 @@ +# pkg Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.pyc ============================================================================== Binary file. No diff available. Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/__init__.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1,2 @@ +# pkg +import a Added: pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/a.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/a.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1,3 @@ +# a.py +imamodule = 1 +inpackage = 1 Added: pypy/trunk/src/pypy/module/test/impsubdir/x/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/x/__init__.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1 @@ +# pkg Added: pypy/trunk/src/pypy/module/test/impsubdir/x/y.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/module/test/impsubdir/x/y.py Tue Jun 1 11:01:52 2004 @@ -0,0 +1 @@ +# y.py 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 Tue Jun 1 11:01:52 2004 @@ -1,25 +1,37 @@ import autopath from pypy.tool import testit +from pypy.interpreter import gateway import os -class TestImport(testit.AppTestCase): - def setUp(self): # interpreter-level - self.space = testit.new_objspace() - def test_import_bare_dir_fails(self): - def imp(): - import impsubdir - self.assertRaises(ImportError,imp) -class TestImportChdiredToimpsubdir(testit.AppTestCase): +def _setup(dn=os.path.abspath(os.path.join(os.path.dirname(__file__), 'impsubdir'))): + import sys + sys.path.append(dn) + return sys.modules.copy() + +_setup = gateway.app2interp(_setup,'setup') + +def _teardown(saved_modules): + import sys + sys.path.pop() + sys.modules.clear() + sys.modules.update(saved_modules) + +_teardown = gateway.app2interp(_teardown,'teardown') + +class TestImport(testit.AppTestCase): def setUp(self): # interpreter-level - self.space = testit.new_objspace() - dn = os.path.abspath(os.path.join(os.path.dirname(__file__), 'impsubdir')) - self.olddir = os.getcwd() - os.chdir(dn) + testit.AppTestCase.setUp(self) + self.saved_modules = _setup(self.space) def tearDown(self): # interpreter-level - os.chdir(self.olddir) + _teardown(self.space,self.saved_modules) + + def test_import_bare_dir_fails(self): + def imp(): + import notapackage + self.assertRaises(ImportError,imp) def test_import_sys(self): import sys @@ -29,6 +41,13 @@ import a self.assertEquals(a, sys.modules.get('a')) + def test_import_a_cache(self): + import sys + import a + a0 = a + import a + self.assertEquals(a, a0) + def test_import_pkg(self): import sys import pkg @@ -40,6 +59,17 @@ self.assertEquals(pkg, sys.modules.get('pkg')) self.assertEquals(pkg.a, sys.modules.get('pkg.a')) + def test_import_dotted_cache(self): + import sys + import pkg.a + self.assertEquals(pkg, sys.modules.get('pkg')) + self.assertEquals(pkg.a, sys.modules.get('pkg.a')) + pkg0 = pkg + pkg_a0 = pkg.a + import pkg.a + self.assertEquals(pkg, pkg0) + self.assertEquals(pkg.a, pkg_a0) + def test_import_dotted2(self): import sys import pkg.pkg1.a @@ -79,6 +109,32 @@ def test_import_relative(self): from pkg import relative_a self.assertEquals(relative_a.a.inpackage,1) + + def test_import_relative_back_to_absolute(self): + from pkg import abs_b + self.assertEquals(abs_b.b.inpackage,0) + import sys + self.assertEquals(sys.modules.get('pkg.b'),None) + + def test_import_pkg_relative(self): + import pkg_relative_a + self.assertEquals(pkg_relative_a.a.inpackage,1) + + def test_import_relative_partial_success(self): + def imp(): + import pkg_r.inpkg + self.assertRaises(ImportError,imp) + + def test_import_relative_back_to_absolute2(self): + from pkg import abs_x_y + import sys + self.assertEquals(abs_x_y.x.__name__,'x') + self.assertEquals(abs_x_y.x.y.__name__,'x.y') + # grrr + self.assertEquals(sys.modules.get('pkg.x'),None) + self.assert_('pkg.x.y' not in sys.modules) + + if __name__ == '__main__': testit.main() From pedronis at codespeak.net Tue Jun 1 11:03:01 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 1 Jun 2004 11:03:01 +0200 (MEST) Subject: [pypy-svn] r4792 - pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x Message-ID: <20040601090301.922AC5BFCC@thoth.codespeak.net> Author: pedronis Date: Tue Jun 1 11:03:00 2004 New Revision: 4792 Removed: pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.pyc Log: removing spurious .pyc file Deleted: /pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.pyc ============================================================================== Binary file. No diff available. From hpk at codespeak.net Tue Jun 1 11:13:14 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 11:13:14 +0200 (MEST) Subject: [pypy-svn] r4793 - pypy/trunk/src/pypy/module/test Message-ID: <20040601091314.7B1A25BFCD@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 11:13:13 2004 New Revision: 4793 Modified: pypy/trunk/src/pypy/module/test/test_import.py Log: disabled unneeded import details in the test (for now) 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 Tue Jun 1 11:13:13 2004 @@ -130,9 +130,9 @@ import sys self.assertEquals(abs_x_y.x.__name__,'x') self.assertEquals(abs_x_y.x.y.__name__,'x.y') - # grrr - self.assertEquals(sys.modules.get('pkg.x'),None) - self.assert_('pkg.x.y' not in sys.modules) + # grrr XXX not needed probably... + #self.assertEquals(sys.modules.get('pkg.x'),None) + #self.assert_('pkg.x.y' not in sys.modules) From arigo at codespeak.net Tue Jun 1 11:37:16 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 1 Jun 2004 11:37:16 +0200 (MEST) Subject: [pypy-svn] r4794 - pypy/trunk/src/pypy/interpreter Message-ID: <20040601093716.913ED5BFCA@thoth.codespeak.net> Author: arigo Date: Tue Jun 1 11:37:15 2004 New Revision: 4794 Modified: pypy/trunk/src/pypy/interpreter/error.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/py.py Log: Trying to run py.py -S py.py Modified: pypy/trunk/src/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/error.py (original) +++ pypy/trunk/src/pypy/interpreter/error.py Tue Jun 1 11:37:15 2004 @@ -162,11 +162,12 @@ self.file.write('\n') # installing the excepthook for OperationErrors -def operr_excepthook(exctype, value, traceback): - if issubclass(exctype, OperationError): - value.debug_tbs.append(traceback) - value.print_detailed_traceback() - else: - old_excepthook(exctype, value, traceback) -old_excepthook = sys.excepthook -sys.excepthook = operr_excepthook +if hasattr(sys, 'excepthook'): # not implemented on PyPy + def operr_excepthook(exctype, value, traceback): + if issubclass(exctype, OperationError): + value.debug_tbs.append(traceback) + value.print_detailed_traceback() + else: + old_excepthook(exctype, value, traceback) + old_excepthook = sys.excepthook + sys.excepthook = operr_excepthook Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Tue Jun 1 11:37:15 2004 @@ -11,7 +11,10 @@ """ import types -from weakref import WeakKeyDictionary +try: + from weakref import WeakKeyDictionary +except ImportError: + WeakKeyDictionary = dict # XXX for PyPy from pypy.interpreter import eval, pycode from pypy.interpreter.baseobjspace import Wrappable, ObjSpace from pypy.interpreter.function import Function, Method Modified: pypy/trunk/src/pypy/interpreter/py.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/py.py (original) +++ pypy/trunk/src/pypy/interpreter/py.py Tue Jun 1 11:37:15 2004 @@ -1,6 +1,10 @@ #!/usr/bin/env python -import autopath +try: + import autopath +except ImportError: + pass + from pypy.tool import option from pypy.tool.optik import make_option from pypy.interpreter import main, interactive, baseobjspace, error From hpk at codespeak.net Tue Jun 1 12:23:11 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 12:23:11 +0200 (MEST) Subject: [pypy-svn] r4795 - in pypy/trunk/src/pypy/appspace: . test Message-ID: <20040601102311.856015BFCA@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 12:23:10 2004 New Revision: 4795 Modified: pypy/trunk/src/pypy/appspace/complexobject.py pypy/trunk/src/pypy/appspace/test/test_complexobject.py Log: make the 'complex' class be self-contained to copy/paste it into __builtin__ soon Modified: pypy/trunk/src/pypy/appspace/complexobject.py ============================================================================== --- pypy/trunk/src/pypy/appspace/complexobject.py (original) +++ pypy/trunk/src/pypy/appspace/complexobject.py Tue Jun 1 12:23:10 2004 @@ -1,29 +1,21 @@ -import re -import math -import types -import warnings - - -PREC_REPR = 0 # 17 -PREC_STR = 0 # 12 - - 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 type(real) == types.StringType and imag is not 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 type(imag) == types.StringType: + if isinstance(imag, str): msg = "complex() second arg can't be a string" raise TypeError, msg - if type(real) in types.StringTypes: + if isinstance(real, str): real, imag = self._makeComplexFromString(real) self.__dict__['real'] = real self.__dict__['imag'] = imag @@ -38,10 +30,10 @@ if name in ('real', 'imag'): raise TypeError, "readonly attribute" else: - self.__dict__[name] = value - + 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() @@ -65,11 +57,11 @@ def __repr__(self): - return self.__description(PREC_REPR) + return self.__description(self.PREC_REPR) def __str__(self): - return self.__description(PREC_STR) + return self.__description(self.PREC_STR) def __hash__(self): @@ -155,6 +147,7 @@ def __mod__(self, other): + import warnings, math warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning) if other.real == 0. and other.imag == 0.: @@ -171,6 +164,7 @@ def __divmod__(self, other): + import warnings, math warnings.warn("complex divmod(), // and % are deprecated", DeprecationWarning) if other.real == 0. and other.imag == 0.: @@ -183,6 +177,7 @@ def __pow__(self, other): + import math if other.__class__ != complex: other = complex(other, 0) @@ -217,6 +212,7 @@ def __abs__(self): + import math result = math.hypot(self.real, self.imag) return float(result) @@ -228,24 +224,23 @@ def __coerce__(self, other): typ = type(other) - if typ is types.IntType: + if typ is int: return self, complex(float(other)) - elif typ is types.LongType: + elif typ is long: return self, complex(float(other)) - elif typ is types.FloatType: + elif typ is float: return self, complex(other) elif other.__class__ == complex: return self, other - elif typ is types.ComplexType: # cough + elif typ is complex: return self, complex(other.real, other.imag) - raise TypeError, "number coercion failed" + 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 Modified: pypy/trunk/src/pypy/appspace/test/test_complexobject.py ============================================================================== --- pypy/trunk/src/pypy/appspace/test/test_complexobject.py (original) +++ pypy/trunk/src/pypy/appspace/test/test_complexobject.py Tue Jun 1 12:23:10 2004 @@ -1,5 +1,13 @@ #!/usr/bin/env python +""" + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +Note that this test currently runs at cpython-level and not +at any application level .... + +""" #taken from CPython 2.3 (?) """ @@ -24,7 +32,7 @@ try: unicode - have_unicode = 1 + have_unicode = 0 # pypy doesn't have unicode, we know it ... except NameError: have_unicode = 0 @@ -179,7 +187,7 @@ self.assertAEqual(+zc, +zp) self.assertAEqual(abs(zc), abs(zp)) self.assertAEqual(zc, zp) - self.assertEqual(zc.conjugate(), zp.conjugate()) + #self.assertEqual(zc.conjugate(), zp.conjugate()) XXX self.assertEqual(str(zc), str(zp)) self.assertEqual(hash(zc), hash(zp)) @@ -243,4 +251,4 @@ self.assertAEqual(pc, pp) if __name__ == "__main__": - unittest.main() + testit.main() From hpk at codespeak.net Tue Jun 1 12:59:18 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 12:59:18 +0200 (MEST) Subject: [pypy-svn] r4796 - pypy/trunk/src/pypy/module Message-ID: <20040601105918.BD8B25BFCD@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 12:59:18 2004 New Revision: 4796 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: pasted 'class complex' from appspace/complexobject.py into the builtins. 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 Tue Jun 1 12:59:18 2004 @@ -572,6 +572,361 @@ return x raise AttributeError, attr +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... # ________________________________________________________________________ ## def app___import__(*args): From hpk at codespeak.net Tue Jun 1 12:59:36 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 12:59:36 +0200 (MEST) Subject: [pypy-svn] r4797 - in pypy/trunk/src/pypy/module: . test Message-ID: <20040601105936.A59855BFCE@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 12:59:36 2004 New Revision: 4797 Modified: pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/test/test_import.py Log: fixed a problem with default arguments of __import__ 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 Tue Jun 1 12:59:36 2004 @@ -90,11 +90,12 @@ space.wrap("__import__() argument 1 must be string" + helper)) w = space.wrap - ctxt_w_name = None - ctxt_w_path = None - if w_globals is not None: + if w_globals is not None and not space.is_true(space.is_(w_globals, space.w_None)): ctxt_w_name = try_getitem(w_globals,w('__name__')) ctxt_w_path = try_getitem(w_globals,w('__path__')) + else: + ctxt_w_name = None + ctxt_w_path = None rel_modulename = None if ctxt_w_name is not None: 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 Tue Jun 1 12:59:36 2004 @@ -125,6 +125,13 @@ import pkg_r.inpkg self.assertRaises(ImportError,imp) + def test_import_Globals_Are_None(self): + import sys + m = __import__('sys') + self.assertEquals(sys, m) + n = __import__('sys', None, None, ['']) + self.assertEquals(sys, n) + def test_import_relative_back_to_absolute2(self): from pkg import abs_x_y import sys From hpk at codespeak.net Tue Jun 1 13:20:48 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 13:20:48 +0200 (MEST) Subject: [pypy-svn] r4798 - pypy/trunk/src/pypy/module Message-ID: <20040601112048.E22535BFD0@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 13:20:48 2004 New Revision: 4798 Modified: pypy/trunk/src/pypy/module/sysinterp.py Log: add operator module to the builtin modules Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Tue Jun 1 13:20:48 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', + 'cStringIO', 'itertools', 'math', 'operator', '_random', '_sre', 'time', 'imp', '_socket', 'errno', 'marshal', 'struct', 'binascii']: if fn not in builtin_modules: From hpk at codespeak.net Tue Jun 1 14:41:43 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 14:41:43 +0200 (MEST) Subject: [pypy-svn] r4802 - in pypy/trunk/src/pypy: . appspace appspace/test Message-ID: <20040601124143.3A66E5BE09@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 14:41:42 2004 New Revision: 4802 Added: pypy/trunk/src/pypy/appspace/exceptions.py pypy/trunk/src/pypy/appspace/test/test_exceptions.py Modified: pypy/trunk/src/pypy/TODO Log: added exceptions-module that just assign all builtin exceptions to the exceptions's module namespace. a test to just import that added String Formatting to the TODO list! Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Tue Jun 1 14:41:42 2004 @@ -1,4 +1,11 @@ -* Provide an importer that can import packages. +* String Formatting: the % mod operator needs to be implemented + for dicts and the current hack for tuples (which just unwraps + to cpython and calls the % operator) needs to be properly + written at interp- or app-level. + +* Provide an importer that can import packages. (we have a + limited __import__ builtin defined) + Consider PEP 302, new import hooks. Try to write as much as possible in app-level. How would PyPy import CPython extensions? Added: pypy/trunk/src/pypy/appspace/exceptions.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/exceptions.py Tue Jun 1 14:41:42 2004 @@ -0,0 +1,14 @@ + + +def _genex(): + glob = globals() + import __builtin__ + for name, value in __builtin__.__dict__.items(): + try: + if issubclass(value, Exception): + glob[name] = value + except TypeError: + pass + +_genex() +del _genex Added: pypy/trunk/src/pypy/appspace/test/test_exceptions.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/test/test_exceptions.py Tue Jun 1 14:41:42 2004 @@ -0,0 +1,10 @@ +import autopath +from pypy.tool import testit + +class A(testit.AppTestCase): + def test_import(self): + import exceptions + assert exceptions.SyntaxError is SyntaxError + +if __name__ == '__main__': + testit.main() From hpk at codespeak.net Tue Jun 1 14:43:08 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 14:43:08 +0200 (MEST) Subject: [pypy-svn] r4803 - pypy/trunk/src/pypy/appspace Message-ID: <20040601124308.572CF5BE4C@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 14:43:07 2004 New Revision: 4803 Modified: pypy/trunk/src/pypy/appspace/exceptions.py Log: *really* just store the builtin exceptions into exceptions ... Modified: pypy/trunk/src/pypy/appspace/exceptions.py ============================================================================== --- pypy/trunk/src/pypy/appspace/exceptions.py (original) +++ pypy/trunk/src/pypy/appspace/exceptions.py Tue Jun 1 14:43:07 2004 @@ -1,14 +1,43 @@ - - -def _genex(): - glob = globals() - import __builtin__ - for name, value in __builtin__.__dict__.items(): - try: - if issubclass(value, Exception): - glob[name] = value - except TypeError: - pass - -_genex() -del _genex +ArithmeticError = ArithmeticError +AssertionError = AssertionError +AttributeError = AttributeError +DeprecationWarning = DeprecationWarning +EOFError = EOFError +EnvironmentError = EnvironmentError +Exception = Exception +FloatingPointError = FloatingPointError +FutureWarning = FutureWarning +IOError = IOError +ImportError = ImportError +IndentationError = IndentationError +IndexError = IndexError +KeyError = KeyError +KeyboardInterrupt = KeyboardInterrupt +LookupError = LookupError +MemoryError = MemoryError +NameError = NameError +NotImplementedError = NotImplementedError +OSError = OSError +OverflowError = OverflowError +OverflowWarning = OverflowWarning +PendingDeprecationWarning = PendingDeprecationWarning +ReferenceError = ReferenceError +RuntimeError = RuntimeError +RuntimeWarning = RuntimeWarning +StandardError = StandardError +StopIteration = StopIteration +SyntaxError = SyntaxError +SyntaxWarning = SyntaxWarning +SystemError = SystemError +SystemExit = SystemExit +TabError = TabError +TypeError = TypeError +UnboundLocalError = UnboundLocalError +UnicodeDecodeError = UnicodeDecodeError +UnicodeEncodeError = UnicodeEncodeError +UnicodeError = UnicodeError +UnicodeTranslateError = UnicodeTranslateError +UserWarning = UserWarning +ValueError = ValueError +Warning = Warning +ZeroDivisionError = ZeroDivisionError From hpk at codespeak.net Tue Jun 1 15:01:57 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 15:01:57 +0200 (MEST) Subject: [pypy-svn] r4804 - pypy/trunk/src/pypy/objspace Message-ID: <20040601130157.232FE5BE07@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 15:01:56 2004 New Revision: 4804 Modified: pypy/trunk/src/pypy/objspace/trivial.py Log: only export non-underscore names as exceptions Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Tue Jun 1 15:01:56 2004 @@ -91,6 +91,8 @@ # connections we have go in the inconvenient direction... for k in dir(exceptions): + if k.startswith('_'): + continue if k not in done: v = getattr(exceptions, k) if isinstance(v, str): From hpk at codespeak.net Tue Jun 1 15:50:12 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 15:50:12 +0200 (MEST) Subject: [pypy-svn] r4805 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040601135012.D83165BE07@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 15:50:12 2004 New Revision: 4805 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py Log: beginnings of 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 Tue Jun 1 15:50:12 2004 @@ -940,8 +940,15 @@ def mod__String_ANY(space, w_str, w_item): return mod_str_tuple(space, w_str, space.newtuple([w_item])) -def mod__String_Tuple(space, w_str, w_tuple): - return mod_str_tuple(space, w_str, w_tuple) +def mod__String_ANY(space, w_str, w_tuple): + return mod_str_tuple(space, w_str, w_tuple) + +#def app_mod__String_Tuple(format, values): +# l = list(values) +# l.reverse() +# for formatchars = list(format) + +#mod__String_Tuple = gateway.app2interp(app_mod__String_Tuple) # register all methods register_all(vars(), W_StringType) From pedronis at codespeak.net Tue Jun 1 16:11:36 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 1 Jun 2004 16:11:36 +0200 (MEST) Subject: [pypy-svn] r4806 - in pypy/trunk/src/pypy: interpreter module module/test Message-ID: <20040601141136.7D3685BE09@thoth.codespeak.net> Author: pedronis Date: Tue Jun 1 16:11:35 2004 New Revision: 4806 Added: pypy/trunk/src/pypy/interpreter/pytraceback.py Modified: pypy/trunk/src/pypy/interpreter/error.py pypy/trunk/src/pypy/interpreter/interactive.py pypy/trunk/src/pypy/interpreter/pyframe.py pypy/trunk/src/pypy/module/sysinterp.py pypy/trunk/src/pypy/module/sysmodule.py pypy/trunk/src/pypy/module/test/test_sysmodule.py Log: added traceback objects and sys.exc_info support Modified: pypy/trunk/src/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/error.py (original) +++ pypy/trunk/src/pypy/interpreter/error.py Tue Jun 1 16:11:35 2004 @@ -23,12 +23,9 @@ def __init__(self, w_type, w_value): self.w_type = w_type self.w_value = w_value - self.application_traceback = [] + self.application_traceback = None self.debug_tbs = [] - def record_application_traceback(self, frame, last_instruction): - self.application_traceback.append((frame, last_instruction)) - def match(self, space, w_check_class): "Check if this application-level exception matches 'w_check_class'." return space.exception_match(self.w_type, w_check_class) @@ -47,8 +44,7 @@ def getframe(self): "The frame this exception was raised in, or None." if self.application_traceback: - frame, last_instruction = self.application_traceback[0] - return frame + return self.application_traceback.frame else: return None @@ -65,14 +61,13 @@ print >> file, self.errorstr(space) def print_app_tb_only(self, file): - tb = self.application_traceback[:] + tb = self.application_traceback if tb: import linecache - tb.reverse() print >> file, "Traceback (application-level):" - for f, i in tb: - co = f.code - lineno = offset2lineno(co, i) + while tb is not None: + co = tb.frame.code + lineno = tb.lineno fname = co.co_filename if fname.startswith('\n'): lines = fname.split('\n') @@ -89,6 +84,7 @@ if l.endswith('\n'): l = l[:-1] print >> file, l + tb = tb.next def print_detailed_traceback(self, space=None, file=None): """Dump a nice detailed interpreter- and application-level traceback, @@ -131,17 +127,6 @@ return compile(w(source), w('\n%s'%source), w(symbol), w(0), w(0)) -def offset2lineno(c, stopat): - tab = c.co_lnotab - line = c.co_firstlineno - addr = 0 - for i in range(0, len(tab), 2): - addr = addr + ord(tab[i]) - if addr > stopat: - break - line = line + ord(tab[i+1]) - return line - class LinePrefixer: """File-like class that inserts a prefix string at the beginning of each line it prints.""" Modified: pypy/trunk/src/pypy/interpreter/interactive.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/interactive.py (original) +++ pypy/trunk/src/pypy/interpreter/interactive.py Tue Jun 1 16:11:35 2004 @@ -6,17 +6,6 @@ import linecache -def offset2lineno(c, stopat): - tab = c.co_lnotab - line = c.co_firstlineno - addr = 0 - for i in range(0, len(tab), 2): - addr = addr + ord(tab[i]) - if addr > stopat: - break - line = line + ord(tab[i+1]) - return line - class PyPyConsole(code.InteractiveConsole): def __init__(self, objspace): code.InteractiveConsole.__init__(self) Modified: pypy/trunk/src/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/src/pypy/interpreter/pyframe.py Tue Jun 1 16:11:35 2004 @@ -4,6 +4,7 @@ from pypy.interpreter import eval, baseobjspace, gateway from pypy.interpreter.miscutils import Stack from pypy.interpreter.error import OperationError +from pypy.interpreter import pytraceback class PyFrame(eval.Frame, baseobjspace.Wrappable): @@ -50,7 +51,8 @@ except OperationError, e: #import traceback #traceback.print_exc() - e.record_application_traceback(self, last_instr) + pytraceback.record_application_traceback( + self.space, e, self, last_instr) self.last_exception = e executioncontext.exception_trace(e) # convert an OperationError into a control flow Added: pypy/trunk/src/pypy/interpreter/pytraceback.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/interpreter/pytraceback.py Tue Jun 1 16:11:35 2004 @@ -0,0 +1,49 @@ +from pypy.interpreter import baseobjspace + + +class PyTraceback(baseobjspace.Wrappable): + """Traceback object + + Public fields: + * 'tb_frame' + * 'tb_lasti' + * 'tb_lineno' + * 'tb_next' + """ + + def __init__(self, space, frame, lasti, lineno, next): + self.space = space + self.frame = frame + self.lasti = lasti + self.lineno = lineno + self.next = next + + ### application level visible attributes ### + def app_visible(self): + def makedict(**kw): return kw + space = self.space + d = makedict( + tb_frame = space.wrap(self.frame), + tb_lasti = space.wrap(self.lasti), + tb_lineno = space.wrap(self.lineno), + tb_next = space.wrap(self.next), + ) + return d.items() + + +def record_application_traceback(space, operror, frame, last_instruction): + lineno = offset2lineno(frame.code, last_instruction) + tb = operror.application_traceback + tb = PyTraceback(space, frame, last_instruction, lineno, tb) + operror.application_traceback = tb + +def offset2lineno(c, stopat): + tab = c.co_lnotab + line = c.co_firstlineno + addr = 0 + for i in range(0, len(tab), 2): + addr = addr + ord(tab[i]) + if addr > stopat: + break + line = line + ord(tab[i+1]) + return line Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Tue Jun 1 16:11:35 2004 @@ -104,3 +104,12 @@ # XXX No Argument Accepted Yet f = space.getexecutioncontext().framestack.items[-1] return space.wrap(f) + +def exc_info(): + operror = space.getexecutioncontext().sys_exc_info() + if operror is None: + return space.newtuple([space.w_None,space.w_None,space.w_None]) + else: + return space.newtuple([operror.w_type,operror.w_value, + space.wrap(operror.application_traceback)]) + Modified: pypy/trunk/src/pypy/module/sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/sysmodule.py (original) +++ pypy/trunk/src/pypy/module/sysmodule.py Tue Jun 1 16:11:35 2004 @@ -13,7 +13,7 @@ from __interplevel__ import hexversion, platform # Functions from interpreter-level -from __interplevel__ import displayhook, _getframe +from __interplevel__ import displayhook, _getframe, exc_info # Dummy executable = '' Modified: pypy/trunk/src/pypy/module/test/test_sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/test/test_sysmodule.py (original) +++ pypy/trunk/src/pypy/module/test/test_sysmodule.py Tue Jun 1 16:11:35 2004 @@ -65,6 +65,23 @@ self.failUnless('__builtin__' in names, "__builtin__ is not listed as a builtin module.") + def test_sys_exc_info(self): + try: + raise Exception + except Exception,e: + import sys + exc_type,exc_val,tb = sys.exc_info() + try: + raise Exception # 5 lines below the previous one + except Exception,e2: + exc_type2,exc_val2,tb2 = sys.exc_info() + self.assertEquals(exc_type,Exception) + self.assertEquals(exc_val,e) + self.assertEquals(exc_type2,Exception) + self.assertEquals(exc_val2,e2) + self.assertEquals(tb2.tb_lineno - tb.tb_lineno, 5) + + if __name__ == '__main__': testit.main() From hpk at codespeak.net Tue Jun 1 16:12:12 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 16:12:12 +0200 (MEST) Subject: [pypy-svn] r4807 - pypy/trunk/src/pypy/interpreter Message-ID: <20040601141212.586925BE4C@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 16:12:11 2004 New Revision: 4807 Modified: pypy/trunk/src/pypy/interpreter/py.py (props changed) Log: set exec on py.py From alex at codespeak.net Tue Jun 1 16:15:49 2004 From: alex at codespeak.net (alex at codespeak.net) Date: Tue, 1 Jun 2004 16:15:49 +0200 (MEST) Subject: [pypy-svn] r4808 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040601141549.E68515BE77@thoth.codespeak.net> Author: alex Date: Tue Jun 1 16:15:49 2004 New Revision: 4808 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringobject.py Log: a first dim beginning of 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 Tue Jun 1 16:15:49 2004 @@ -938,17 +938,47 @@ return space.wrap(ord(space.unwrap(w_str))) def mod__String_ANY(space, w_str, w_item): - return mod_str_tuple(space, w_str, space.newtuple([w_item])) + return mod__String_Tuple(space, w_str, space.newtuple([w_item])) -def mod__String_ANY(space, w_str, w_tuple): - return mod_str_tuple(space, w_str, w_tuple) +def app_mod__String_Tuple(format, values): + l = list(values) + l.reverse() + pieces = [] + start = 0 + state = 0 + for i in range(len(format)): + c = format[i] + if state == 0: + """ just copy constant-pieces of the format """ + if c!='%': + continue + pieces.append(format[start:i]) + state = 1 + else: + if c=='%': + pieces.append('%') + elif c=='s': + pieces.append(str(l.pop())) + elif c=='d': + pieces.append(str(int(l.pop()))) + elif c=='x': + pieces.append(hex(int(l.pop()))) + elif c=='r': + pieces.append(repr(l.pop())) + else: + raise ValueError, "unsupported format character '%s' (%x) at index %d" % ( + c, ord(c), i) + state = 0 + start = i+1 -#def app_mod__String_Tuple(format, values): -# l = list(values) -# l.reverse() -# for formatchars = list(format) + if state == 1: + raise ValueError, "incomplete format" -#mod__String_Tuple = gateway.app2interp(app_mod__String_Tuple) + pieces.append(format[start:]) + return ''.join(pieces) + + +mod__String_Tuple = gateway.app2interp(app_mod__String_Tuple) # register all methods register_all(vars(), W_StringType) 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 Jun 1 16:15:49 2004 @@ -118,6 +118,9 @@ def setUp(self): self.space = testit.objspace('std') + def test_format_wrongchar(self): + self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) + def test_split(self): self.assertEquals("".split(), []) self.assertEquals("a".split(), ['a']) From alex at codespeak.net Tue Jun 1 16:21:44 2004 From: alex at codespeak.net (alex at codespeak.net) Date: Tue, 1 Jun 2004 16:21:44 +0200 (MEST) Subject: [pypy-svn] r4809 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040601142144.3082B5BFCA@thoth.codespeak.net> Author: alex Date: Tue Jun 1 16:21:43 2004 New Revision: 4809 Added: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: a start for more, better tests of string formatting Added: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Tue Jun 1 16:21:43 2004 @@ -0,0 +1,25 @@ +import autopath +from pypy.tool import testit + + +class TestStringObject(testit.AppTestCase): + + def setUp(self): + self.space = testit.objspace('std') + + def test_format_item(self): + self.assertEquals('a23b', 'a%sb' % 23) + self.assertEquals('23b', '%sb' % 23) + self.assertEquals('a23', 'a%s' % 23) + self.assertEquals('23', '%s' % 23) + self.assertEquals('a%b', 'a%%b' % ()) + self.assertEquals('%b', '%%b' % ()) + self.assertEquals('a%', 'a%%' % ()) + self.assertEquals('%', '%%' % ()) + + def test_format_wrongchar(self): + self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) + + +if __name__ == '__main__': + testit.main() From alex at codespeak.net Tue Jun 1 16:30:04 2004 From: alex at codespeak.net (alex at codespeak.net) Date: Tue, 1 Jun 2004 16:30:04 +0200 (MEST) Subject: [pypy-svn] r4810 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040601143004.1B5015BFCB@thoth.codespeak.net> Author: alex Date: Tue Jun 1 16:30:03 2004 New Revision: 4810 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: better errors for too many or too few %'s 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 Jun 1 16:30:03 2004 @@ -955,24 +955,29 @@ pieces.append(format[start:i]) state = 1 else: - if c=='%': - pieces.append('%') - elif c=='s': - pieces.append(str(l.pop())) - elif c=='d': - pieces.append(str(int(l.pop()))) - elif c=='x': - pieces.append(hex(int(l.pop()))) - elif c=='r': - pieces.append(repr(l.pop())) - else: - raise ValueError, "unsupported format character '%s' (%x) at index %d" % ( - c, ord(c), i) + try: + if c=='%': + pieces.append('%') + elif c=='s': + pieces.append(str(l.pop())) + elif c=='d': + pieces.append(str(int(l.pop()))) + elif c=='x': + pieces.append(hex(int(l.pop()))) + elif c=='r': + pieces.append(repr(l.pop())) + else: + raise ValueError, "unsupported format character '%s' (%x) at index %d" % ( + c, ord(c), i) + except IndexError: + raise TypeError, 'not enough arguments for format string' state = 0 start = i+1 if state == 1: raise ValueError, "incomplete format" + if l: + raise TypeError, 'not all arguments converted during string formatting' pieces.append(format[start:]) return ''.join(pieces) 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 Jun 1 16:30:03 2004 @@ -17,6 +17,12 @@ self.assertEquals('a%', 'a%%' % ()) self.assertEquals('%', '%%' % ()) + def test_format_wronglength(self): + self.assertRaises(TypeError, '%s%s'.__mod__, ()) + self.assertRaises(TypeError, '%s%s'.__mod__, (23,)) + self.assertRaises(TypeError, '%s%s'.__mod__, (23,)*3) + self.assertRaises(TypeError, '%s%s'.__mod__, (23,)*4) + def test_format_wrongchar(self): self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) From alex at codespeak.net Tue Jun 1 16:42:23 2004 From: alex at codespeak.net (alex at codespeak.net) Date: Tue, 1 Jun 2004 16:42:23 +0200 (MEST) Subject: [pypy-svn] r4811 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040601144223.EAC285BE4C@thoth.codespeak.net> Author: alex Date: Tue Jun 1 16:42:23 2004 New Revision: 4811 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: more and more tests 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 Jun 1 16:42:23 2004 @@ -23,6 +23,23 @@ self.assertRaises(TypeError, '%s%s'.__mod__, (23,)*3) self.assertRaises(TypeError, '%s%s'.__mod__, (23,)*4) + def test_format_kinds(self): + self.assertEquals('23', '%s' % '23') + self.assertEquals("'23'", '%r' % '23') + """ unclear behavior requirement, so commented for now...: + self.assertEquals('23', '%d' % '23') ...or...: + self.assertRaises(TypeError, '%d'.__mod__, ((23,),)) ...? + """ + self.assertEquals('23', '%d' % 23.456) + self.assertEquals('0x17', '%x' % 23.456) + self.assertEquals('23.456', '%s' % 23.456) + 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) + def test_format_wrongchar(self): self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) From pedronis at codespeak.net Tue Jun 1 17:41:27 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 1 Jun 2004 17:41:27 +0200 (MEST) Subject: [pypy-svn] r4812 - in pypy/trunk/src/pypy/interpreter: . test Message-ID: <20040601154127.E383D5BE07@thoth.codespeak.net> Author: pedronis Date: Tue Jun 1 17:41:27 2004 New Revision: 4812 Modified: pypy/trunk/src/pypy/interpreter/error.py pypy/trunk/src/pypy/interpreter/pyframe.py pypy/trunk/src/pypy/interpreter/pyopcode.py pypy/trunk/src/pypy/interpreter/test/test_interpreter.py Log: added 3 args raise and re-raise support Modified: pypy/trunk/src/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/error.py (original) +++ pypy/trunk/src/pypy/interpreter/error.py Tue Jun 1 17:41:27 2004 @@ -20,10 +20,10 @@ (frame, instruction_position) making the application-level traceback. """ - def __init__(self, w_type, w_value): + def __init__(self, w_type, w_value, tb=None): self.w_type = w_type self.w_value = w_value - self.application_traceback = None + self.application_traceback = tb self.debug_tbs = [] def match(self, space, w_check_class): Modified: pypy/trunk/src/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/src/pypy/interpreter/pyframe.py Tue Jun 1 17:41:27 2004 @@ -49,12 +49,8 @@ # dispatch() is abstract, see pyopcode. self.dispatch() except OperationError, e: - #import traceback - #traceback.print_exc() pytraceback.record_application_traceback( self.space, e, self, last_instr) - self.last_exception = e - executioncontext.exception_trace(e) # convert an OperationError into a control flow # exception import sys @@ -263,10 +259,23 @@ class SApplicationException(ControlFlowException): """Unroll the stack because of an application-level exception (i.e. an OperationException).""" + + def action(self, frame, last_instr, executioncontext): + e = self.args[0] + frame.last_exception = e + executioncontext.exception_trace(e) + + ControlFlowException.action(self, frame, + last_instr, executioncontext) + def emptystack(self, frame): # propagate the exception to the caller - operationerr, tb = self.args - raise operationerr.__class__, operationerr, tb + if len(self.args) == 2: + operationerr, tb = self.args + raise operationerr.__class__, operationerr, tb + else: + operationerr = self.args[0] + raise operationerr class SBreakLoop(ControlFlowException): """Signals a 'break' statement.""" Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Tue Jun 1 17:41:27 2004 @@ -6,7 +6,8 @@ from pypy.interpreter.baseobjspace import OperationError, NoValue from pypy.interpreter.eval import UNDEFINED -from pypy.interpreter import baseobjspace, pyframe, gateway, function +from pypy.interpreter import baseobjspace, gateway, function +from pypy.interpreter import pyframe, pytraceback from pypy.interpreter.miscutils import InitializedClass @@ -302,8 +303,17 @@ if nbargs >= 1: w_type = f.valuestack.pop() w_resulttuple = prepare_raise(f.space, w_type, w_value, w_traceback) w_type, w_value, w_traceback = f.space.unpacktuple(w_resulttuple, 3) - # XXX the three-arguments 'raise' is not supported yet - raise OperationError(w_type, w_value) + tb = f.space.unwrap(w_traceback) + if tb is not None: + if not isinstance(tb,pytraceback.PyTraceback): + raise OperationError(f.space.w_TypeError, + f.space.wrap("raise: arg 3 must be a traceback or None")) + operror = OperationError(w_type,w_value,tb) + # re-raise, no new traceback obj will be attached + raise pyframe.SApplicationException(operror) + else: + # common-case + raise OperationError(w_type, w_value) def LOAD_LOCALS(f): f.valuestack.push(f.w_locals) @@ -850,11 +860,12 @@ value = etype etype = value.__class__ elif isinstance(etype, type) and issubclass(etype, Exception): - if value is None: - value = () - elif not isinstance(value, tuple): - value = (value,) - value = etype(*value) + if not isinstance(value,etype): + if value is None: + value = () + elif not isinstance(value, tuple): + value = (value,) + value = etype(*value) else: raise TypeError("exceptions must be instances or subclasses of " "Exception or strings (deprecated), not %s" % Modified: pypy/trunk/src/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_interpreter.py Tue Jun 1 17:41:27 2004 @@ -185,6 +185,20 @@ else: self.fail("shouldn't be able to raise 1") + def test_raise_three_args(self): + import sys + try: + raise ValueError + except: + exc_type,exc_val,exc_tb = sys.exc_info() + try: + raise exc_type,exc_val,exc_tb + except: + exc_type2,exc_val2,exc_tb2 = sys.exc_info() + self.assertEquals(exc_type,exc_type2) + self.assertEquals(exc_val,exc_val2) + self.assertEquals(exc_tb,exc_tb2) + def test_trivial_call(self): def f(): return 42 self.assertEquals(f(), 42) From hpk at codespeak.net Tue Jun 1 17:47:41 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 17:47:41 +0200 (MEST) Subject: [pypy-svn] r4813 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040601154741.B6E0B5BE09@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 17:47:40 2004 New Revision: 4813 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: stringformatting with dict and tuples - tests added and pass 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 Jun 1 17:47:40 2004 @@ -940,50 +940,67 @@ def mod__String_ANY(space, w_str, w_item): return mod__String_Tuple(space, w_str, space.newtuple([w_item])) -def app_mod__String_Tuple(format, values): - l = list(values) - l.reverse() +def app_mod__String_ANY(format, values): pieces = [] start = 0 state = 0 - for i in range(len(format)): + 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!='%': - continue - pieces.append(format[start:i]) - state = 1 + # just copy constant-pieces of the format + if c=='%': + pieces.append(format[start:i]) + state = 1 else: - try: - if c=='%': - pieces.append('%') - elif c=='s': - pieces.append(str(l.pop())) + if c=='%': + pieces.append('%') + else: + if c == '(': + # read name + j = format.find(')', i+1) + if j == -1: + raise ValueError, "incomplete format string" + if index != -1: + 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]) + value = values[index] + + if c=='s': + pieces.append(str(value)) elif c=='d': - pieces.append(str(int(l.pop()))) + pieces.append(str(value)) elif c=='x': - pieces.append(hex(int(l.pop()))) + pieces.append(hex(int(value))) elif c=='r': - pieces.append(repr(l.pop())) + pieces.append(repr(value)) else: raise ValueError, "unsupported format character '%s' (%x) at index %d" % ( c, ord(c), i) - except IndexError: - raise TypeError, 'not enough arguments for format string' state = 0 start = i+1 + i += 1 if state == 1: raise ValueError, "incomplete format" - if l: + if index >= 0 and index < len(values) - 1: raise TypeError, 'not all arguments converted during string formatting' - pieces.append(format[start:]) return ''.join(pieces) - -mod__String_Tuple = gateway.app2interp(app_mod__String_Tuple) +mod__String_ANY = gateway.app2interp(app_mod__String_ANY) # register all methods register_all(vars(), W_StringType) 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 Jun 1 17:47:40 2004 @@ -2,6 +2,21 @@ from pypy.tool import testit +class TestStringObjectWithDict(testit.AppTestCase): + + def setUp(self): + self.space = testit.objspace('std') + + def test_format_item(self): + d = {'i': 23, '':42} + self.assertEquals('a23b', 'a%(i)sb' % d) + self.assertEquals('23b', '%(i)sb' % d) + self.assertEquals('a23', 'a%(i)s' % d) + self.assertEquals('23', '%(i)s' % d) + self.assertEquals('a%b', 'a%%b' % d) + self.assertEquals('42', '%()s' % d) + self.assertRaises(ValueError, 'a%()Zb'.__mod__, d) + class TestStringObject(testit.AppTestCase): def setUp(self): @@ -42,6 +57,23 @@ def test_format_wrongchar(self): self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) +class TestStringObject(testit.AppTestCase): + + def setUp(self): + self.space = testit.objspace('std') + + def test_format_item(self): + self.assertEquals('a23b', 'a%sb' % 23) + self.assertEquals('23b', '%sb' % 23) + self.assertEquals('a23', 'a%s' % 23) + self.assertEquals('23', '%s' % 23) + self.assertEquals('a%b', 'a%%b' % ()) + self.assertEquals('%b', '%%b' % ()) + self.assertEquals('a%', 'a%%' % ()) + self.assertEquals('%', '%%' % ()) + + def test_format_wrongchar(self): + self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) if __name__ == '__main__': From hpk at codespeak.net Tue Jun 1 17:51:44 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 1 Jun 2004 17:51:44 +0200 (MEST) Subject: [pypy-svn] r4814 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040601155144.468B55BE09@thoth.codespeak.net> Author: hpk Date: Tue Jun 1 17:51:43 2004 New Revision: 4814 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py Log: small fix 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 Jun 1 17:51:43 2004 @@ -981,7 +981,7 @@ if c=='s': pieces.append(str(value)) elif c=='d': - pieces.append(str(value)) + pieces.append(str(int(value))) elif c=='x': pieces.append(hex(int(value))) elif c=='r': From alex at codespeak.net Tue Jun 1 17:55:33 2004 From: alex at codespeak.net (alex at codespeak.net) Date: Tue, 1 Jun 2004 17:55:33 +0200 (MEST) Subject: [pypy-svn] r4815 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040601155533.783AD5BE09@thoth.codespeak.net> Author: alex Date: Tue Jun 1 17:55:32 2004 New Revision: 4815 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: more minor fixes of stuff that had dropped by the wayside due to some incorrect conflict resolution &c 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 Jun 1 17:55:32 2004 @@ -976,7 +976,10 @@ raise TypeError, "format string mismatch" elif index == 0 and not isinstance(values, tuple): values = tuple([values]) - value = values[index] + try: + value = values[index] + except IndexError: + raise TypeError, "not enough arguments for format string" if c=='s': pieces.append(str(value)) 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 Jun 1 17:55:32 2004 @@ -57,24 +57,6 @@ def test_format_wrongchar(self): self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) -class TestStringObject(testit.AppTestCase): - - def setUp(self): - self.space = testit.objspace('std') - - def test_format_item(self): - self.assertEquals('a23b', 'a%sb' % 23) - self.assertEquals('23b', '%sb' % 23) - self.assertEquals('a23', 'a%s' % 23) - self.assertEquals('23', '%s' % 23) - self.assertEquals('a%b', 'a%%b' % ()) - self.assertEquals('%b', '%%b' % ()) - self.assertEquals('a%', 'a%%' % ()) - self.assertEquals('%', '%%' % ()) - - def test_format_wrongchar(self): - self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) - if __name__ == '__main__': testit.main() From arigo at codespeak.net Wed Jun 2 11:18:22 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 2 Jun 2004 11:18:22 +0200 (MEST) Subject: [pypy-svn] r4817 - in pypy/trunk/src/pypy: annotation translator Message-ID: <20040602091822.677A05BE07@thoth.codespeak.net> Author: arigo Date: Wed Jun 2 11:18:20 2004 New Revision: 4817 Modified: pypy/trunk/src/pypy/annotation/binaryop.py pypy/trunk/src/pypy/annotation/factory.py pypy/trunk/src/pypy/annotation/unaryop.py pypy/trunk/src/pypy/translator/annrpython.py Log: Start some clean-ups and simplifications. A bit more needed in ClassDef.generalize(). Modified: pypy/trunk/src/pypy/annotation/binaryop.py ============================================================================== --- pypy/trunk/src/pypy/annotation/binaryop.py (original) +++ pypy/trunk/src/pypy/annotation/binaryop.py Wed Jun 2 11:18:20 2004 @@ -9,7 +9,7 @@ from pypy.annotation.model import SomeInstance, SomeFunction, SomeMethod from pypy.annotation.model import SomeBuiltin, SomeIterator from pypy.annotation.model import unionof, set, setunion, missing_operation -from pypy.annotation.factory import BlockedInference, getbookkeeper +from pypy.annotation.factory import generalize # XXX unify this with ObjSpace.MethodTable @@ -122,10 +122,7 @@ def setitem((dic1, obj2), s_value): assert obj2.is_constant() key = obj2.const - if key not in dic1.items or not dic1.items[key].contains(s_value): - bookkeeper = getbookkeeper() - for factory in dic1.factories: - factory.generalize(key, s_value, bookkeeper) + generalize(dic1.factories, key, s_value) class __extend__(pairtype(SomeTuple, SomeInteger)): @@ -146,10 +143,7 @@ return lst1.s_item def setitem((lst1, int2), s_value): - if not lst1.s_item.contains(s_value): - bookkeeper = getbookkeeper() - for factory in lst1.factories: - factory.generalize(s_value, bookkeeper) + generalize(lst1.factories, s_value) class __extend__(pairtype(SomeInteger, SomeList)): Modified: pypy/trunk/src/pypy/annotation/factory.py ============================================================================== --- pypy/trunk/src/pypy/annotation/factory.py (original) +++ pypy/trunk/src/pypy/annotation/factory.py Wed Jun 2 11:18:20 2004 @@ -1,9 +1,9 @@ """ Mutable Objects Factories. -A factory is associated to each point in the source that creates a mutable -object. The factory remembers how general an object it has to create here. - +A factory is associated to an SpaceOperation in the source that creates a +mutable object, currently 'newlist' and 'call' (which can build instances). +The factory remembers how general an object it has to create here. """ from __future__ import generators @@ -36,7 +36,7 @@ def __init__(self, annotator): self.annotator = annotator - self.creationpoints = {} # map positions-in-blocks to Factories + self.creationpoints = {} # map position-in-a-block to its Factory self.userclasses = {} # map classes to ClassDefs self.userclasseslist = []# userclasses.keys() in creation order @@ -44,36 +44,25 @@ """Start of an operation. The operation is uniquely identified by the given key.""" self.position_key = position_key - self.choice_id = 0 getthreadlocals().bookkeeper = self def leave(self): """End of an operation.""" del getthreadlocals().bookkeeper del self.position_key - del self.choice_id - - def nextchoice(self): - """Get the next choice key. The keys are unique, but they follow - the same sequence while reflowing.""" - # 'position_key' is an arbitrary key that identifies a specific - # operation, but calling nextchoice() several times during the same - # operation returns a different choice key. - key = self.position_key, self.choice_id - self.choice_id += 1 - return key - def getfactory(self, factorycls, *factoryargs): + def getfactory(self, factorycls): """Get the Factory associated with the current position, - or if it doesn't exist yet build it with factorycls(*factoryargs).""" - key = self.nextchoice() + or build it if it doesn't exist yet.""" try: - return self.creationpoints[key] + factory = self.creationpoints[self.position_key] except KeyError: - factory = factorycls(*factoryargs) + factory = factorycls() + factory.bookkeeper = self factory.position_key = self.position_key - self.creationpoints[key] = factory - return factory + self.creationpoints[self.position_key] = factory + assert isinstance(factory, factorycls) + return factory def getclassdef(self, cls): """Get the ClassDef associated with the given user cls.""" @@ -98,16 +87,26 @@ # Factories # +def generalize(factories, *args): + modified = [factory for factory in factories if factory.generalize(*args)] + if modified: + for factory in modified: + factory.bookkeeper.annotator.reflowfromposition(factory.position_key) + raise BlockedInference # reflow now + + class ListFactory: s_item = SomeImpossibleValue() def create(self): return SomeList(factories = {self: True}, s_item = self.s_item) - def generalize(self, s_new_item, bookkeeper=None): - self.s_item = unionof(self.s_item, s_new_item) - if bookkeeper: - bookkeeper.annotator.reflowfromposition(self.position_key) + def generalize(self, s_new_item): + if not self.s_item.contains(s_new_item): + self.s_item = unionof(self.s_item, s_new_item) + return True + else: + return False class DictFactory: @@ -116,31 +115,30 @@ def create(self): return SomeDict(factories = {self: True}, items = self.items) - def generalize(self, key, s_new_value, bookkeeper=None): - result = self.items.copy() - if key in result: - result[key] = unionof(result[key], s_new_value) + def generalize(self, key, s_new_value): + self.items = self.items.copy() + if key not in self.items: + self.items[key] = s_new_value + return True + elif not self.items[key].contains(s_new_value): + self.items[key] = unionof(self.items[key], s_new_value) + return True else: - result[key] = s_new_value - self.items = result - if bookkeeper: - bookkeeper.annotator.reflowfromposition(self.position_key) + return False class FuncCallFactory: def pycall(self, func, arglist): - return getbookkeeper().annotator.recursivecall(func, arglist, self) + return self.bookkeeper.annotator.recursivecall(func, arglist, self) class InstanceFactory: - def __init__(self, cls): - self.classdef = getbookkeeper().getclassdef(cls) - self.classdef.instancefactories[self] = True - - def create(self): - return SomeInstance(self.classdef) + def create(self, cls): + classdef = self.bookkeeper.getclassdef(cls) + classdef.instancefactories[self] = True + return SomeInstance(classdef) class ClassDef: Modified: pypy/trunk/src/pypy/annotation/unaryop.py ============================================================================== --- pypy/trunk/src/pypy/annotation/unaryop.py (original) +++ pypy/trunk/src/pypy/annotation/unaryop.py Wed Jun 2 11:18:20 2004 @@ -131,8 +131,8 @@ def call(cls, args, kwds): # XXX flow into __init__ - factory = getbookkeeper().getfactory(InstanceFactory, cls.cls) - return factory.create() + factory = getbookkeeper().getfactory(InstanceFactory) + return factory.create(cls.cls) class __extend__(SomeFunction): Modified: pypy/trunk/src/pypy/translator/annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/annrpython.py (original) +++ pypy/trunk/src/pypy/translator/annrpython.py Wed Jun 2 11:18:20 2004 @@ -3,8 +3,7 @@ from types import FunctionType, ClassType from pypy.annotation import model as annmodel from pypy.annotation.model import pair -from pypy.annotation.factory import ListFactory, InstanceFactory -from pypy.annotation.factory import DictFactory +from pypy.annotation.factory import ListFactory, DictFactory from pypy.annotation.factory import BlockedInference, Bookkeeper from pypy.objspace.flow.model import Variable, Constant, UndefinedConstant from pypy.objspace.flow.model import SpaceOperation, FunctionGraph From hpk at codespeak.net Wed Jun 2 14:08:16 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 2 Jun 2004 14:08:16 +0200 (MEST) Subject: [pypy-svn] r4819 - pypy/trunk/src/goal Message-ID: <20040602120816.C621C5BE07@thoth.codespeak.net> Author: hpk Date: Wed Jun 2 14:08:16 2004 New Revision: 4819 Added: pypy/trunk/src/goal/objectspace-reconstruct.py Log: some draft ideas how the object type system and objectspace/interpreter interactions might work Added: pypy/trunk/src/goal/objectspace-reconstruct.py ============================================================================== --- (empty file) +++ pypy/trunk/src/goal/objectspace-reconstruct.py Wed Jun 2 14:08:16 2004 @@ -0,0 +1,40 @@ + +def __getattribute__(w_obj,w_name): + type = space.gettype(w_obj) + name = space.unwrap(w_name) + w_descr = type.lookup(name) + if w_descr is not None: + if space.is_data_descr(w_descr): + return space.get(w_descr,w_obj,space.wrap(type)) + w_dict = space.getdict(w_obj) + if w_dict is not None: + try: + return space.getitem(w_dict,w_name) + except OperationError, e: + if not e.match(space,space.w_KeyError): + raise + if w_descr is not None: + return space.get(w_descr,w_obj,space.wrap(type)) + raise OperationError(space.w_AttributeError,w_name) + +def space.getattr(w_obj,w_name): + type = space.gettype(w_obj) + w_descr = type.lookup('__getattribute__') + w_impl = space.get(w_descr,w_obj, space.wrap(type)) + try: + return space.call_function(w_impl, w_name) + except: # AttributeError + w_descr = type.lookup('__getattr__') + if w_descr is None: + raise + w_impl = space.get(w_descr,w_obj, space.wrap(type)) + return space.call_function(w_descr,w_obj, space.wrap(type)) + +def space.get(w_obj,w_name): + type = space.gettype(w_obj) + w_descr = type.lookup('__get__') + if w_descr is not None: + w_impl = space.get(w_descr,w_obj, space.wrap(type)) + return space.call_function(w_impl, w_name) + else: + return w_obj From alex at codespeak.net Wed Jun 2 14:30:22 2004 From: alex at codespeak.net (alex at codespeak.net) Date: Wed, 2 Jun 2004 14:30:22 +0200 (MEST) Subject: [pypy-svn] r4820 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040602123022.21C9F5BE07@thoth.codespeak.net> Author: alex Date: Wed Jun 2 14:30:21 2004 New Revision: 4820 Modified: pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: more thorough testing of string formatting 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 Wed Jun 2 14:30:21 2004 @@ -5,21 +5,40 @@ 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, '':42} + d = {'i': 23} self.assertEquals('a23b', 'a%(i)sb' % d) self.assertEquals('23b', '%(i)sb' % d) self.assertEquals('a23', 'a%(i)s' % d) self.assertEquals('23', '%(i)s' % d) - self.assertEquals('a%b', 'a%%b' % d) + + def test_format_two_items(self): + d = {'i': 23, 'j': 42} + self.assertEquals('a23b42c', 'a%(i)sb%(j)sc' % d) + self.assertEquals('a23b23c', 'a%(i)sb%(i)sc' % d) + + def test_format_percent(self): + self.assertEquals('a%b', 'a%%b' % {}) + + def test_format_empty_key(self): + d = {'':42} self.assertEquals('42', '%()s' % d) - self.assertRaises(ValueError, 'a%()Zb'.__mod__, d) + + def test_format_wrong_char(self): + d = {'i': 23} + self.assertRaises(ValueError, 'a%(i)Zb'.__mod__, d) + + def test_format_missing(self): + d = {'i': 23} + self.assertRaises(KeyError, 'a%(x)sb'.__mod__, d) class TestStringObject(testit.AppTestCase): def setUp(self): + # force testing to use standard objspace self.space = testit.objspace('std') def test_format_item(self): @@ -27,27 +46,34 @@ self.assertEquals('23b', '%sb' % 23) self.assertEquals('a23', 'a%s' % 23) self.assertEquals('23', '%s' % 23) + + def test_format_percent(self): self.assertEquals('a%b', 'a%%b' % ()) self.assertEquals('%b', '%%b' % ()) self.assertEquals('a%', 'a%%' % ()) self.assertEquals('%', '%%' % ()) - def test_format_wronglength(self): + def test_format_too_much(self): self.assertRaises(TypeError, '%s%s'.__mod__, ()) self.assertRaises(TypeError, '%s%s'.__mod__, (23,)) + + def test_format_not_enough(self): self.assertRaises(TypeError, '%s%s'.__mod__, (23,)*3) self.assertRaises(TypeError, '%s%s'.__mod__, (23,)*4) - def test_format_kinds(self): + def test_format_string(self): self.assertEquals('23', '%s' % '23') self.assertEquals("'23'", '%r' % '23') - """ unclear behavior requirement, so commented for now...: + """ unclear behavior requirement, so, both commented for now...: self.assertEquals('23', '%d' % '23') ...or...: self.assertRaises(TypeError, '%d'.__mod__, ((23,),)) ...? """ + + def test_format_float(self): self.assertEquals('23', '%d' % 23.456) self.assertEquals('0x17', '%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) @@ -55,7 +81,13 @@ r9 = '23.44' + '9'*(len(r)-5) self.assertEquals(r9, r) - def test_format_wrongchar(self): + def test_format_int(self): + self.assertEquals('23', '%d' % 23) + self.assertEquals('0x17', '%x' % 23) + self.assertEquals('23', '%s' % 23) + self.assertEquals('23', '%r' % 23) + + def test_format_wrong_char(self): self.assertRaises(ValueError, 'a%Zb'.__mod__, ((23,),)) if __name__ == '__main__': From alex at codespeak.net Wed Jun 2 14:31:00 2004 From: alex at codespeak.net (alex at codespeak.net) Date: Wed, 2 Jun 2004 14:31:00 +0200 (MEST) Subject: [pypy-svn] r4821 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040602123100.453E35BE07@thoth.codespeak.net> Author: alex Date: Wed Jun 2 14:30:59 2004 New Revision: 4821 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py Log: fix bug triggered when more than one %(name)s formatting items were present 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 Jun 2 14:30:59 2004 @@ -963,7 +963,7 @@ j = format.find(')', i+1) if j == -1: raise ValueError, "incomplete format string" - if index != -1: + if index >= 0: raise TypeError, "format string mismatch" name = format[i+1:j] value = values[name] From hpk at codespeak.net Wed Jun 2 17:16:46 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 2 Jun 2004 17:16:46 +0200 (MEST) Subject: [pypy-svn] r4824 - pypy/branch/src-newobjectmodel Message-ID: <20040602151646.8CD565BE07@thoth.codespeak.net> Author: hpk Date: Wed Jun 2 17:16:46 2004 New Revision: 4824 Added: pypy/branch/src-newobjectmodel/ - copied from r4823, pypy/trunk/src/ Log: branch for a new object model (and new interpreter-types etc.pp) From hpk at codespeak.net Wed Jun 2 17:19:45 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 2 Jun 2004 17:19:45 +0200 (MEST) Subject: [pypy-svn] r4825 - pypy/branch/src-newobjectmodel/goal Message-ID: <20040602151945.779155BE07@thoth.codespeak.net> Author: hpk Date: Wed Jun 2 17:19:44 2004 New Revision: 4825 Modified: pypy/branch/src-newobjectmodel/goal/objectspace-reconstruct.py Log: state of thoughts ... Modified: pypy/branch/src-newobjectmodel/goal/objectspace-reconstruct.py ============================================================================== --- pypy/branch/src-newobjectmodel/goal/objectspace-reconstruct.py (original) +++ pypy/branch/src-newobjectmodel/goal/objectspace-reconstruct.py Wed Jun 2 17:19:44 2004 @@ -1,11 +1,10 @@ def __getattribute__(w_obj,w_name): - type = space.gettype(w_obj) name = space.unwrap(w_name) - w_descr = type.lookup(name) + w_descr = space.lookup(w_obj, name) if w_descr is not None: if space.is_data_descr(w_descr): - return space.get(w_descr,w_obj,space.wrap(type)) + return space.get(w_descr,w_obj,space.type(w_obj)) w_dict = space.getdict(w_obj) if w_dict is not None: try: @@ -18,23 +17,147 @@ raise OperationError(space.w_AttributeError,w_name) def space.getattr(w_obj,w_name): - type = space.gettype(w_obj) - w_descr = type.lookup('__getattribute__') - w_impl = space.get(w_descr,w_obj, space.wrap(type)) + w_descr = space.lookup(w_obj, '__getattribute__') try: - return space.call_function(w_impl, w_name) + return space.get_and_call_function(w_descr, w_obj, w_name) except: # AttributeError - w_descr = type.lookup('__getattr__') + w_descr = space.lookup(w_obj, '__getattr__') if w_descr is None: raise - w_impl = space.get(w_descr,w_obj, space.wrap(type)) - return space.call_function(w_descr,w_obj, space.wrap(type)) + return space.get_and_call_function(w_descr, w_obj, w_name) def space.get(w_obj,w_name): - type = space.gettype(w_obj) - w_descr = type.lookup('__get__') + w_descr = space.lookup(w_obj, '__get__') if w_descr is not None: - w_impl = space.get(w_descr,w_obj, space.wrap(type)) - return space.call_function(w_impl, w_name) + return space.get_and_call(w_descr, w_obj, space.newtuple([w_name])) else: return w_obj + +def space.call(w_obj, w_args, w_kwargs): + w_descr = space.lookup(w_obj, '__call__') + if w_descr is None: + raise OperationError(space.w_TypeError, space.wrap('...')) + return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) + + +class BaseObjSpace: + def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): + if isinstance(w_descr, W_Function): + args_w = space.unpacktuple(w_args) + return w_descr.func.call(space.newtuple([w_obj]+args_w),w_kwargs) + else: + w_bound = space.get(w_descr,w_obj,space.gettype(w_obj)) + return space.call(w_bound, w_args, w_kwargs) + +class Wrappable: + def __wrap__(self, space): + return self + +class Function(Wrappable): + TypeDef = Type("function", [], { + '__call__' : app_descr_function_call, + 'func_code' : Property(func_code_getter) + }) + +class BuiltinType: + def __init__(self, name, bases, rawdict): + self.name = name + self.bases = bases + self.rawdict = rawdict + self.mro = [] + +class W_Function: + def __init__(self, space, func): + self.func = func + self.space = space + + def gettype(self): + space = self.space + try: + return space.FunctionType + except AttributeError: + space.FunctionType = f = Type(space, [space.ObjectType]) + f.dict_w['__call__'] = space.wrap(app_descr_function_call) + func_code_property = Property(func_code_getter) + f.dict_w['func_code'] = space.wrap(func_code_property) + return f + +class StdObjectSpace: + def lookup(space, w_obj, name): + typ = space._gettype(w_obj) + return space.wrap(typ.lookup(name)) + + def type(space,w_obj): + return space.wrap(space._gettype(w_obj)) + + def _gettype + try: + return space._types[w_obj.__class__] + except KeyError: + typ = space.buildtype(w_obj.TypeDef) + space._types[w_obj.__class__] = typ + return typ + + def buildtype(space, typedef): + typ = Type(w_ + for name, value + + def wrap(space, obj): + + assert self.space == space + return W_Type(space, self) + +def trivspace.lookup(space, w_obj, name): + if isinstance(w_obj, Wrappable): + for basedef in w_obj.TypeDef.mro(): + if name in basedef.rawdict: + return space.wrap(basedef.rawdict[name]) + return None + else: + for cls in w_obj.__class__.__mro__: + if name in cls.__dict__: + return cls.__dict__[name] + return None + + +def func_code_getter(space,w_func): + return space.wrap(w_func.func.code) + +def object___class__(space,w_obj): + return space.type(w_obj) + +def descr_function_call(space, w_func, w_args, w_kwds): + return w_func.func.call(w_args, w_kwds) +app_descr_function_call = gateway.interp2app(descr_function_call) + + + + +class Property: + def __init__(self, fget, fset=None, fdel=None, doc=None): + self.fget = fget + self.fset = fset + self.fdel = fdel + self.doc = doc + def __wrap__(self, space): + return W_Property(space, self) + +class W_Property(...Wrapped): + def __init__(self, space, property): + self.space = space + self.property = property + def gettype(self): + space = self.space + try: + return space.PropertyType + except AttributeError: + space.PropertyType = t = Type(space, "builtin-property", []) + t.dict_w["__get__"] = space.wrap(app_descr_property_get) + return t + +def descr_property_get(space, w_property, w_obj, w_ignored): + return w_property.property.fget(space, w_obj) + +app_descr_property_get = gateway.interp2app(descr_property_get) + + From ale at codespeak.net Wed Jun 2 18:08:01 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 2 Jun 2004 18:08:01 +0200 (MEST) Subject: [pypy-svn] r4826 - in pypy/branch/ale_translator_stuff: . tool tool/pygame Message-ID: <20040602160801.9067E5BE07@thoth.codespeak.net> Author: ale Date: Wed Jun 2 18:08:00 2004 New Revision: 4826 Added: pypy/branch/ale_translator_stuff/ - copied from r4813, pypy/trunk/src/pypy/translator/ pypy/branch/ale_translator_stuff/tool/pygame/graphviewer.py - copied unchanged from r4825, pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py Modified: pypy/branch/ale_translator_stuff/genpyrex.py pypy/branch/ale_translator_stuff/tool/buildpyxmodule.py pypy/branch/ale_translator_stuff/translator.py Log: made a copy Modified: pypy/branch/ale_translator_stuff/genpyrex.py ============================================================================== --- pypy/trunk/src/pypy/translator/genpyrex.py (original) +++ pypy/branch/ale_translator_stuff/genpyrex.py Wed Jun 2 18:08:00 2004 @@ -2,152 +2,37 @@ generate Pyrex files from the flowmodel. """ +from __future__ import generators from pypy.interpreter.baseobjspace import ObjSpace from pypy.objspace.flow.model import Variable, Constant, UndefinedConstant from pypy.objspace.flow.model import mkentrymap from pypy.translator.annrpython import RPythonAnnotator from pypy.annotation.model import SomeMethod +from pypy.translator.codewriter import CodeWriter -class Op: - def __init__(self, operation, gen, block): - self._str = gen._str - self.gen = gen - self.argnames = [self._str(arg, block) for arg in operation.args] - self.resultname = self._str(operation.result, block) - self.op = operation - #op.opname - - def __call__(self): - operator = self.gen.ops.get(self.op.opname, self.op.opname) - #print "operator, ", self.op.opname, operator, self.gen.ops - - args = self.argnames - if not (operator[0] >= "a" and operator[0] <= "z"): - if len(args) == 1: - return "%s = %s %s" % (self.resultname, operator) + args - elif len(args) == 2: - return "%s = %s %s %s" % (self.resultname, args[0], operator, args[1]) - elif len(args) == 3 and operator == "**": #special case, have to handle it manually - return "%s = pow(%s, %s, %s)" % (self.resultname,) + args - else: - raise NotImplementedError, "I don't know to handle the operator %s (arity %s)" \ - % (operator, len(args)) - else: - method = getattr(self, "op_%s" % operator, self.generic_op) - return method() - - def ispythonident(self, s): - if s[0] not in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_": - return False - for c in s[1:]: - if (c not in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_" - "0123456789"): - return False - return True - - - def generic_op(self): - """Generic handler for all operators, which I don't handle explicitly""" - - return "%s = %s(%s)" % (self.resultname, self.op.opname, ", ".join(self.argnames)) +Op={'next' :'', + 'getitem' :"%s = %s[%s]", + 'newtuple' :"%s = (%s)", + 'newlist' :"%s = [%s]", + 'newdict' :"%s = {%s}", + 'newslice' :"%s = slice(%s, %s, %s)", + 'call' :"%s = %s(*%s, **%s)", + 'simple_call' :"%s = %s(%s)", + 'setitem' :"%s[%s] = %s", + 'getattr' :"%s = getattr(%s,%s)", + 'setattr' :"%s = setattr(%s, %s, %s)", + 'not' :"%s = not %s", + 'is_true' :"%s = not not %s", + 'exception' :"%s, last_exc = last_exc, None" , + 'generic' :"%s = %s(%s)" + } +class GenPyrex(CodeWriter): - def op_next(self): - lines = [] - args = self.argnames - lines.append("try:") - lines.append(" %s = %s.next()" % (self.resultname, args[0])) - lines.append("except StopIteration:") - lines.append(" last_exc = StopIteration") - lines.append("else:") - lines.append(" last_exc = None") - return "\n".join(lines) - - def op_getitem(self): - direct = "%s = %s[%s]" % ((self.resultname,) + tuple(self.argnames)) - w_sequence, w_index = self.op.args - tp = self.gen.get_type(w_index) - if tp is int: - return direct - else: - # the index could be a slice - indexname = self.argnames[1] - lines = [] - if tp is slice: # XXX do this better - lines.append('if 1:') - else: - lines.append('from types import SliceType') - lines.append('if isinstance(%s, SliceType):' % indexname) - lines.append(' assert %s.step is None' % indexname) - lines.append(' %s = %s[%s.start:%s.stop]' % (self.resultname, - self.argnames[0], - indexname, - indexname)) - lines.append('else:') - lines.append(' ' + direct) - return "\n".join(lines) - - def op_newtuple(self): - if self.argnames: - return "%s = (%s,)" % (self.resultname, ", ".join(self.argnames)) - else: - return "%s = ()" % self.resultname - - def op_newlist(self): - if self.argnames: - return "%s = [%s,]" % (self.resultname, ", ".join(self.argnames)) - else: - return "%s = []" % self.resultname - - def op_newdict(self): - pairs = [] - for i in range(0, len(self.argnames), 2): - pairs.append("%s: %s, " % (self.argnames[i], self.argnames[i+1])) - return "%s = {%s}" % (self.resultname, "".join(pairs)) - - def op_newslice(self): - a = self.argnames - return "%s = slice(%s, %s, %s)" % (self.resultname, a[0], a[1], a[2]) - - def op_call(self): - a = self.argnames - return "%s = %s(*%s, **%s)" % (self.resultname, a[0], a[1], a[2]) - - def op_simple_call(self): - a = self.argnames - return "%s = %s(%s)" % (self.resultname, a[0], ", ".join(a[1:])) - - def op_setitem(self): - a = self.argnames - return "%s[%s] = %s" % (a[0], a[1], a[2]) - - def op_getattr(self): - args = self.argnames - attr = self.op.args[1] - if isinstance(attr, Constant) and self.ispythonident(attr.value): - return "%s = %s.%s" % (self.resultname, args[0], attr.value) - else: - return "%s = getattr(%s)" % (self.resultname, ", ".join(args)) - - def op_setattr(self): - args = self.argnames - attr = self.op.args[1] - if isinstance(attr, Constant) and self.ispythonident(attr.value): - return "%s.%s = %s" % (args[0], attr.value, args[2]) - else: - return "setattr(%s, %s, %s)" % args - - def op_not(self): - return "%s = not %s" % (self.resultname, self.argnames[0]) - - def op_is_true(self): - return "%s = not not %s" % (self.resultname, self.argnames[0]) - - def op_exception(self): - return "%s, last_exc = last_exc, None" % (self.resultname,) - -class GenPyrex: - def __init__(self, functiongraph): - self.functiongraph = functiongraph + def __init__(self,translator,annotator): + CodeWriter.__init__(self) + self.translator=translator + self.annotator=annotator + self.blockids={} ops = {} oparity = {} for (opname, opsymbol, arity, _) in ObjSpace.MethodTable: @@ -155,185 +40,165 @@ oparity[opname] = arity self.ops = ops self.oparity = oparity - self.annotator = None - - def annotate(self, input_arg_types): - a = RPythonAnnotator() - a.build_types(self.functiongraph, input_arg_types) - self.setannotator(a) - - def setannotator(self, annotator): - self.annotator = annotator - - def emitcode(self): - self.blockids = {} - #self.variablelocations = {} - self.lines = [] - self.indent = 0 - self.gen_graph() - return "\n".join(self.lines) - - def putline(self, line): - for l in line.split('\n'): - self.lines.append(" " * self.indent + l) - - def gen_graph(self): - fun = self.functiongraph - self.entrymap = mkentrymap(fun) - currentlines = self.lines - self.lines = [] - self.indent += 1 - self.putline("last_exc = None") - self.gen_block(fun.startblock) - self.indent -= 1 - # emit the header after the body - functionbodylines = self.lines - self.lines = currentlines - inputargnames = [ " ".join(self._paramvardecl(var)) for var in fun.getargs() ] - params = ", ".join(inputargnames) - returntype = self.get_type(fun.getreturnvar()) - returntypename = self._gettypename(returntype) - try: - function_object = self.by_the_way_the_function_was # XXX! - except AttributeError: - def function_object(): pass # XXX!!! - # make the function visible from the outside under its original name - hackedargs = ', '.join([var.name for var in fun.getargs()]) - self.putline("def %s(%s):" % (fun.name, hackedargs)) - self.indent += 1 - self.putline("return %s(%s)" % (self._hackname(function_object), hackedargs)) - self.indent -= 1 - # go ahead with the mandled header and body of the function - self.putline("def %s(%s):" % (self._hackname(function_object), params)) - self.indent += 1 - #self.putline("# %r" % self.annotations) - decllines = [] - missing_decl = [] - funargs = fun.getargs() - for block in self.blockids: - for var in block.getvariables(): - if var not in funargs: - decl = self._vardecl(var) - if decl: - decllines.append(decl) - else: - missing_decl.append(self.get_varname(var)) - if missing_decl: - missing_decl.sort() - decllines.append('# untyped variables: ' + ' '.join(missing_decl)) - decllines.sort() - for decl in decllines: - self.putline(decl) - self.indent -= 1 - self.lines.extend(functionbodylines) - - def get_type(self, var): - if isinstance(var, Constant): - return type(var.value) - elif self.annotator: - return self.annotator.gettype(var) - else: - return None - - def get_varname(self, var): - vartype = self.get_type(var) - if vartype in (int, bool): - prefix = "i_" - elif self.annotator and vartype in self.annotator.getuserclasses(): - prefix = "p_" - else: - prefix = "" - return prefix + var.name - - def _paramvardecl(self, var): - vartype = self.get_type(var) - ctype=self._gettypename(vartype) - return (ctype, self.get_varname(var)) - - def _gettypename(self, vartype): - if vartype in (int, bool): - ctype = "int" - elif self.annotator and vartype in self.annotator.getuserclasses(): - ctype = self.get_classname(vartype) - else: - ctype = "object" - return ctype - - def get_classname(self, userclass): - return self._hackname(userclass) - - def _vardecl(self, var): - vartype, varname = self._paramvardecl(var) - if vartype != "object": - return "cdef %s %s" % (vartype, varname) + + def build(self): + self.blockids={} + self.discover_methods() + self.blocks+=self.build_classes() + self.blocks+=self.build_functions() + + def discover_methods(self): + self.methods={} # maps classes to lists of methods + self.methodset={} # set of Python functions that are methods + for cls in self.annotator.getuserclassdefinitions(): + self.methods[cls] = [] + for cls in self.annotator.getuserclassdefinitions(): + for attr,s_value in cls.attrs.items(): + if isinstance(s_value,SomeMethod): + for py_fun,fun_class in s_value.meths.items(): + self.methods[fun_class].append(py_fun) + self.methodset[py_fun] = True + + def build_classes(self): + print "Entering build_classes" + for cls in self.annotator.getuserclassdefinitions(): + #print "Class %s"%cls + if cls.basedef: + bdef="(%s)" % (self.name(cls.basedef.cls)) else: - return "" - - def _hackname(self, value): - try: - name = value.__name__ - except AttributeError: - pass - else: - import types - if isinstance(value, (types.FunctionType, types.ClassType, type)): - # XXX! use the id of the value to make unique function and - # class names - return '%s__%x' % (name, id(value)) - elif isinstance(value, types.BuiltinFunctionType): - return str(name) - if isinstance(value, int): - value = int(value) # cast subclasses of int (i.e. bools) to ints - return repr(value) - - def _str(self, obj, block): - if isinstance(obj, Variable): - #self.variablelocations[obj] = block - return self.get_varname(obj) - elif isinstance(obj, Constant): - return self._hackname(obj.value) - else: - raise TypeError("Unknown class: %s" % obj.__class__) - - def gen_block(self, block): + bdef="" + yield "cdef class %s%s:" % (self.name(cls.cls),bdef) + body=[] + for attr,s_value in cls.attrs.items(): + if not isinstance(s_value,SomeMethod): + vartype=self.typename(s_value.knowntype) + body.append("cdef public %s %s" % (vartype, attr)) + for py_fun in self.methods[cls]: + body+=self.build_function(py_fun) + + yield body or ["pass"] + yield "" + yield "" + + def build_functions(self): + for fun in self.translator.functions: + if fun not in self.methodset: + gen = self.build_function(fun) + yield gen.next() + yield list(gen) + yield "" + yield "" + + # _________________________________________________________ + + def build_function(self,function): + print "Entering build_function %s"%function + self.blockids={} + fungraph=self.translator.getflowgraph(function) + self.entrymap = mkentrymap(fungraph) + signature = [ "%s %s"%(self.typename(self.typeof(var)), + self.name(var)) for var in fungraph.getargs() ] + signature=",".join(signature) + if self.translator.entrypoint is function: + yield "def %s(%s):" % (self.name(function),signature) + else: + yield "cdef %s %s(%s):" % (self.typeof(fungraph.getreturnvar()), + self.name(function),signature) + # Building the body of the function + body=[] + print "Entry map keys",self.entrymap.keys() + print "Start block", fungraph.startblock + print " goes to", self.entrymap[fungraph.startblock] + self.blocks_done = {} + body += self.build_block(fungraph.startblock) + print " blockids", self.blockids + yield body + blocks = [] + while True: + loop_on = [] + for block in self.blockids: + if block not in self.blocks_done: + loop_on.append(block) + if not loop_on: + break + for block in loop_on: + blocks += self.build_block(block) + print "Doing block", block + print " goes to", self.entrymap[block] + print " blockids", self.blockids + yield blocks + # _________________________________________________________ + + def build_block(self, block): + self.blocks_done[block] = True if self.blockids.has_key(block): - self.putline('cinline "goto Label%s;"' % self.blockids[block]) - return - + yield 'cinline "goto Label%s;"' % self.blockids[block] + return blockids = self.blockids - blockids.setdefault(block, len(blockids)) + thisone = blockids[block] = len(blockids) #the label is only written if there are multiple refs to the block if len(self.entrymap[block]) > 1: - self.putline('cinline "Label%s:"' % blockids[block]) + yield 'cinline "Label%s:"' % thisone for op in block.operations: - opg = Op(op, self, block) - self.putline(opg()) - + # print "making operations %s"%op + argnames = [self.name(arg) for arg in op.args] + resultname = self.name(op.result) + operator = self.ops.get(op.opname, op.opname) + + if operator in ['+','-','*','**','/']: + if len(argnames) == 1: + yield "%s = %s %s" % (resultname, operator) + argnames + elif len(argnames) == 2: + yield "%s = %s %s %s" % (resultname, argnames[0], operator, argnames[1]) + elif len(argnames) == 3 and operator == "**": #special case, have to handle it manually + yield "%s = pow(%s, %s, %s)" % (resultname,) + argnames + else: + raise NotImplementedError, "I don't know to handle the operator %s (arity %s)" \ + % (operator, len(argnames)) + else: + opstring=Op.get(operator,None) + if opstring: + if operator in ['newlist','newtuple']: + format=(resultname,"".join([a+',' for a in argnames])) + elif operator =='newdict': + pairs = [] + for i in range(0, len(argnames), 2): + pairs.append("%s: %s, " % + (argnames[i], argnames[i+1])) + format=(resultname,",".join(pairs)) + elif operator =='simple_call': + format=(resultname,argnames[0], + ",".join(argnames[1:])) + else: + format=(resultname,)+tuple(argnames) + #print opstring,resultname,argnames,format + yield opstring %format + else: + yield Op['generic']%format exits = block.exits if len(exits) == 1: - self.gen_link(block, exits[0]) + for line in self.gen_link(block, exits[0]): yield line elif len(exits) > 1: - varname = self._str(block.exitswitch, block) + varname = self.name(block.exitswitch) for i in range(len(exits)): exit = exits[-i-1] # reverse order - cond = self._str(Constant(exit.exitcase), block) + cond = self.name(Constant(exit.exitcase)) if i == 0: - self.putline("if %s == %s:" % (varname, cond)) + yield "if %s == %s:" % (varname, cond) elif i < len(exits) - 1: - self.putline("elif %s == %s:" % (varname, cond)) + yield "elif %s == %s:" % (varname, cond) else: - self.putline("else: # %s == %s" % (varname, cond)) - self.indent += 1 - self.gen_link(block, exit) - self.indent -= 1 + yield "else: # %s == %s" % (varname, cond) + yield list(self.gen_link(block, exit)) elif hasattr(block, 'exc_type'): - self.putline("raise %s" % block.exc_type.__name__) + yield "raise %s" % block.exc_type.__name__ else: - self.putline("return %s" % self._str(block.inputargs[0], block)) + yield "return %s" % self.name(block.inputargs[0]) def gen_link(self, prevblock, link): - _str = self._str + print "Entering gen_link" + _str = self.name block = link.target sourceargs = link.args targetargs = block.inputargs @@ -345,49 +210,41 @@ sargs.append(s) targs.append(t) if sargs: - sargs = [_str(arg, prevblock) for arg in sargs] - targs = [_str(arg, block) for arg in targs] - self.putline("%s = %s" % (", ".join(targs), ", ".join(sargs))) - - self.gen_block(block) - - def globaldeclarations(self,): - """Generate the global class declaration for a group of functions.""" - if self.annotator: - self.lines = [] - self.indent = 0 - delay_methods={} - for cls in self.annotator.getuserclassdefinitions(): - if cls.basedef: - bdef="(%s)" % (self.get_classname(cls.basedef.cls)) - else: - bdef="" - self.putline("cdef class %s%s:" % (self.get_classname(cls.cls),bdef)) - self.indent += 1 - empty = True - for attr,s_value in cls.attrs.items(): - if isinstance(s_value,SomeMethod): - for py_fun,fun_class in s_value.meths.items(): - delay_methods.setdefault(fun_class,[]).append(py_fun) - else: - vartype=self._gettypename(s_value.knowntype) - self.putline("cdef public %s %s" % (vartype, attr)) - empty = False - list_methods=delay_methods.get(cls,[]) - for py_fun in list_methods: - # XXX! - fun = self.annotator.translator.flowgraphs[py_fun] - hackedargs = ', '.join([var.name for var in fun.getargs()]) - self.putline("def %s(%s):" % (py_fun.__name__, hackedargs)) - self.indent += 1 - self.putline("return %s(%s)" % (self._hackname(py_fun), - hackedargs)) - self.indent -= 1 - empty = False - if empty: - self.putline("pass") - self.indent -= 1 - self.putline("") - return '\n'.join(self.lines) + sargs1 = [_str(arg) for arg in sargs] + targs1 = [_str(arg) for arg in targs] + yield "%s = %s" % (", ".join(targs1), ", ".join(sargs1)) + + print "from gen_link", prevblock, "doing", block + for line in self.build_block(block): yield line + + + def typeof(self,var): + if isinstance(var, Constant): + return self.typename(var.value) else: - return '' + return self.typename(self.annotator.gettype(var)) + + + def varname(self, var): + if isinstance(var, Variable): + vartype = self.typeof(var) + if vartype in (int, bool): + prefix = "i_" + elif vartype in self.annotator.getuserclasses(): + prefix = "p_" + else: + prefix = "" + return prefix + var.name + elif isinstance(var, Constant): + return self.name(var.value) + else: + raise TypeError("Unknown class: %s" % var.__class__) + + def typename(self, vartype): + if vartype in (int, bool): + ctype = "int" + elif vartype in self.annotator.getuserclasses(): + ctype = self.name(vartype) + else: + ctype = "object" + return ctype Modified: pypy/branch/ale_translator_stuff/tool/buildpyxmodule.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/buildpyxmodule.py (original) +++ pypy/branch/ale_translator_stuff/tool/buildpyxmodule.py Wed Jun 2 18:08:00 2004 @@ -77,7 +77,8 @@ from Pyrex.Compiler.Main import CompilationOptions, Context, PyrexError try: options = CompilationOptions(show_version = 0, - use_listing_file = 0, + use_listing_file = 0, + errors_to_stderr = 1, c_only = 1, output_file = None) context = Context(options.include_path) Modified: pypy/branch/ale_translator_stuff/translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/translator.py (original) +++ pypy/branch/ale_translator_stuff/translator.py Wed Jun 2 18:08:00 2004 @@ -124,14 +124,14 @@ graph = self.getflowgraph(func) return getattr(graph, 'source', '') - def pyrex(self, input_arg_types=None, func=None): + def pyrex(self): """pyrex(self[, input_arg_types][, func]) -> Pyrex translation Returns Pyrex translation. If input_arg_types is provided, returns type annotated translation. Subsequent calls are not affected by this. """ - return self.generatecode(GenPyrex, input_arg_types, func) + return self.generatecode(GenPyrex) def cl(self, input_arg_types=None, func=None): """cl(self[, input_arg_types][, func]) -> Common Lisp translation @@ -142,24 +142,14 @@ """ return self.generatecode(GenCL, input_arg_types, func) - def generatecode(self, gencls, input_arg_types, func): - if input_arg_types is None: - ann = self.annotator - else: - ann = RPythonAnnotator(self) - if func is None: - codes = [self.generatecode1(gencls, input_arg_types, - self.entrypoint, ann)] - for func in self.functions: - if func is not self.entrypoint: - code = self.generatecode1(gencls, None, func, ann) - codes.append(code) - else: - codes = [self.generatecode1(gencls, input_arg_types, func, ann)] - code = self.generateglobaldecl(gencls, func, ann) - if code: - codes.insert(0, code) - return '\n\n#_________________\n\n'.join(codes) + def generatecode(self, gencls): + from StringIO import StringIO + ann = self.annotator or RPythonAnnotator(self) + code_file=StringIO() + code_cw=gencls(self,ann) + code_cw.build() + code_cw.write(code_file) + return code_file.getvalue() def generatecode1(self, gencls, input_arg_types, func, ann): graph = self.getflowgraph(func) From ale at codespeak.net Wed Jun 2 18:12:32 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 2 Jun 2004 18:12:32 +0200 (MEST) Subject: [pypy-svn] r4827 - pypy/branch/ale_translator_stuff Message-ID: <20040602161232.381405BE07@thoth.codespeak.net> Author: ale Date: Wed Jun 2 18:12:31 2004 New Revision: 4827 Added: pypy/branch/ale_translator_stuff/codewriter.py Log: The CodeWriter baseclass module Added: pypy/branch/ale_translator_stuff/codewriter.py ============================================================================== --- (empty file) +++ pypy/branch/ale_translator_stuff/codewriter.py Wed Jun 2 18:12:31 2004 @@ -0,0 +1,37 @@ + + +class CodeWriter: + """ The CodeWriter writes code from blocks. Blocks are list of strings and + other lists (blocks). + + If an item is a string it is written, and if it as a list the indentation + level is increased""" + + def __init__(self): + self.blocks=[] + self.known_names={} + self.unique_val={} + + def write(self,file): + def write_rec(block,indentation_level=0): + for item in block: + if isinstance(item,str): + print >>file," "*indentation_level+item + else: + write_rec(item,indentation_level+1) + + write_rec(self.blocks) + + def name(self,obj): + if obj in self.known_names: + return self.known_names[obj] + else: + name=getattr(obj,'__name__','Var') + if name in self.unique_val: + self.unique_val[name]+=1 + name=name+'__'+str(self.unique_val[name]) + else: + self.unique_val[name]=0 + self.known_names[obj]=name + return name + \ No newline at end of file From hpk at codespeak.net Wed Jun 2 18:39:35 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 2 Jun 2004 18:39:35 +0200 (MEST) Subject: [pypy-svn] r4828 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040602163935.AC90D5BE07@thoth.codespeak.net> Author: hpk Date: Wed Jun 2 18:39:35 2004 New Revision: 4828 Added: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py Log: some first moves towards descriptors for interpreter objects Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Wed Jun 2 18:39:35 2004 @@ -9,31 +9,8 @@ class Wrappable(object): """A subclass of Wrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" - - def get_wdict(self): - space = self.space - try: - return self.w_dict - except AttributeError: - w_dict = self.w_dict = space.newdict([]) - for name,w_value in self.app_visible(): - space.setitem(w_dict,space.wrap(name),w_value) - return w_dict - - def app_visible(self): - """ returns [(name,w_value)...] for application-level visible attributes """ - raise NotImplementedError - - def pypy_getattr(self, w_name): - space = self.space - w_dict = self.get_wdict() - try: - return space.getitem(w_dict,w_name) - except OperationError,e: - if not e.match(space,space.w_KeyError): - raise - raise OperationError(space.w_AttributeError,w_name) - + def __wrap__(self, space): + return self class NoValue(Exception): """Raised to signal absence of value, e.g. in the iterator accessing Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Wed Jun 2 18:39:35 2004 @@ -6,8 +6,10 @@ attribute. """ -from error import OperationError -from baseobjspace import Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import attrproperty, attrproperty_w, TypeDef +from pypy.interpreter.gateway import interp2app class Function(Wrappable): """A function is a code object captured with some environment: @@ -31,8 +33,6 @@ frame.setfastscope(scope_w) return frame.run() - pypy_call = call - def parse_args(self, w_args, w_kwds=None): """ parse args and kwargs to initialize the frame. """ @@ -156,17 +156,8 @@ self.name, nkwds) raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - - def __get__(self, obj, cls=None): - wrap = self.space.wrap - if obj is not None: - if cls is None: - cls = obj.__class__ - return Method(self.space, wrap(self), wrap(obj), wrap(cls)) - else: - return Method(self.space, wrap(self), None, wrap(cls)) - - def pypy_get(self, w_obj, w_cls): + + def descr_function_get(self, w_obj, w_cls): space = self.space wrap = space.wrap if not space.is_true(space.is_(w_obj, space.w_None)): @@ -176,33 +167,16 @@ else: return wrap(Method(space, wrap(self), None, w_cls)) - def __call__(self, *args_w, **kwds_w): - wrap = self.space.wrap - w_args = self.space.newtuple(args_w) - w_kwds = self.space.newdict([(wrap(key), w_value) - for key, w_value in kwds_w.items()]) - # go through the object space, don't call directly here - # (for FlowObjSpace) - return self.space.call(wrap(self), w_args, w_kwds) - - def app_visible(self): - space = self.space - def makedict(**kw): - return kw - #print "APPVISI", self.code, "INTO", space.wrap(self.code) - it = makedict( - func_defaults = self.defs_w and space.newtuple(self.defs_w) or space.w_None, - func_code = space.wrap(self.code), - func_dict = self.w_func_dict, - func_doc = space.wrap(self.doc), - func_name = space.wrap(self.name), - func_globals = self.w_func_globals, - func_closure = space.wrap(self.closure)) - it['__name__'] = it['func_name'] - it['__doc__'] = it['func_doc'] - it['__dict__'] = it['func_dict'] - it['__call__'] = space.wrap(self) - return it.items() + typedef = TypeDef("function", { + '__call__' : interp2app(call), + '__get__' : interp2app(descr_function_get), + 'func_code' : attrproperty('code'), + 'func_doc' : attrproperty('doc'), + 'func_name' : attrproperty('name'), + 'func_dict' : attrproperty_w('w_func_dict'), + '__dict__' : attrproperty_w('w_func_dict'), + # XXX getattribute/setattribute etc.pp + }) class Method(object): """A method is a function bound to a specific instance or class.""" @@ -231,11 +205,34 @@ self.space.wrap(msg)) return self.space.call(self.w_function, w_args, w_kwds) - pypy_call = call - def __call__(self, *args_w, **kwds_w): - wrap = self.space.wrap - w_args = self.space.newtuple(args_w) - w_kwds = self.space.newdict([(wrap(key), w_value) - for key, w_value in kwds_w.items()]) - return self.call(w_args, w_kwds) + typedef = TypeDef("method", { + '__call__': interp2app(call), + 'im_func' : attrproperty_w('w_function'), + 'im_self' : attrproperty_w('w_instance'), + 'im_class': attrproperty_w('w_class'), + # XXX getattribute/setattribute etc.pp +# it['__name__'] = it['func_name'] +# it['__doc__'] = it['func_doc'] +# it['__dict__'] = it['func_dict'] +# it['__call__'] = space.wrap(self) + }) + +# def app_visible(self): +# space = self.space +# def makedict(**kw): +# return kw +# #print "APPVISI", self.code, "INTO", space.wrap(self.code) +# it = makedict( +# func_defaults = self.defs_w and space.newtuple(self.defs_w) or space.w_None, +# func_code = space.wrap(self.code), +# func_dict = self.w_func_dict, +# func_doc = space.wrap(self.doc), +# func_name = space.wrap(self.name), +# func_globals = self.w_func_globals, +# func_closure = space.wrap(self.closure)) +# it['__name__'] = it['func_name'] +# it['__doc__'] = it['func_doc'] +# it['__dict__'] = it['func_dict'] +# it['__call__'] = space.wrap(self) +# return it.items() Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py Wed Jun 2 18:39:35 2004 @@ -17,7 +17,6 @@ WeakKeyDictionary = dict # XXX for PyPy from pypy.interpreter import eval, pycode from pypy.interpreter.baseobjspace import Wrappable, ObjSpace -from pypy.interpreter.function import Function, Method class BuiltinCode(eval.Code): @@ -189,6 +188,7 @@ if space in self.functioncache: fn = self.functioncache[space] else: + from pypy.interpreter.function import Function defs = self.getdefaults(space) # needs to be implemented by subclass fn = Function(space, self.code, w_globals, defs, forcename = self.name) self.functioncache[space] = fn Added: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- (empty file) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Wed Jun 2 18:39:35 2004 @@ -0,0 +1,44 @@ +""" + + +""" +from pypy.interpreter.gateway import interp2app + +class TypeDef: + def __init__(self, name, rawdict): + self.name = name + self.rawdict = rawdict + + def mro(self, space): + return [self, space.object_typedef] + +class GetSetProperty: + def __init__(self, fget, fset=None, fdel=None, doc=None): + self.fget = fget + self.fset = fset + self.fdel = fdel + self.doc = doc + + def descr_property_get(space, w_property, w_obj, w_ignored): + return space.unwrap(w_property).fget(space, w_obj) + + typedef = TypeDef("GetSetProperty", { + '__get__' : interp2app(descr_property_get), + }) + +def attrproperty(name): + def fget(space, w_obj): + obj = space.unwrap(w_obj) + return space.wrap(getattr(obj, name)) + return GetSetProperty(fget) + +def attrproperty_w(name): + def fget(space, w_obj): + obj = space.unwrap(w_obj) + w_value = getattr(obj, name) + if w_value is None: + return space.w_None + else: + return w_value + + return GetSetProperty(fget) From pedronis at codespeak.net Wed Jun 2 18:50:45 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 2 Jun 2004 18:50:45 +0200 (MEST) Subject: [pypy-svn] r4829 - pypy/branch/src-newobjectmodel/pypy/objspace/descr Message-ID: <20040602165045.DEF465BE07@thoth.codespeak.net> Author: pedronis Date: Wed Jun 2 18:50:45 2004 New Revision: 4829 Added: pypy/branch/src-newobjectmodel/pypy/objspace/descr/ pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Log: start of descriptor-using obj space abstract implementation Added: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py ============================================================================== --- (empty file) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Wed Jun 2 18:50:45 2004 @@ -0,0 +1,87 @@ +from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import * + + +class DescrObjSpace(ObjSpace): + + def getattr(space,w_obj,w_name): + w_descr = space.lookup(w_obj,'__getattribute__') + try: + return space.get_and_call_function(w_descr,w_obj,w_name) + except OperatioError,e: + if not e.match(space,space.w_AttributeError): + raise + w_descr = space.lookup(w_obj,'__getattr__') + return space.get_and_call_function(w_descr,w_obj,w_name) + + def setattr(space,w_obj,w_name,w_val): + w_descr = space.lookup(w_obj,'__setattr__') + if w_descr is None: + raise OperationError(space.w_AttributeError) # xxx error + return space.get_and_call_function(w_descr,w_obj,w_name,w_val) + + def delattr(space,w_obj,w_name): + w_descr = space.lookup(w_obj,'__delattr__') + if w_descr is None: + raise OperationError(space.w_AttributeError) # xxx error + return space.get_and_call_function(w_descr,w_obj,w_name) + + def str(space,w_obj): + w_descr = space.lookup(w_obj,'__str__') + return space.get_and_call_function(w_descr,w_obj) + + def repr(space,w_obj): + w_descr = space.lookup(w_obj,'__repr__') + return space.get_and_call_function(w_descr,w_obj) + + def pos(space,w_obj): + w_descr = space.lookup(w_obj,'__pos__') + if w_descr is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call_function(w_descr,w_obj) + + # xxx todo rest of 0 args methods + # rest of 1 args methods + # special cases + + +# regular methods def helpers +def _make_binary_impl(specialnames): + left, right = specialnames + def binary_impl(space,w_obj1,w_obj2): + w_typ1 = space.type(w_obj1) + w_typ2 = space.type(w_obj2) + if space.issubtype(w_typ1,w_typ2): + w_right_impl = space.lookup(w_obj2, right) + if w_right_impl is not None: + w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return w_res + w_left_impl = space.lookup(w_obj1, left) + if w_left_impl is not None: + w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return w_res + else: + w_left_impl = space.lookup(w_obj1, left) + if w_left_impl is not None: + w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return w_res + w_right_impl = space.lookup(w_obj2, right) + if w_right_impl is not None: + w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return w_res + raise OperationError(space.w_TypeError) # xxx error + return binary_impl + +# add regular methods +for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: + if not hasattr(DescrObjSpace,_name): + if _arity == 2: # binary + setattr(DescrObjSpace,_name,_make_binary_impl(_specialnames)) + + + + From pedronis at codespeak.net Wed Jun 2 19:01:07 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 2 Jun 2004 19:01:07 +0200 (MEST) Subject: [pypy-svn] r4830 - pypy/branch/src-newobjectmodel/pypy/objspace/descr Message-ID: <20040602170107.882F25BE07@thoth.codespeak.net> Author: pedronis Date: Wed Jun 2 19:01:06 2004 New Revision: 4830 Added: pypy/branch/src-newobjectmodel/pypy/objspace/descr/__init__.py Log: make descr a package Added: pypy/branch/src-newobjectmodel/pypy/objspace/descr/__init__.py ============================================================================== --- (empty file) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descr/__init__.py Wed Jun 2 19:01:06 2004 @@ -0,0 +1 @@ +# descriptor-using object space From arigo at codespeak.net Wed Jun 2 19:27:49 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 2 Jun 2004 19:27:49 +0200 (MEST) Subject: [pypy-svn] r4833 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040602172749.D3FEA5BE07@thoth.codespeak.net> Author: arigo Date: Wed Jun 2 19:27:47 2004 New Revision: 4833 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/interpreter/module.py pypy/branch/src-newobjectmodel/pypy/interpreter/pycode.py pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Log: Initial typedefs for most internal types. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py Wed Jun 2 19:27:47 2004 @@ -2,9 +2,11 @@ This module defines the abstract base classes that support execution: Code and Frame. """ -from error import OperationError +from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import Wrappable -class Code(object): + +class Code(Wrappable): """A code is a compiled version of some source code. Abstract base class.""" @@ -48,7 +50,7 @@ UNDEFINED = object() # marker for undefined local variables -class Frame(object): +class Frame(Wrappable): """A frame is an environment supporting the execution of a code object. Abstract base class.""" Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Wed Jun 2 19:27:47 2004 @@ -8,7 +8,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.typedef import attrproperty, attrproperty_w, TypeDef from pypy.interpreter.gateway import interp2app class Function(Wrappable): @@ -167,16 +166,6 @@ else: return wrap(Method(space, wrap(self), None, w_cls)) - typedef = TypeDef("function", { - '__call__' : interp2app(call), - '__get__' : interp2app(descr_function_get), - 'func_code' : attrproperty('code'), - 'func_doc' : attrproperty('doc'), - 'func_name' : attrproperty('name'), - 'func_dict' : attrproperty_w('w_func_dict'), - '__dict__' : attrproperty_w('w_func_dict'), - # XXX getattribute/setattribute etc.pp - }) class Method(object): """A method is a function bound to a specific instance or class.""" @@ -204,35 +193,3 @@ raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) return self.space.call(self.w_function, w_args, w_kwds) - - - typedef = TypeDef("method", { - '__call__': interp2app(call), - 'im_func' : attrproperty_w('w_function'), - 'im_self' : attrproperty_w('w_instance'), - 'im_class': attrproperty_w('w_class'), - # XXX getattribute/setattribute etc.pp -# it['__name__'] = it['func_name'] -# it['__doc__'] = it['func_doc'] -# it['__dict__'] = it['func_dict'] -# it['__call__'] = space.wrap(self) - }) - -# def app_visible(self): -# space = self.space -# def makedict(**kw): -# return kw -# #print "APPVISI", self.code, "INTO", space.wrap(self.code) -# it = makedict( -# func_defaults = self.defs_w and space.newtuple(self.defs_w) or space.w_None, -# func_code = space.wrap(self.code), -# func_dict = self.w_func_dict, -# func_doc = space.wrap(self.doc), -# func_name = space.wrap(self.name), -# func_globals = self.w_func_globals, -# func_closure = space.wrap(self.closure)) -# it['__name__'] = it['func_name'] -# it['__doc__'] = it['func_doc'] -# it['__dict__'] = it['func_dict'] -# it['__call__'] = space.wrap(self) -# return it.items() Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/module.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/module.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/module.py Wed Jun 2 19:27:47 2004 @@ -3,13 +3,6 @@ """ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.error import OperationError - -def _checkattrtype(space, w_attr): - attr = space.unwrap(w_attr) - if not isinstance(attr, str): - raise OperationError(space.w_TypeError, - space.wrap('attribute name must be string')) class Module(Wrappable): """A module.""" @@ -21,32 +14,3 @@ self.w_dict = w_dict self.w_name = w_name space.setitem(w_dict, space.wrap('__name__'), w_name) - - def pypy_getattr(self, w_attr): - space = self.space - _checkattrtype(space, w_attr) - if space.is_true(space.eq(w_attr, space.wrap('__dict__'))): - return self.w_dict - try: - return space.getitem(self.w_dict, w_attr) - except OperationError, e: - if not e.match(space, space.w_KeyError): - raise - # XXX fix error message - raise OperationError(space.w_AttributeError, w_attr) - - def pypy_setattr(self, w_attr, w_value): - space = self.space - _checkattrtype(space, w_attr) - space.setitem(self.w_dict, w_attr, w_value) - - def pypy_delattr(self, w_attr): - space = self.space - _checkattrtype(space, w_attr) - try: - space.delitem(self.w_dict, w_attr) - except OperationError, e: - if not e.match(space, space.w_KeyError): - raise - # XXX fix error message - raise OperationError(space.w_AttributeError, w_attr) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/pycode.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/pycode.py Wed Jun 2 19:27:47 2004 @@ -7,7 +7,6 @@ import dis from pypy.interpreter import eval from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import Wrappable # code object contants, for co_flags below @@ -18,33 +17,6 @@ CO_NESTED = 0x0010 CO_GENERATOR = 0x0020 -class AppPyCode(Wrappable): - """ applevel representation of a PyCode object. """ - def __init__(self, pycode, space): - self.space = space - self.pycode = pycode - - def __unwrap__(self): - return self.pycode - - def pypy_id(self): - # XXX we need a type system for internal objects! - return id(self.pycode) - - def pypy_type(self): - # XXX we need a type system for internal objects! - return self.space.wrap(self.__class__) - - def app_visible(self): - - # XXX change that if we have type objects ... - l = [] - for name,value in self.pycode.__dict__.items(): - if name.startswith('co_'): - l.append( (name, self.space.wrap(value))) - l.append(('__class__', self.pypy_type())) - return l - class PyCode(eval.Code): "CPython-style code objects." @@ -66,9 +38,6 @@ self.co_firstlineno = 0 # first source line number self.co_lnotab = "" # string: encoding addr<->lineno mapping - def __wrap__(self, space): - return space.wrap(AppPyCode(self, space)) - def _from_code(self, code): """ Initialize the code object from a real (CPython) one. This is just a hack, until we have our own compile. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py Wed Jun 2 19:27:47 2004 @@ -7,7 +7,7 @@ from pypy.interpreter import pytraceback -class PyFrame(eval.Frame, baseobjspace.Wrappable): +class PyFrame(eval.Frame): """Represents a frame for a regular Python function that needs to be interpreted. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Wed Jun 2 19:27:47 2004 @@ -5,9 +5,9 @@ from pypy.interpreter.gateway import interp2app class TypeDef: - def __init__(self, name, rawdict): - self.name = name - self.rawdict = rawdict + def __init__(self, __name, **rawdict): + self.name = __name + self.rawdict = rawdict def mro(self, space): return [self, space.object_typedef] @@ -22,9 +22,9 @@ def descr_property_get(space, w_property, w_obj, w_ignored): return space.unwrap(w_property).fget(space, w_obj) - typedef = TypeDef("GetSetProperty", { - '__get__' : interp2app(descr_property_get), - }) + typedef = TypeDef("GetSetProperty", + __get__ = interp2app(descr_property_get), + ) def attrproperty(name): def fget(space, w_obj): @@ -42,3 +42,68 @@ return w_value return GetSetProperty(fget) + +# ____________________________________________________________ +# +# Definition of the type's descriptors for all the internal types + +from pypy.interpreter.eval import Code, Frame +from pypy.interpreter.pycode import PyCode +from pypy.interpreter.pyframe import PyFrame +from pypy.interpreter.module import Module +from pypy.interpreter.function import Function, Method + +Code.typedef = TypeDef('internal-code', + co_name = attrproperty('co_name'), + # XXX compute more co_xxx from the methods in Code + ) + +Frame.typedef = TypeDef('internal-frame', + f_code = attrproperty('code'), + #f_locals = GetSetProperty(getdictscope, setdictscope), XXX + f_globals = attrproperty_w('w_globals'), + ) + +PyCode.typedef = TypeDef('code', + co_argcount = attrproperty('co_argcount'), + co_nlocals = attrproperty('co_nlocals'), + co_stacksize = attrproperty('co_stacksize'), + co_flags = attrproperty('co_flags'), + co_code = attrproperty('co_code'), + co_consts = attrproperty('co_consts'), + co_names = attrproperty('co_names'), + co_varnames = attrproperty('co_varnames'), + co_freevars = attrproperty('co_freevars'), + co_cellvars = attrproperty('co_cellvars'), + co_filename = attrproperty('co_filename'), + co_name = attrproperty('co_name'), + co_firstlineno = attrproperty('co_firstlineno'), + co_lnotab = attrproperty('co_lnotab'), + ) + +PyFrame.typedef = TypeDef('frame', + f_builtins = attrproperty_w('w_builtins'), + **Frame.typedef.rawdict) + +Module.typedef = TypeDef("module", + __dict__ = attrproperty_w('w_dict'), + ) + +Function.typedef = TypeDef("function", + __call__ = interp2app(Function.call.im_func), + __get__ = interp2app(Function.descr_function_get.im_func), + func_code = attrproperty('code'), + func_doc = attrproperty('doc'), + func_name = attrproperty('name'), + func_dict = attrproperty_w('w_func_dict'), + __dict__ = attrproperty_w('w_func_dict'), + # XXX func_closure, __name__, __doc__, etc.pp + ) + +Method.typedef = TypeDef("method", + __call__ = interp2app(Method.call.im_func), + im_func = attrproperty_w('w_function'), + im_self = attrproperty_w('w_instance'), + im_class = attrproperty_w('w_class'), + # XXX getattribute/setattribute etc.pp + ) From arigo at codespeak.net Wed Jun 2 19:30:40 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 2 Jun 2004 19:30:40 +0200 (MEST) Subject: [pypy-svn] r4834 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040602173040.E2CC75BE09@thoth.codespeak.net> Author: arigo Date: Wed Jun 2 19:30:39 2004 New Revision: 4834 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py pypy/branch/src-newobjectmodel/pypy/interpreter/pytraceback.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Log: Tracebacks, and removed the last app_visible()s. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py Wed Jun 2 19:30:39 2004 @@ -81,19 +81,6 @@ break self.exceptionstack.pop() - ### application level visible attributes ### - def app_visible(self): - def makedict(**kw): return kw - space = self.space - d = makedict( - f_code = space.wrap(self.code), - f_locals = self.getdictscope(), - f_globals = self.w_globals, - f_builtins = self.w_builtins, - # XXX f_lasti, f_back, f_exc*, f_restricted need to do pypy_getattr directly - ) - return d.items() - ### Frame Blocks ### class FrameBlock: Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pytraceback.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/pytraceback.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/pytraceback.py Wed Jun 2 19:30:39 2004 @@ -18,18 +18,6 @@ self.lineno = lineno self.next = next - ### application level visible attributes ### - def app_visible(self): - def makedict(**kw): return kw - space = self.space - d = makedict( - tb_frame = space.wrap(self.frame), - tb_lasti = space.wrap(self.lasti), - tb_lineno = space.wrap(self.lineno), - tb_next = space.wrap(self.next), - ) - return d.items() - def record_application_traceback(space, operror, frame, last_instruction): lineno = offset2lineno(frame.code, last_instruction) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Wed Jun 2 19:30:39 2004 @@ -52,6 +52,7 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.module import Module from pypy.interpreter.function import Function, Method +from pypy.interpreter.pytraceback import PyTraceback Code.typedef = TypeDef('internal-code', co_name = attrproperty('co_name'), @@ -107,3 +108,10 @@ im_class = attrproperty_w('w_class'), # XXX getattribute/setattribute etc.pp ) + +PyTraceback.typedef = TypeDef("traceback", + tb_frame = attrproperty('tb_frame'), + tb_lasti = attrproperty('tb_lasti'), + tb_lineno = attrproperty('tb_line'), + tb_next = attrproperty('tb_next'), + ) From pedronis at codespeak.net Wed Jun 2 19:35:32 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 2 Jun 2004 19:35:32 +0200 (MEST) Subject: [pypy-svn] r4835 - pypy/branch/src-newobjectmodel/pypy/objspace/descr Message-ID: <20040602173532.AB1A25BE0A@thoth.codespeak.net> Author: pedronis Date: Wed Jun 2 19:35:28 2004 New Revision: 4835 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Log: added helper to invoke __cmp__ for comparisons method impls Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Wed Jun 2 19:35:28 2004 @@ -44,6 +44,36 @@ # rest of 1 args methods # special cases +# helper for invoking __cmp__ + +def _cmp(space,w_obj1,w_obj2): + w_typ1 = space.type(w_obj1) + w_typ2 = space.type(w_obj2) + if space.issubtype(w_typ1,w_typ2): + w_right_impl = space.lookup(w_obj2, '__cmp__') + if w_right_impl is not None: + w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return space.neg(w_res) + w_left_impl = space.lookup(w_obj1, '__cmp__') + if w_left_impl is not None: + w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return w_res + else: + w_left_impl = space.lookup(w_obj1, '__cmp__') + if w_left_impl is not None: + w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return w_res + w_right_impl = space.lookup(w_obj2, '__cmp__') + if w_right_impl is not None: + w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return space.neg(w_res) + raise OperationError(space.w_TypeError) # xxx error + + # regular methods def helpers def _make_binary_impl(specialnames): From arigo at codespeak.net Wed Jun 2 19:41:01 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 2 Jun 2004 19:41:01 +0200 (MEST) Subject: [pypy-svn] r4836 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040602174101.79D5D5BE0A@thoth.codespeak.net> Author: arigo Date: Wed Jun 2 19:41:00 2004 New Revision: 4836 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Log: Starts to look like it is crashing in the expected way. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Wed Jun 2 19:41:00 2004 @@ -8,7 +8,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.gateway import interp2app class Function(Wrappable): """A function is a code object captured with some environment: Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py Wed Jun 2 19:41:00 2004 @@ -16,6 +16,7 @@ except ImportError: WeakKeyDictionary = dict # XXX for PyPy from pypy.interpreter import eval, pycode +from pypy.interpreter.function import Function, Method from pypy.interpreter.baseobjspace import Wrappable, ObjSpace @@ -153,8 +154,12 @@ assert self.code.ismethod, ( 'global built-in function %r used as method' % self.code.func) - fn = self.get_function(obj.space) - return fn.__get__(obj, cls) + space = obj.space + fn = self.get_function(space) + if cls is None: + cls = obj.__class__ + return Method(space, space.wrap(fn), + space.wrap(obj), space.wrap(cls)) def get_function(self, space): try: @@ -188,7 +193,6 @@ if space in self.functioncache: fn = self.functioncache[space] else: - from pypy.interpreter.function import Function defs = self.getdefaults(space) # needs to be implemented by subclass fn = Function(space, self.code, w_globals, defs, forcename = self.name) self.functioncache[space] = fn Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Wed Jun 2 19:41:00 2004 @@ -97,8 +97,10 @@ func_doc = attrproperty('doc'), func_name = attrproperty('name'), func_dict = attrproperty_w('w_func_dict'), + __doc__ = attrproperty('doc'), + __name__ = attrproperty('name'), __dict__ = attrproperty_w('w_func_dict'), - # XXX func_closure, __name__, __doc__, etc.pp + # XXX func_closure, etc.pp ) Method.typedef = TypeDef("method", From pedronis at codespeak.net Wed Jun 2 19:49:09 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 2 Jun 2004 19:49:09 +0200 (MEST) Subject: [pypy-svn] r4837 - pypy/branch/src-newobjectmodel/pypy/objspace/descr Message-ID: <20040602174909.49DDE5BE4C@thoth.codespeak.net> Author: pedronis Date: Wed Jun 2 19:49:08 2004 New Revision: 4837 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Log: make descr import Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Wed Jun 2 19:49:08 2004 @@ -109,7 +109,7 @@ # add regular methods for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: if not hasattr(DescrObjSpace,_name): - if _arity == 2: # binary + if _arity == 2 and len(_specialnames) == 2: # binary setattr(DescrObjSpace,_name,_make_binary_impl(_specialnames)) From hpk at codespeak.net Wed Jun 2 20:14:06 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 2 Jun 2004 20:14:06 +0200 (MEST) Subject: [pypy-svn] r4838 - in pypy/branch/src-newobjectmodel/pypy/objspace: . descr Message-ID: <20040602181406.3E8F55BE07@thoth.codespeak.net> Author: hpk Date: Wed Jun 2 20:14:05 2004 New Revision: 4838 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: added call to DescrObjSpace added lookup to TrivObjSpace Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Wed Jun 2 20:14:05 2004 @@ -4,6 +4,13 @@ class DescrObjSpace(ObjSpace): + def call(space, w_obj, w_args, w_kwargs): + w_descr = space.lookup(w_obj, '__call__') + if w_descr is None: + raise OperationError(space.w_TypeError, + space.wrap('object is not callable')) + return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) + def getattr(space,w_obj,w_name): w_descr = space.lookup(w_obj,'__getattribute__') try: Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Wed Jun 2 20:14:05 2004 @@ -384,6 +384,20 @@ def round(self, *args): return round(*args) + def lookup(space, w_obj, name): + if isinstance(w_obj, Wrappable): + for basedef in w_obj.TypeDef.mro(): + if name in basedef.rawdict: + return space.wrap(basedef.rawdict[name]) + return None + else: + for cls in w_obj.__class__.__mro__: + if name in cls.__dict__: + return cls.__dict__[name] + return None + + + for m in ObjSpace.MethodTable: if not hasattr(TrivialObjSpace, m[0]): print m[0] # this should raise something From pedronis at codespeak.net Wed Jun 2 20:19:22 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 2 Jun 2004 20:19:22 +0200 (MEST) Subject: [pypy-svn] r4839 - pypy/branch/src-newobjectmodel/pypy/objspace/descr Message-ID: <20040602181922.B584F5BE07@thoth.codespeak.net> Author: pedronis Date: Wed Jun 2 20:19:22 2004 New Revision: 4839 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Log: some helpers Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Wed Jun 2 20:19:22 2004 @@ -50,7 +50,23 @@ # xxx todo rest of 0 args methods # rest of 1 args methods # special cases + + +# helpers + +def _invoke_binop(self,methname,w_obj1,w_obj2): + w__impl = space.lookup(w_obj1, methoname) + if w_left_impl is not None: + w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) + else: + return space.w_NotImplemented + + +def _isnt_notimplemented(space,w_obj): + return not space.is_true(space.is_(w_res.space.w_NotImplemented)): + + # helper for invoking __cmp__ def _cmp(space,w_obj1,w_obj2): @@ -60,7 +76,7 @@ w_right_impl = space.lookup(w_obj2, '__cmp__') if w_right_impl is not None: w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + if return space.neg(w_res) w_left_impl = space.lookup(w_obj1, '__cmp__') if w_left_impl is not None: From pedronis at codespeak.net Wed Jun 2 20:23:17 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 2 Jun 2004 20:23:17 +0200 (MEST) Subject: [pypy-svn] r4840 - in pypy/branch/src-newobjectmodel/pypy/objspace: . descr Message-ID: <20040602182317.611345BE09@thoth.codespeak.net> Author: pedronis Date: Wed Jun 2 20:23:16 2004 New Revision: 4840 Added: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py - copied unchanged from r4839, pypy/branch/src-newobjectmodel/pypy/objspace/descr/objspace.py Removed: pypy/branch/src-newobjectmodel/pypy/objspace/descr/ Log: rename to descroperation.py From pedronis at codespeak.net Wed Jun 2 20:24:56 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 2 Jun 2004 20:24:56 +0200 (MEST) Subject: [pypy-svn] r4841 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040602182456.C8D9C5BE09@thoth.codespeak.net> Author: pedronis Date: Wed Jun 2 20:24:56 2004 New Revision: 4841 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: rename DescrObjSpace to DescrOperation, make it a mix-in Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Wed Jun 2 20:24:56 2004 @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import * -class DescrObjSpace(ObjSpace): +class DescrOperation: def call(space, w_obj, w_args, w_kwargs): w_descr = space.lookup(w_obj, '__call__') From hpk at codespeak.net Thu Jun 3 09:19:43 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Jun 2004 09:19:43 +0200 (MEST) Subject: [pypy-svn] r4842 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040603071943.2F9155BE07@thoth.codespeak.net> Author: hpk Date: Thu Jun 3 09:19:40 2004 New Revision: 4842 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Log: moved generator to typedef-descriptor scheme Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Thu Jun 3 09:19:40 2004 @@ -3,7 +3,7 @@ from pypy.interpreter.miscutils import Stack, getthreadlocals import pypy.module -__all__ = ['ObjSpace', 'OperationError', 'NoValue'] +__all__ = ['ObjSpace', 'OperationError', 'NoValue', 'Wrappable'] class Wrappable(object): Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py Thu Jun 3 09:19:40 2004 @@ -44,10 +44,10 @@ self.frame = frame self.running = False - def pypy_iter(self): + def descr__iter__(self): return self.space.wrap(self) - def pypy_next(self): + def descr_next(self): # raise NoValue when exhausted if self.running: space = self.frame.space @@ -66,21 +66,16 @@ finally: self.running = False + # XXX the next two methods we don't really want here, + # it appears to be there for trivial object space def next(self): try: - return self.pypy_next() + return self.descr_next() # except NoValue: raise OperationError(self.space.w_StopIteration, self.space.w_None) app_next = gateway.interp2app(next) - def pypy_getattr(self, w_attr): - # XXX boilerplate that should disappear at some point - attr = self.space.unwrap(w_attr) - if attr == 'next': - return self.space.wrap(self.app_next) - raise OperationError(self.space.w_AttributeError, w_attr) - # XXX the following is for TrivialObjSpace only, when iteration is # done by C code (e.g. when calling 'list(g())'). def __iter__(self): Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Thu Jun 3 09:19:40 2004 @@ -53,6 +53,7 @@ from pypy.interpreter.module import Module from pypy.interpreter.function import Function, Method from pypy.interpreter.pytraceback import PyTraceback +from pypy.interpreter.generator import GeneratorIterator Code.typedef = TypeDef('internal-code', co_name = attrproperty('co_name'), @@ -117,3 +118,10 @@ tb_lineno = attrproperty('tb_line'), tb_next = attrproperty('tb_next'), ) + +GeneratorIterator.typedef = TypeDef("generator", + next = interp2app(GeneratorIterator.descr_next.im_func), + __iter__ = interp2app(GeneratorIterator.descr__iter__.im_func), + gi_running = attrproperty('running'), + gi_frame = attrproperty('frame'), +) From pedronis at codespeak.net Thu Jun 3 09:34:52 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 3 Jun 2004 09:34:52 +0200 (MEST) Subject: [pypy-svn] r4843 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603073452.8ECAF5BE07@thoth.codespeak.net> Author: pedronis Date: Thu Jun 3 09:34:51 2004 New Revision: 4843 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: added more operations support missing pow,not_, round and ord Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 09:34:51 2004 @@ -1,7 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import * - class DescrOperation: def call(space, w_obj, w_args, w_kwargs): @@ -11,6 +10,24 @@ space.wrap('object is not callable')) return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) + def get(space,w_descr,w_obj,w_type): + w_get = space.lookup(w_descr,'__get__') + if w_get is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call(w_descr,w_obj,w_type) + + def set(space,w_descr,w_obj,w_val): + w_get = space.lookup(w_descr,'__set__') + if w_get is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call(w_descr,w_obj,w_val) + + def delete(space,w_descr,w_obj): + w_get = space.lookup(w_descr,'__get__') + if w_get is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call(w_descr,w_obj) + def getattr(space,w_obj,w_name): w_descr = space.lookup(w_obj,'__getattribute__') try: @@ -41,100 +58,177 @@ w_descr = space.lookup(w_obj,'__repr__') return space.get_and_call_function(w_descr,w_obj) - def pos(space,w_obj): - w_descr = space.lookup(w_obj,'__pos__') + def contains(space,w_obj,w_val): + w_descr = space.lookup(w_obj,'__contains__') + if w_descr is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call_function(w_descr,w_obj,w_val) + + def iter(space,w_obj): + w_descr = space.lookup(w_obj,'__delattr__') if w_descr is None: raise OperationError(space.w_TypeError) # xxx error return space.get_and_call_function(w_descr,w_obj) - # xxx todo rest of 0 args methods - # rest of 1 args methods - # special cases + def getitem(space,w_obj,w_key): + w_descr = space.lookup(w_obj,'__getitem__') + if w_descr is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call_function(w_descr,w_obj,w_key) + def setitem(space,w_obj,w_key,w_val): + w_descr = space.lookup(w_obj,'__setitem__') + if w_descr is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call_function(w_descr,w_obj,w_key,w_val) -# helpers + def delitem(space,w_obj,w_key): + w_descr = space.lookup(w_obj,'__delitem__') + if w_descr is None: + raise OperationError(space.w_TypeError) # xxx error + return space.get_and_call_function(w_descr,w_obj,w_key) -def _invoke_binop(self,methname,w_obj1,w_obj2): - w__impl = space.lookup(w_obj1, methoname) - if w_left_impl is not None: - w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) - else: - return space.w_NotImplemented + # special cases + + # xxx what about not_,round,ord -def _isnt_notimplemented(space,w_obj): - return not space.is_true(space.is_(w_res.space.w_NotImplemented)): - +# helpers +def _invoke_binop(self,w_impl,w_obj1,w_obj2): + if w_impl is not None: + w_res = space.get_and_call_function(w_impl,w_obj1,w_obj2) + if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + return w_res + return None # helper for invoking __cmp__ +def _conditional_neg(space,w_obj,flag): + if flag: + return space.neg(w_obj) + else: + return w_obj + def _cmp(space,w_obj1,w_obj2): w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) - if space.issubtype(w_typ1,w_typ2): - w_right_impl = space.lookup(w_obj2, '__cmp__') - if w_right_impl is not None: - w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) - if - return space.neg(w_res) - w_left_impl = space.lookup(w_obj1, '__cmp__') - if w_left_impl is not None: - w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): - return w_res + w_left_impl = space.lookup(w_obj1,'__cmp__') + do_neg1 = False + do_neg2 = True + if space.is_true(space.is_(w_typ1,w_typ2)): + w_right_impl = None else: - w_left_impl = space.lookup(w_obj1, '__cmp__') - if w_left_impl is not None: - w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): - return w_res - w_right_impl = space.lookup(w_obj2, '__cmp__') - if w_right_impl is not None: - w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): - return space.neg(w_res) + w_right_impl = space.lookup(w_obj2,'__cmp__') + if 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 + do_neg1,do_neg2 = do_neg2,do_neg1 + + w_res = _invoke_binop(w_left_impl,w_obj1,w_obj2) + if w_res is not None: + return _conditional_neg(space,w_res,do_neg1) + w_res = _invoke_binop(w_right_impl,w_obj2,w_obj1) + if w_res is not None: + return _conditional_neg(space,w_res,do_neg2) raise OperationError(space.w_TypeError) # xxx error - - # regular methods def helpers -def _make_binary_impl(specialnames): + +def _make_binop_impl(specialnames): left, right = specialnames - def binary_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) - if space.issubtype(w_typ1,w_typ2): - w_right_impl = space.lookup(w_obj2, right) - if w_right_impl is not None: - w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): - return w_res - w_left_impl = space.lookup(w_obj1, left) - if w_left_impl is not None: - w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): - return w_res + w_left_impl = space.lookup(w_obj1,left) + if space.is_true(space.is_(w_typ1,w_typ2)): + w_right_impl = None else: - w_left_impl = space.lookup(w_obj1, left) - if w_left_impl is not None: - w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): - return w_res - w_right_impl = space.lookup(w_obj2, right) - if w_right_impl is not None: - w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): - return w_res + w_right_impl = space.lookup(w_obj2,right) + if 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(w_left_impl,w_obj1,w_obj2) + if w_res is not None: + return w_res + w_res = _invoke_binop(w_right_impl,w_obj2,w_obj1) + if w_res is not None: + return w_res raise OperationError(space.w_TypeError) # xxx error - return binary_impl + return binop_impl + +def _make_comparison_impl(specialnames): + left, right = specialnames + def comparison_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) + w_first = w_obj1 + w_second = w_obj2 + + 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.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(w_left_impl,w_obj1,w_obj2) + if w_res is not None: + return w_res + w_res = _invoke_binop(w_right_impl,w_obj2,w_obj1) + if w_res is not None: + return w_res + w_res = _cmp(space,w_first,w_second) + # fallback: lt(a,b) <= lt(cmp(a,b),0) ... + if space.is_true(comparison_impl(space,w_res,space.wrap(0))): + return space.w_True + else: + return space.w_False + + return comparison_impl + +def _make_inplace_impl(specialnames): + specialname, = specialnames + def inplace_impl(space,w_lhs,w_rhs): + w_impl = space.lookup(w_lhs,specialname) + if w_impl is None: + raise OperationError(space.w_TypeError) # xxx error + space.get_and_call_function(w_impl,w_lhs,w_rhs) + return inplace_impl + +def _make_unaryop_impl(specialnames): + def unaryop_impl(space,w_obj): + w_impl = space.lookup(w_obj,specialname) + if w_impl is None: + raise OperationError(space.w_TypeError) # xxx error + space.get_and_call_function(w_impl,w_obj) + return unaryop_impl + # add regular methods -for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if not hasattr(DescrObjSpace,_name): - if _arity == 2 and len(_specialnames) == 2: # binary - setattr(DescrObjSpace,_name,_make_binary_impl(_specialnames)) - - +for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: + if not hasattr(DescrOperation,_name): + _impl_maker = None + if _arity ==2 and _name in ['lt','le','gt','ge','ne','eq']: + #print "comparison",_specialnames + _impl_maker = _make_comparison_impl + elif _arity == 2 and _name.startswith('inplace_'): + #print "inplace",_specialnames + _impl_maker = _make_inplace_impl + elif _arity == 2 and len(_specialnames) == 2: + #print "binop",_specialnames + _impl_maker = _make_binop_impl + elif _arity == 1 and len(_specialnames) == 1: + #print "unaryop",_specialnames + _impl_maker = _make_unaryop_impl + if _impl_maker: + setattr(DescrOperation,_name,_impl_maker(_specialnames)) + elif _name not in ['id','type','issubtype']: + print "missing %s" % _name + + From pedronis at codespeak.net Thu Jun 3 09:39:44 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 3 Jun 2004 09:39:44 +0200 (MEST) Subject: [pypy-svn] r4844 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603073944.005FB5BE07@thoth.codespeak.net> Author: pedronis Date: Thu Jun 3 09:39:44 2004 New Revision: 4844 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: fixed some get_and_call -> get_and_call_function Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 09:39:44 2004 @@ -14,19 +14,19 @@ w_get = space.lookup(w_descr,'__get__') if w_get is None: raise OperationError(space.w_TypeError) # xxx error - return space.get_and_call(w_descr,w_obj,w_type) + return space.get_and_call_function(w_descr,w_obj,w_type) def set(space,w_descr,w_obj,w_val): w_get = space.lookup(w_descr,'__set__') if w_get is None: raise OperationError(space.w_TypeError) # xxx error - return space.get_and_call(w_descr,w_obj,w_val) + return space.get_and_call_function(w_descr,w_obj,w_val) def delete(space,w_descr,w_obj): w_get = space.lookup(w_descr,'__get__') if w_get is None: raise OperationError(space.w_TypeError) # xxx error - return space.get_and_call(w_descr,w_obj) + return space.get_and_call_function(w_descr,w_obj) def getattr(space,w_obj,w_name): w_descr = space.lookup(w_obj,'__getattribute__') From pedronis at codespeak.net Thu Jun 3 09:50:12 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 3 Jun 2004 09:50:12 +0200 (MEST) Subject: [pypy-svn] r4845 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603075012.BE2BA5BE07@thoth.codespeak.net> Author: pedronis Date: Thu Jun 3 09:50:12 2004 New Revision: 4845 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: reduce imports Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 09:50:12 2004 @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import * +from pypy.interpreter.baseobjspace import ObjSpace class DescrOperation: @@ -89,9 +89,11 @@ return space.get_and_call_function(w_descr,w_obj,w_key) - # special cases + # not_ has a default implementation + + # xxx round, not_ + - # xxx what about not_,round,ord # helpers @@ -227,7 +229,9 @@ _impl_maker = _make_unaryop_impl if _impl_maker: setattr(DescrOperation,_name,_impl_maker(_specialnames)) - elif _name not in ['id','type','issubtype']: + elif _name not in ['id','type','issubtype', + # not really to be defined in DescrOperation + 'ord','not_','round']: print "missing %s" % _name From hpk at codespeak.net Thu Jun 3 09:57:52 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Jun 2004 09:57:52 +0200 (MEST) Subject: [pypy-svn] r4846 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603075752.E851A5BE07@thoth.codespeak.net> Author: hpk Date: Thu Jun 3 09:57:52 2004 New Revision: 4846 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: more steps toward getting trivspace working again Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Thu Jun 3 09:57:52 2004 @@ -25,6 +25,7 @@ def __init__(self): "Basic initialization of objects." + # sets all the internal descriptors self.initialize() def make_builtins(self): Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Thu Jun 3 09:57:52 2004 @@ -166,7 +166,7 @@ return wrap(Method(space, wrap(self), None, w_cls)) -class Method(object): +class Method(Wrappable): """A method is a function bound to a specific instance or class.""" def __init__(self, space, w_function, w_instance, w_class): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 09:57:52 2004 @@ -1,9 +1,40 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import ObjSpace +class Object: + def descr__getattribute__(space, w_obj, w_name): + name = space.unwrap(w_name) + w_descr = space.lookup(w_obj, name) + if w_descr is not None: + if space.is_data_descr(w_descr): # + return space.get(w_descr,w_obj,space.type(w_obj)) + w_dict = space.getdict(w_obj) # + if w_dict is not None: + try: + return space.getitem(w_dict,w_name) + except OperationError, e: + if not e.match(space,space.w_KeyError): + raise + if w_descr is not None: + return space.get(w_descr,w_obj,space.wrap(type)) + raise OperationError(space.w_AttributeError,w_name) + class DescrOperation: + def getdict(self, w_obj): + if isinstance(w_obj, Wrappable): + descr = self.lookup(w_obj, '__dict__') + if descr is None: + return None + return #w_dict + else: + try: + return w_obj.__dict__ + except AttributeError: + return None + def call(space, w_obj, w_args, w_kwargs): + print "call %r, %r, %r" %(w_obj, w_args, w_kwargs) w_descr = space.lookup(w_obj, '__call__') if w_descr is None: raise OperationError(space.w_TypeError, Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 09:57:52 2004 @@ -6,63 +6,11 @@ from pypy.interpreter import pyframe, gateway from pypy.interpreter.baseobjspace import * -import operator, types, new, sys, __builtin__ +from pypy.objspace.descroperation import DescrOperation +import operator, types, new, sys +import __builtin__ as cpy_builtin -##class nugen(object): -## def __init__(self, frame): -## self.space = frame.space -## self.frame = frame -## self.running = 0 - -## def next(self): -## if self.running: -## raise OperationError(self.space.w_ValueError, -## "generator already executing") -## ec = self.space.getexecutioncontext() - -## self.running = 1 -## try: -## try: -## ret = ec.eval_frame(self.frame) -## except NoValue: -## raise StopIteration -## finally: -## self.running = 0 - -## return ret - -## def __iter__(self): -## return self - -##from pypy.interpreter.gateway import InterpretedFunction, InterpretedFunctionFromCode - -##class numeth(InterpretedFunction): -## def __init__(self, ifunc, instance, cls): -## self.ifunc = ifunc -## self.instance = instance -## self.cls = cls - -## def __call__(self, *args, **kws): -## if self.instance is None and self.cls is not type(None): -## pass -## else: -## args = (self.instance,) + args -## return self.ifunc(*args, **kws) - -##class nufun(InterpretedFunctionFromCode): - -## def __call__(self, *args, **kwargs): -## if self.cpycode.co_flags & 0x0020: -## frame = self.create_frame(args, kwargs) -## return nugen(frame) -## else: -## return self.eval_frame(args, kwargs) - -## def __get__(self, ob, cls=None): -## return numeth(self, ob, cls) - - -class TrivialObjSpace(ObjSpace): +class TrivialObjSpace(ObjSpace, DescrOperation): def clone_exception_hierarchy(self): def __init__(self, *args): @@ -117,6 +65,12 @@ return done def initialize(self): + from pypy.interpreter.typedef import TypeDef + + self.object_typedef = TypeDef('object', + __getattribute__ = interp2app(descroperation.object_getattribute), + ) + self.w_None = None self.w_True = True self.w_False = False @@ -131,13 +85,13 @@ #"xrange": xrange, "slice": slice, } - for n, c in __builtin__.__dict__.iteritems(): - if n in ['xrange', # we define this in builtin_app - 'staticmethod', - 'classmethod', - 'property', - ]: - continue + for n, c in cpy_builtin.__dict__.iteritems(): + #if n in ['xrange', # we define this in builtin_app + # 'staticmethod', + # 'classmethod', + # 'property', + # ]: + # continue if isinstance(c, types.TypeType): setattr(self, 'w_' + c.__name__, c) newstuff[c.__name__] = c @@ -150,16 +104,20 @@ # general stuff def wrap(self, x): - if hasattr(type(x), '__wrap__'): + if isinstance(x, Wrappable): return x.__wrap__(self) else: return x def unwrap(self, w): - if hasattr(type(w), '__unwrap__'): - w = w.__unwrap__() + #if hasattr(type(w), '__unwrap__'): + # w = w.__unwrap__() return w + def is_(self, w_obj1, w_obj2): + return self.unwrap(w_obj1) is self.unwrap(w_obj2) + + def reraise(self): #import traceback #traceback.print_exc() @@ -187,8 +145,6 @@ def _auto(name, sourcefn, classlocals): s = """ def %(name)s(self, x, *args): - if hasattr(type(x), 'pypy_%(name)s'): - return x.pypy_%(name)s(*args) try: value = %(sourcefn)s(x, *args) except: @@ -206,58 +162,63 @@ is_true = operator.truth # 'is_true' is not called 'truth' because it returns a *non-wrapped* boolean - for _name in ('id', 'type', 'iter', 'repr', 'str', 'len', + for _name in ('id', 'repr', 'str', 'type', 'pow', 'divmod', 'hash', 'setattr', 'delattr', 'hex', 'oct', 'ord', 'getattr'): _auto(_name, _name, locals()) - for _name in ('pos', 'neg', 'not_', 'abs', 'invert', - 'mul', 'truediv', 'floordiv', 'div', 'mod', - 'add', 'sub', 'lshift', 'rshift', 'and_', 'xor', 'or_', - 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'contains'): - _auto(_name, 'operator.' + _name, locals()) +# for _name in ('id', 'type', 'iter', 'repr', 'str', 'len', +# 'pow', 'divmod', 'hash', 'setattr', 'delattr', 'hex', +# 'oct', 'ord', 'getattr'): +# _auto(_name, _name, locals()) +# + #for _name in ('pos', 'neg', 'not_', 'abs', 'invert', + # 'mul', 'truediv', 'floordiv', 'div', 'mod', + # 'add', 'sub', 'lshift', 'rshift', 'and_', 'xor', 'or_', + # 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'contains'): + # _auto(_name, 'operator.' + _name, locals()) # in-place operators - def inplace_pow(self, w1, w2): - w1 **= w2 - return self.wrap(w1) - def inplace_mul(self, w1, w2): - w1 *= w2 - return self.wrap(w1) - def inplace_truediv(self, w1, w2): - w1 /= w2 # XXX depends on compiler flags - return self.wrap(w1) - def inplace_floordiv(self, w1, w2): - w1 //= w2 - return self.wrap(w1) - def inplace_div(self, w1, w2): - w1 /= w2 # XXX depends on compiler flags - return self.wrap(w1) - def inplace_mod(self, w1, w2): - w1 %= w2 - return self.wrap(w1) - - def inplace_add(self, w1, w2): - w1 += w2 - return self.wrap(w1) - def inplace_sub(self, w1, w2): - w1 -= w2 - return self.wrap(w1) - def inplace_lshift(self, w1, w2): - w1 <<= w2 - return self.wrap(w1) - def inplace_rshift(self, w1, w2): - w1 >>= w2 - return self.wrap(w1) - def inplace_and(self, w1, w2): - w1 &= w2 - return self.wrap(w1) - def inplace_or(self, w1, w2): - w1 |= w2 - return self.wrap(w1) - def inplace_xor(self, w1, w2): - w1 ^= w2 - return self.wrap(w1) + #def inplace_pow(self, w1, w2): + # w1 **= w2 + # return self.wrap(w1) + #def inplace_mul(self, w1, w2): + # w1 *= w2 + # return self.wrap(w1) + #def inplace_truediv(self, w1, w2): + # w1 /= w2 # XXX depends on compiler flags + # return self.wrap(w1) + #def inplace_floordiv(self, w1, w2): + # w1 //= w2 + # return self.wrap(w1) + #def inplace_div(self, w1, w2): + # w1 /= w2 # XXX depends on compiler flags + # return self.wrap(w1) + #def inplace_mod(self, w1, w2): + # w1 %= w2 + # return self.wrap(w1) + + #def inplace_add(self, w1, w2): + # w1 += w2 + # return self.wrap(w1) + #def inplace_sub(self, w1, w2): + # w1 -= w2 + # return self.wrap(w1) + #def inplace_lshift(self, w1, w2): + # w1 <<= w2 + # return self.wrap(w1) + #def inplace_rshift(self, w1, w2): + # w1 >>= w2 + # return self.wrap(w1) + #def inplace_and(self, w1, w2): + # w1 &= w2 + # return self.wrap(w1) + #def inplace_or(self, w1, w2): + # w1 |= w2 + # return self.wrap(w1) + #def inplace_xor(self, w1, w2): + # w1 ^= w2 + # return self.wrap(w1) # slicing @@ -311,13 +272,13 @@ self.reraise() # misc - def next(self, w): - if hasattr(w, 'pypy_next'): - return w.pypy_next() - try: - return self.wrap(w.next()) - except StopIteration: - raise NoValue + #def next(self, w): + # if hasattr(w, 'pypy_next'): + # return w.pypy_next() + # try: + # return self.wrap(w.next()) + # except StopIteration: + # raise NoValue def newstring(self, asciilist): try: @@ -325,40 +286,40 @@ except: self.reraise() - def call(self, callable, args, kwds): - if isinstance(callable, types.ClassType): - import new - try: - r = new.instance(callable) - except: - self.reraise() - if hasattr(r, '__init__'): - self.call(r.__init__, args, kwds) - return self.wrap(r) - #if (isinstance(callable, types.MethodType) + #def call(self, callable, args, kwds): + # if isinstance(callable, types.ClassType): + # import new + # try: + # r = new.instance(callable) + # except: + # self.reraise() + # if hasattr(r, '__init__'): + # self.call(r.__init__, args, kwds) + # return self.wrap(r) + # #if (isinstance(callable, types.MethodType) # and callable.im_self is not None): # args = (callable.im_self,) + args # callable = callable.im_func - assert not isinstance(callable, gateway.Gateway), ( - "trivial object space is detecting an object that has not " - "been wrapped") - if hasattr(callable, 'pypy_call'): - return callable.pypy_call(args, kwds) - try: - return self.wrap(callable(*args, **(kwds or {}))) - except OperationError: - raise - except: - #print "got exception in", callable.__name__ - #print "len args", len(args) - #print "kwds", kwds - self.reraise() - - def get(self, descr, ob, cls): - try: - return self.wrap(descr.__get__(ob, cls)) - except: - self.reraise() + # assert not isinstance(callable, gateway.Gateway), ( + # "trivial object space is detecting an object that has not " + # "been wrapped") + # if hasattr(callable, 'pypy_call'): + # return callable.pypy_call(args, kwds) + # try: + # return self.wrap(callable(*args, **(kwds or {}))) + # except OperationError: + # raise + # except: + # #print "got exception in", callable.__name__ + # #print "len args", len(args) + # #print "kwds", kwds + # self.reraise() + # + #def get(self, descr, ob, cls): + # try: + # return self.wrap(descr.__get__(ob, cls)) + # except: + # self.reraise() def new(self, type, args, kw): return self.wrap(type(args, kw)) @@ -366,27 +327,27 @@ def init(self, type, args, kw): pass - def set(self, descr, ob, val): - descr.__set__(ob, val) + #def set(self, descr, ob, val): + # descr.__set__(ob, val) - def delete(self, descr, ob): - descr.__delete__(ob) + #def delete(self, descr, ob): + # descr.__delete__(ob) - def nonzero(self, ob): - return not not ob + #def nonzero(self, ob): + # return not not ob - def float(self, ob): - return float(ob) + #def float(self, ob): + # return float(ob) - def int(self, ob): - return int(ob) + #def int(self, ob): + # return int(ob) - def round(self, *args): - return round(*args) + #def round(self, *args): + # return round(*args) def lookup(space, w_obj, name): if isinstance(w_obj, Wrappable): - for basedef in w_obj.TypeDef.mro(): + for basedef in w_obj.typedef.mro(space): if name in basedef.rawdict: return space.wrap(basedef.rawdict[name]) return None From pedronis at codespeak.net Thu Jun 3 10:05:28 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 3 Jun 2004 10:05:28 +0200 (MEST) Subject: [pypy-svn] r4847 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603080528.766725BE07@thoth.codespeak.net> Author: pedronis Date: Thu Jun 3 10:05:27 2004 New Revision: 4847 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: get operation should fallback to return obj Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 10:05:27 2004 @@ -44,19 +44,21 @@ def get(space,w_descr,w_obj,w_type): w_get = space.lookup(w_descr,'__get__') if w_get is None: - raise OperationError(space.w_TypeError) # xxx error + return w_obj return space.get_and_call_function(w_descr,w_obj,w_type) def set(space,w_descr,w_obj,w_val): w_get = space.lookup(w_descr,'__set__') if w_get is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("object is not a descriptor with set")) return space.get_and_call_function(w_descr,w_obj,w_val) def delete(space,w_descr,w_obj): w_get = space.lookup(w_descr,'__get__') if w_get is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("object is not a descriptor with delete")) return space.get_and_call_function(w_descr,w_obj) def getattr(space,w_obj,w_name): @@ -72,13 +74,15 @@ def setattr(space,w_obj,w_name,w_val): w_descr = space.lookup(w_obj,'__setattr__') if w_descr is None: - raise OperationError(space.w_AttributeError) # xxx error + raise OperationError(space.w_AttributeError, + space.wrap("object is readonly")) return space.get_and_call_function(w_descr,w_obj,w_name,w_val) def delattr(space,w_obj,w_name): w_descr = space.lookup(w_obj,'__delattr__') if w_descr is None: - raise OperationError(space.w_AttributeError) # xxx error + raise OperationError(space.w_AttributeError, + space.wrap("object does not support attribute removal")) return space.get_and_call_function(w_descr,w_obj,w_name) def str(space,w_obj): @@ -92,31 +96,36 @@ def contains(space,w_obj,w_val): w_descr = space.lookup(w_obj,'__contains__') if w_descr is None: - raise OperationError(space.w_TypeError) # xxx error + 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,'__delattr__') + w_descr = space.lookup(w_obj,'__iter__') if w_descr is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("object is not iter()-able")) return space.get_and_call_function(w_descr,w_obj) def getitem(space,w_obj,w_key): w_descr = space.lookup(w_obj,'__getitem__') if w_descr is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("cannot get items from object")) return space.get_and_call_function(w_descr,w_obj,w_key) def setitem(space,w_obj,w_key,w_val): w_descr = space.lookup(w_obj,'__setitem__') if w_descr is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("cannot set items on object")) return space.get_and_call_function(w_descr,w_obj,w_key,w_val) def delitem(space,w_obj,w_key): w_descr = space.lookup(w_obj,'__delitem__') if w_descr is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("cannot delete items from object")) return space.get_and_call_function(w_descr,w_obj,w_key) From pedronis at codespeak.net Thu Jun 3 10:13:04 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 3 Jun 2004 10:13:04 +0200 (MEST) Subject: [pypy-svn] r4848 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603081304.47A435BE07@thoth.codespeak.net> Author: pedronis Date: Thu Jun 3 10:13:03 2004 New Revision: 4848 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: more draft error messages for operations Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 10:13:03 2004 @@ -131,7 +131,7 @@ # not_ has a default implementation - # xxx round, not_ + # xxx round, ord @@ -173,11 +173,12 @@ w_res = _invoke_binop(w_right_impl,w_obj2,w_obj1) if w_res is not None: return _conditional_neg(space,w_res,do_neg2) - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("operands do not support comparison")) # regular methods def helpers -def _make_binop_impl(specialnames): +def _make_binop_impl(symbol,specialnames): left, right = specialnames def binop_impl(space,w_obj1,w_obj2): w_typ1 = space.type(w_obj1) @@ -197,10 +198,11 @@ w_res = _invoke_binop(w_right_impl,w_obj2,w_obj1) if w_res is not None: return w_res - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("operands do not support binary %s" % symbol)) return binop_impl -def _make_comparison_impl(specialnames): +def _make_comparison_impl(symbol,specialnames): left, right = specialnames def comparison_impl(space,w_obj1,w_obj2): w_typ1 = space.type(w_obj1) @@ -232,20 +234,22 @@ return comparison_impl -def _make_inplace_impl(specialnames): +def _make_inplace_impl(symbol,specialnames): specialname, = specialnames def inplace_impl(space,w_lhs,w_rhs): w_impl = space.lookup(w_lhs,specialname) if w_impl is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("operands do not support inplace %s" % symbol)) space.get_and_call_function(w_impl,w_lhs,w_rhs) return inplace_impl -def _make_unaryop_impl(specialnames): +def _make_unaryop_impl(symbol,specialnames): def unaryop_impl(space,w_obj): w_impl = space.lookup(w_obj,specialname) if w_impl is None: - raise OperationError(space.w_TypeError) # xxx error + raise OperationError(space.w_TypeError, + space.wrap("operand does not support unary %s" % symbol)) space.get_and_call_function(w_impl,w_obj) return unaryop_impl @@ -268,7 +272,7 @@ #print "unaryop",_specialnames _impl_maker = _make_unaryop_impl if _impl_maker: - setattr(DescrOperation,_name,_impl_maker(_specialnames)) + setattr(DescrOperation,_name,_impl_maker(_symbol,_specialnames)) elif _name not in ['id','type','issubtype', # not really to be defined in DescrOperation 'ord','not_','round']: From pedronis at codespeak.net Thu Jun 3 10:17:37 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 3 Jun 2004 10:17:37 +0200 (MEST) Subject: [pypy-svn] r4849 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603081737.15CED5BE07@thoth.codespeak.net> Author: pedronis Date: Thu Jun 3 10:17:36 2004 New Revision: 4849 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: fix ./, typo Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 10:17:36 2004 @@ -140,7 +140,7 @@ def _invoke_binop(self,w_impl,w_obj1,w_obj2): if w_impl is not None: w_res = space.get_and_call_function(w_impl,w_obj1,w_obj2) - if not space.is_true(space.is_(w_res.space.w_NotImplemented)): + if not space.is_true(space.is_(w_res,space.w_NotImplemented)): return w_res return None From ale at codespeak.net Thu Jun 3 10:27:33 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 3 Jun 2004 10:27:33 +0200 (MEST) Subject: [pypy-svn] r4850 - pypy/branch/ale_translator_stuff/test Message-ID: <20040603082733.66F2B5BE07@thoth.codespeak.net> Author: ale Date: Thu Jun 3 10:27:32 2004 New Revision: 4850 Modified: pypy/branch/ale_translator_stuff/test/snippet.py Log: Added a generator to the snippet collection Modified: pypy/branch/ale_translator_stuff/test/snippet.py ============================================================================== --- pypy/branch/ale_translator_stuff/test/snippet.py (original) +++ pypy/branch/ale_translator_stuff/test/snippet.py Thu Jun 3 10:27:32 2004 @@ -377,3 +377,7 @@ z = Z() z.my_attribute = v return z.my_method() + +def simple_generator(): + for i in range(5): + yield i \ No newline at end of file From pedronis at codespeak.net Thu Jun 3 10:51:49 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 3 Jun 2004 10:51:49 +0200 (MEST) Subject: [pypy-svn] r4851 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603085149.7B80B5BE07@thoth.codespeak.net> Author: pedronis Date: Thu Jun 3 10:51:48 2004 New Revision: 4851 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: try at pow (__pow__,__rpow__) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 10:51:48 2004 @@ -128,7 +128,32 @@ space.wrap("cannot delete items from object")) return space.get_and_call_function(w_descr,w_obj,w_key) + def pow(space,w_obj1,w_obj2,w_obj3): + w_typ1 = space.type(w_obj1) + w_typ2 = space.type(w_obj2) + w_left_impl = space.lookup(w_obj1,'__pow__') + if space.is_true(space.is_(w_typ1,w_typ2)): + w_right_impl = None + else: + w_right_impl = space.lookup(w_obj2,'__rpow__') + if 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 + if w_left_impl is not None: + w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2, + w_obj3) + if _check_notimplemented(w_res): + return w_res + if w_right_impl is not None: + w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1, + w_obj3) + if _check_notimplemented(w_res): + return w_res + raise OperationError(space.w_TypeError, + space.wrap("operands do not support **")) + + # not_ has a default implementation # xxx round, ord @@ -137,10 +162,13 @@ # helpers -def _invoke_binop(self,w_impl,w_obj1,w_obj2): +def _check_notimplemented(space,w_obj): + return not space.is_true(space.is_(w_res,space.w_NotImplemented)) + +def _invoke_binop(space,w_impl,w_obj1,w_obj2): if w_impl is not None: w_res = space.get_and_call_function(w_impl,w_obj1,w_obj2) - if not space.is_true(space.is_(w_res,space.w_NotImplemented)): + if _check_notimplemented(w_res): return w_res return None @@ -245,6 +273,7 @@ return inplace_impl def _make_unaryop_impl(symbol,specialnames): + specialname, = specialnames def unaryop_impl(space,w_obj): w_impl = space.lookup(w_obj,specialname) if w_impl is None: @@ -276,7 +305,7 @@ elif _name not in ['id','type','issubtype', # not really to be defined in DescrOperation 'ord','not_','round']: - print "missing %s" % _name + raise Exception,"missing def for operation%s" % _name From arigo at codespeak.net Thu Jun 3 11:04:10 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 11:04:10 +0200 (MEST) Subject: [pypy-svn] r4852 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603090410.B8BAC5BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 11:04:10 2004 New Revision: 4852 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: More progress... Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Thu Jun 3 11:04:10 2004 @@ -165,6 +165,13 @@ else: return wrap(Method(space, wrap(self), None, w_cls)) + def descr_function_call(self, *args_w, **kwds_w): + # XXX refactor to avoid unwrapping and rewrapping all around + space = self.space + return self.call(space.newtuple(args_w), + space.newdict([(space.wrap(key), w_item) + for key, w_item in kwds_w])) + class Method(Wrappable): """A method is a function bound to a specific instance or class.""" @@ -192,3 +199,10 @@ raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) return self.space.call(self.w_function, w_args, w_kwds) + + def descr_method_call(self, *args_w, **kwds_w): + # XXX refactor to avoid unwrapping and rewrapping all around + space = self.space + return self.call(space.newtuple(args_w), + space.newdict([(space.wrap(key), w_item) + for key, w_item in kwds_w])) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Thu Jun 3 11:04:10 2004 @@ -92,7 +92,7 @@ ) Function.typedef = TypeDef("function", - __call__ = interp2app(Function.call.im_func), + __call__ = interp2app(Function.descr_function_call.im_func), __get__ = interp2app(Function.descr_function_get.im_func), func_code = attrproperty('code'), func_doc = attrproperty('doc'), @@ -105,7 +105,7 @@ ) Method.typedef = TypeDef("method", - __call__ = interp2app(Method.call.im_func), + __call__ = interp2app(Method.descr_method_call.im_func), im_func = attrproperty_w('w_function'), im_self = attrproperty_w('w_instance'), im_class = attrproperty_w('w_class'), Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 11:04:10 2004 @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.baseobjspace import ObjSpace, NoValue +from pypy.interpreter.function import Function class Object: def descr__getattribute__(space, w_obj, w_name): @@ -21,17 +22,39 @@ class DescrOperation: - def getdict(self, w_obj): - if isinstance(w_obj, Wrappable): - descr = self.lookup(w_obj, '__dict__') - if descr is None: - return None - return #w_dict + def getdict(space, w_obj): + w_descr = space.lookup(w_obj, '__dict__') + if w_descr is None: + return None + return space.get_and_call_function(w_descr, w_obj) + + def is_data_descr(space, w_obj): + # XXX check this logic + return (space.lookup(w_obj, '__set__') is not None and + space.lookup(w_obj, '__get__') is not None) + + def get_and_call(space, w_descr, w_obj, w_args, w_kwargs): + if isinstance(w_descr, Function): # wrapped Function actually + # special-case Functions to avoid infinite recursion + args_w = space.unpacktuple(w_args) + args_w = [w_obj] + args_w + w_args = space.newtuple(args_w) + return w_descr.call(w_args, w_kwargs) else: - try: - return w_obj.__dict__ - except AttributeError: - return None + w_impl = space.get(w_descr, w_obj, space.type(w_obj)) + return space.call(w_impl, w_args, w_kwargs) + + def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w): + if isinstance(w_descr, Function): # wrapped Function actually + # special-case Functions to avoid infinite recursion + args_w = [w_obj] + list(args_w) + w_args = space.newtuple(args_w) + w_kwargs = space.newdict([(space.wrap(key), w_item) + for key, w_item in kwargs_w]) + return w_descr.call(w_args, w_kwargs) + else: + w_impl = space.get(w_descr, w_obj, space.type(w_obj)) + return space.call_function(w_impl, *args_w, **kwargs_w) def call(space, w_obj, w_args, w_kwargs): print "call %r, %r, %r" %(w_obj, w_args, w_kwargs) @@ -65,7 +88,7 @@ w_descr = space.lookup(w_obj,'__getattribute__') try: return space.get_and_call_function(w_descr,w_obj,w_name) - except OperatioError,e: + except OperationError,e: if not e.match(space,space.w_AttributeError): raise w_descr = space.lookup(w_obj,'__getattr__') @@ -107,6 +130,18 @@ space.wrap("object is not iter()-able")) return space.get_and_call_function(w_descr,w_obj) + def next(space,w_obj): + w_descr = space.lookup(w_obj,'next') + if w_descr is None: + raise OperationError(space.w_TypeError, + space.wrap("iterator has no next() method")) + try: + return space.get_and_call_function(w_descr,w_obj) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + raise NoValue + def getitem(space,w_obj,w_key): w_descr = space.lookup(w_obj,'__getitem__') if w_descr is None: @@ -142,12 +177,12 @@ if w_left_impl is not None: w_res = space.get_and_call_function(w_left_impl,w_obj1,w_obj2, w_obj3) - if _check_notimplemented(w_res): + if _check_notimplemented(space,w_res): return w_res if w_right_impl is not None: w_res = space.get_and_call_function(w_right_impl,w_obj2,w_obj1, w_obj3) - if _check_notimplemented(w_res): + if _check_notimplemented(space,w_res): return w_res raise OperationError(space.w_TypeError, @@ -163,12 +198,12 @@ # helpers def _check_notimplemented(space,w_obj): - return not space.is_true(space.is_(w_res,space.w_NotImplemented)) + return not space.is_true(space.is_(w_obj,space.w_NotImplemented)) def _invoke_binop(space,w_impl,w_obj1,w_obj2): if w_impl is not None: w_res = space.get_and_call_function(w_impl,w_obj1,w_obj2) - if _check_notimplemented(w_res): + if _check_notimplemented(space,w_res): return w_res return None @@ -195,10 +230,10 @@ w_left_impl,w_right_impl = w_right_impl,w_left_impl do_neg1,do_neg2 = do_neg2,do_neg1 - w_res = _invoke_binop(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 _conditional_neg(space,w_res,do_neg1) - w_res = _invoke_binop(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 _conditional_neg(space,w_res,do_neg2) raise OperationError(space.w_TypeError, @@ -220,10 +255,10 @@ w_obj1,w_obj2 = w_obj2,w_obj1 w_left_impl,w_right_impl = w_right_impl,w_left_impl - w_res = _invoke_binop(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(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, @@ -247,10 +282,10 @@ w_obj1,w_obj2 = w_obj2,w_obj1 w_left_impl,w_right_impl = w_right_impl,w_left_impl - w_res = _invoke_binop(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(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 w_res = _cmp(space,w_first,w_second) @@ -269,7 +304,7 @@ if w_impl is None: raise OperationError(space.w_TypeError, space.wrap("operands do not support inplace %s" % symbol)) - space.get_and_call_function(w_impl,w_lhs,w_rhs) + return space.get_and_call_function(w_impl,w_lhs,w_rhs) return inplace_impl def _make_unaryop_impl(symbol,specialnames): @@ -279,7 +314,7 @@ if w_impl is None: raise OperationError(space.w_TypeError, space.wrap("operand does not support unary %s" % symbol)) - space.get_and_call_function(w_impl,w_obj) + return space.get_and_call_function(w_impl,w_obj) return unaryop_impl Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 11:04:10 2004 @@ -6,7 +6,7 @@ from pypy.interpreter import pyframe, gateway from pypy.interpreter.baseobjspace import * -from pypy.objspace.descroperation import DescrOperation +from pypy.objspace.descroperation import DescrOperation, Object import operator, types, new, sys import __builtin__ as cpy_builtin @@ -68,7 +68,7 @@ from pypy.interpreter.typedef import TypeDef self.object_typedef = TypeDef('object', - __getattribute__ = interp2app(descroperation.object_getattribute), + __getattribute__ = gateway.interp2app(Object.descr__getattribute__.im_func), ) self.w_None = None @@ -104,7 +104,7 @@ # general stuff def wrap(self, x): - if isinstance(x, Wrappable): + if hasattr(type(x), '__wrap__'): return x.__wrap__(self) else: return x @@ -115,8 +115,11 @@ return w def is_(self, w_obj1, w_obj2): - return self.unwrap(w_obj1) is self.unwrap(w_obj2) + return self.unwrap(w_obj1) is self.unwrap(w_obj2) + def unpacktuple(self, w_tuple): + assert isinstance(w_tuple, tuple) + return list(w_tuple) def reraise(self): #import traceback @@ -162,9 +165,7 @@ is_true = operator.truth # 'is_true' is not called 'truth' because it returns a *non-wrapped* boolean - for _name in ('id', 'repr', 'str', 'type', - 'pow', 'divmod', 'hash', 'setattr', 'delattr', 'hex', - 'oct', 'ord', 'getattr'): + for _name in ('id', 'type', 'ord'): _auto(_name, _name, locals()) # for _name in ('id', 'type', 'iter', 'repr', 'str', 'len', @@ -234,42 +235,42 @@ return start, stop return None - def getitem(self, w_obj, w_index): - obj = self.unwrap(w_obj) - index = self.unwrap(w_index) - sindex = self.old_slice(index) - try: - if sindex is None: - return self.wrap(obj[index]) - else: - return self.wrap(operator.getslice(obj, sindex[0], sindex[1])) - except: - self.reraise() - - def setitem(self, w_obj, w_index, w_value): - obj = self.unwrap(w_obj) - index = self.unwrap(w_index) - value = self.unwrap(w_value) - sindex = self.old_slice(index) - try: - if sindex is None: - obj[index] = value - else: - operator.setslice(obj, sindex[0], sindex[1], value) - except: - self.reraise() - - def delitem(self, w_obj, w_index): - obj = self.unwrap(w_obj) - index = self.unwrap(w_index) - sindex = self.old_slice(index) - try: - if sindex is None: - del obj[index] - else: - operator.delslice(obj, sindex[0], sindex[1]) - except: - self.reraise() +## def getitem(self, w_obj, w_index): +## obj = self.unwrap(w_obj) +## index = self.unwrap(w_index) +## sindex = self.old_slice(index) +## try: +## if sindex is None: +## return self.wrap(obj[index]) +## else: +## return self.wrap(operator.getslice(obj, sindex[0], sindex[1])) +## except: +## self.reraise() + +## def setitem(self, w_obj, w_index, w_value): +## obj = self.unwrap(w_obj) +## index = self.unwrap(w_index) +## value = self.unwrap(w_value) +## sindex = self.old_slice(index) +## try: +## if sindex is None: +## obj[index] = value +## else: +## operator.setslice(obj, sindex[0], sindex[1], value) +## except: +## self.reraise() + +## def delitem(self, w_obj, w_index): +## obj = self.unwrap(w_obj) +## index = self.unwrap(w_index) +## sindex = self.old_slice(index) +## try: +## if sindex is None: +## del obj[index] +## else: +## operator.delslice(obj, sindex[0], sindex[1]) +## except: +## self.reraise() # misc #def next(self, w): @@ -357,6 +358,27 @@ return cls.__dict__[name] return None + def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): + if isinstance(w_descr, Wrappable): + return DescrOperation.get_and_call(self, w_descr, w_obj, + w_args, w_kwargs) + else: + try: + impl = w_descr.__get__(w_obj, type(w_obj)) + return impl(*w_args, **w_kwargs) + except: + self.reraise() + + def get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w): + if isinstance(w_descr, Wrappable): + return DescrOperation.get_and_call_function(self, w_descr, w_obj, + *args_w, **kwargs_w) + else: + try: + impl = w_descr.__get__(w_obj, type(w_obj)) + return impl(*args_w, **kwargs_w) + except: + self.reraise() for m in ObjSpace.MethodTable: From arigo at codespeak.net Thu Jun 3 11:24:01 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 11:24:01 +0200 (MEST) Subject: [pypy-svn] r4853 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603092401.E8DCA5BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 11:24:01 2004 New Revision: 4853 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Progressing.... Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Thu Jun 3 11:24:01 2004 @@ -98,6 +98,9 @@ w_id_y = self.id(w_y) return self.eq(w_id_x, w_id_y) + def not_(self, w_obj): # default implementation + return self.wrap(not self.is_true(w_obj)) + def unwrapdefault(self, w_value, default): if w_value is None or w_value == self.w_None: return default Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Thu Jun 3 11:24:01 2004 @@ -3,6 +3,7 @@ """ from pypy.interpreter.gateway import interp2app +from pypy.interpreter.baseobjspace import Wrappable class TypeDef: def __init__(self, __name, **rawdict): @@ -12,7 +13,7 @@ def mro(self, space): return [self, space.object_typedef] -class GetSetProperty: +class GetSetProperty(Wrappable): def __init__(self, fget, fset=None, fdel=None, doc=None): self.fget = fget self.fset = fset Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 11:24:01 2004 @@ -57,7 +57,7 @@ return space.call_function(w_impl, *args_w, **kwargs_w) def call(space, w_obj, w_args, w_kwargs): - print "call %r, %r, %r" %(w_obj, w_args, w_kwargs) + #print "call %r, %r, %r" %(w_obj, w_args, w_kwargs) w_descr = space.lookup(w_obj, '__call__') if w_descr is None: raise OperationError(space.w_TypeError, @@ -91,8 +91,10 @@ except OperationError,e: if not e.match(space,space.w_AttributeError): raise - w_descr = space.lookup(w_obj,'__getattr__') - return space.get_and_call_function(w_descr,w_obj,w_name) + w_descr = space.lookup(w_obj,'__getattr__') + if w_descr is None: + raise + return space.get_and_call_function(w_descr,w_obj,w_name) def setattr(space,w_obj,w_name,w_val): w_descr = space.lookup(w_obj,'__setattr__') Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 11:24:01 2004 @@ -69,6 +69,8 @@ self.object_typedef = TypeDef('object', __getattribute__ = gateway.interp2app(Object.descr__getattribute__.im_func), + __str__ = gateway.interp2app(lambda space, w_x: str(w_x)), + __repr__ = gateway.interp2app(lambda space, w_x: repr(w_x)), ) self.w_None = None @@ -378,11 +380,12 @@ impl = w_descr.__get__(w_obj, type(w_obj)) return impl(*args_w, **kwargs_w) except: + #import traceback; traceback.print_exc() self.reraise() for m in ObjSpace.MethodTable: if not hasattr(TrivialObjSpace, m[0]): - print m[0] # this should raise something + print 'XXX there is no', m[0], 'in TrivialObjSpace' Space = TrivialObjSpace From arigo at codespeak.net Thu Jun 3 11:41:30 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 11:41:30 +0200 (MEST) Subject: [pypy-svn] r4855 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603094130.626C35BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 11:41:29 2004 New Revision: 4855 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Seems to work! Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py Thu Jun 3 11:41:29 2004 @@ -141,7 +141,7 @@ # to call the Gateway as a non-method, 'space' must be explicitely # supplied. We build the Function object and call it. fn = self.get_function(space) - return fn(*args_w, **kwds_w) + return fn.descr_function_call(*args_w, **kwds_w) def __get__(self, obj, cls=None): # to get the Gateway as a method out of an instance, we build a Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 11:41:29 2004 @@ -1,3 +1,4 @@ +import operator from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import ObjSpace, NoValue from pypy.interpreter.function import Function @@ -26,7 +27,7 @@ w_descr = space.lookup(w_obj, '__dict__') if w_descr is None: return None - return space.get_and_call_function(w_descr, w_obj) + return space.get(w_descr, w_obj, space.type(w_obj)) def is_data_descr(space, w_obj): # XXX check this logic @@ -68,21 +69,21 @@ w_get = space.lookup(w_descr,'__get__') if w_get is None: return w_obj - return space.get_and_call_function(w_descr,w_obj,w_type) + return space.get_and_call_function(w_get,w_descr,w_obj,w_type) def set(space,w_descr,w_obj,w_val): - w_get = space.lookup(w_descr,'__set__') - if w_get is None: + w_set = space.lookup(w_descr,'__set__') + if w_set is None: raise OperationError(space.w_TypeError, space.wrap("object is not a descriptor with set")) - return space.get_and_call_function(w_descr,w_obj,w_val) + return space.get_and_call_function(w_set,w_descr,w_obj,w_val) def delete(space,w_descr,w_obj): - w_get = space.lookup(w_descr,'__get__') - if w_get is None: + w_delete = space.lookup(w_descr,'__delete__') + if w_delete is None: raise OperationError(space.w_TypeError, space.wrap("object is not a descriptor with delete")) - return space.get_and_call_function(w_descr,w_obj) + return space.get_and_call_function(w_delete,w_descr,w_obj) def getattr(space,w_obj,w_name): w_descr = space.lookup(w_obj,'__getattribute__') @@ -269,6 +270,7 @@ def _make_comparison_impl(symbol,specialnames): left, right = specialnames + op = getattr(operator, left) def comparison_impl(space,w_obj1,w_obj2): w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) @@ -290,12 +292,10 @@ w_res = _invoke_binop(space,w_right_impl,w_obj2,w_obj1) if w_res is not None: return w_res - w_res = _cmp(space,w_first,w_second) # fallback: lt(a,b) <= lt(cmp(a,b),0) ... - if space.is_true(comparison_impl(space,w_res,space.wrap(0))): - return space.w_True - else: - return space.w_False + w_res = _cmp(space,w_first,w_second) + res = space.unwrap(w_res) + return space.wrap(op(res, 0)) return comparison_impl Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 11:41:29 2004 @@ -167,7 +167,7 @@ is_true = operator.truth # 'is_true' is not called 'truth' because it returns a *non-wrapped* boolean - for _name in ('id', 'type', 'ord'): + for _name in ('id', 'type', 'ord', 'round'): _auto(_name, _name, locals()) # for _name in ('id', 'type', 'iter', 'repr', 'str', 'len', From arigo at codespeak.net Thu Jun 3 11:49:42 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 11:49:42 +0200 (MEST) Subject: [pypy-svn] r4856 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603094942.B8F7D5BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 11:49:42 2004 New Revision: 4856 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Everything is fine apart from the tests. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/pyframe.py Thu Jun 3 11:49:42 2004 @@ -51,6 +51,7 @@ except OperationError, e: pytraceback.record_application_traceback( self.space, e, self, last_instr) + executioncontext.exception_trace(e) # convert an OperationError into a control flow # exception import sys @@ -250,7 +251,6 @@ def action(self, frame, last_instr, executioncontext): e = self.args[0] frame.last_exception = e - executioncontext.exception_trace(e) ControlFlowException.action(self, frame, last_instr, executioncontext) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 11:49:42 2004 @@ -65,12 +65,13 @@ return done def initialize(self): - from pypy.interpreter.typedef import TypeDef + from pypy.interpreter.typedef import TypeDef, GetSetProperty self.object_typedef = TypeDef('object', __getattribute__ = gateway.interp2app(Object.descr__getattribute__.im_func), __str__ = gateway.interp2app(lambda space, w_x: str(w_x)), __repr__ = gateway.interp2app(lambda space, w_x: repr(w_x)), + __class__ = GetSetProperty(self.__class__.type), ) self.w_None = None From ale at codespeak.net Thu Jun 3 12:19:53 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 3 Jun 2004 12:19:53 +0200 (MEST) Subject: [pypy-svn] r4858 - pypy/branch/ale_translator_stuff Message-ID: <20040603101953.25CE35BE07@thoth.codespeak.net> Author: ale Date: Thu Jun 3 12:19:52 2004 New Revision: 4858 Modified: pypy/branch/ale_translator_stuff/codewriter.py pypy/branch/ale_translator_stuff/genpyrex.py Log: Using the old naming logic Modified: pypy/branch/ale_translator_stuff/codewriter.py ============================================================================== --- pypy/branch/ale_translator_stuff/codewriter.py (original) +++ pypy/branch/ale_translator_stuff/codewriter.py Thu Jun 3 12:19:52 2004 @@ -1,3 +1,4 @@ +from pypy.objspace.flow.model import Variable, Constant, UndefinedConstant class CodeWriter: @@ -16,22 +17,95 @@ def write_rec(block,indentation_level=0): for item in block: if isinstance(item,str): - print >>file," "*indentation_level+item + print >>file, " "*indentation_level + item else: write_rec(item,indentation_level+1) write_rec(self.blocks) - def name(self,obj): + def xx_name(self,obj): + print "Name, ",repr(obj) if obj in self.known_names: return self.known_names[obj] else: name=getattr(obj,'__name__','Var') if name in self.unique_val: self.unique_val[name]+=1 - name=name+'__'+str(self.unique_val[name]) + name=name+'_'+str(self.unique_val[name]) else: self.unique_val[name]=0 self.known_names[obj]=name return name + + def _hackname(self, value): + try: + name = value.__name__ + except AttributeError: + pass + else: + import types + if isinstance(value, (types.FunctionType, types.ClassType, type)): + # XXX! use the id of the value to make unique function and + # class names + return '%s__%x' % (name, id(value)) + elif isinstance(value, types.BuiltinFunctionType): + return str(name) + if isinstance(value, int): + value = int(value) # cast subclasses of int (i.e. bools) to ints + return repr(value) + + def get_functionname(self,function): + return function.func_name + + def name(self, obj): + if isinstance(obj, Variable): + #self.variablelocations[obj] = block + return self.get_varname(obj) + elif isinstance(obj, Constant): + return self._hackname(obj.value) + else: + print "Type error" + raise TypeError("Unknown class: %s" % obj.__class__) + def get_type(self, var): + if isinstance(var, Constant): + return type(var.value) + elif self.annotator: + return self.annotator.gettype(var) + else: + return None + + def get_classname(self, userclass): + return self._hackname(userclass) + + def _vardecl(self, var): + vartype, varname = self._paramvardecl(var) + if vartype != "object": + return "cdef %s %s" % (vartype, varname) + else: + return "" + + def get_varname(self, var): + vartype = self.get_type(var) + if vartype in (int, bool): + prefix = "i_" + elif self.annotator and vartype in self.annotator.getuserclasses(): + prefix = "p_" + else: + prefix = "" + return prefix + var.name + + def _paramvardecl(self, var): + vartype = self.get_type(var) + ctype=self._gettypename(vartype) + return (ctype, self.get_varname(var)) + + def _gettypename(self, vartype): + if vartype in (int, bool): + ctype = "int" + elif self.annotator and vartype in self.annotator.getuserclasses(): + ctype = self.get_classname(vartype) + else: + ctype = "object" + return ctype + \ No newline at end of file Modified: pypy/branch/ale_translator_stuff/genpyrex.py ============================================================================== --- pypy/branch/ale_translator_stuff/genpyrex.py (original) +++ pypy/branch/ale_translator_stuff/genpyrex.py Thu Jun 3 12:19:52 2004 @@ -10,7 +10,7 @@ from pypy.annotation.model import SomeMethod from pypy.translator.codewriter import CodeWriter -Op={'next' :'', +Op={ 'getitem' :"%s = %s[%s]", 'newtuple' :"%s = (%s)", 'newlist' :"%s = [%s]", @@ -24,7 +24,8 @@ 'not' :"%s = not %s", 'is_true' :"%s = not not %s", 'exception' :"%s, last_exc = last_exc, None" , - 'generic' :"%s = %s(%s)" + 'generic' :"%s = %s(%s)" , + 'next' :'', } class GenPyrex(CodeWriter): @@ -34,12 +35,10 @@ self.annotator=annotator self.blockids={} ops = {} - oparity = {} for (opname, opsymbol, arity, _) in ObjSpace.MethodTable: ops[opname] = opsymbol - oparity[opname] = arity self.ops = ops - self.oparity = oparity + def build(self): self.blockids={} @@ -96,14 +95,14 @@ self.blockids={} fungraph=self.translator.getflowgraph(function) self.entrymap = mkentrymap(fungraph) - signature = [ "%s %s"%(self.typename(self.typeof(var)), + signature = [ "%s %s"%(self.typeof(var), self.name(var)) for var in fungraph.getargs() ] signature=",".join(signature) if self.translator.entrypoint is function: - yield "def %s(%s):" % (self.name(function),signature) + yield "def %s(%s):" % (self.get_functionname(function),signature) else: yield "cdef %s %s(%s):" % (self.typeof(fungraph.getreturnvar()), - self.name(function),signature) + self.get_functionname(function),signature) # Building the body of the function body=[] print "Entry map keys",self.entrymap.keys() @@ -142,40 +141,8 @@ yield 'cinline "Label%s:"' % thisone for op in block.operations: # print "making operations %s"%op - argnames = [self.name(arg) for arg in op.args] - resultname = self.name(op.result) - operator = self.ops.get(op.opname, op.opname) - - if operator in ['+','-','*','**','/']: - if len(argnames) == 1: - yield "%s = %s %s" % (resultname, operator) + argnames - elif len(argnames) == 2: - yield "%s = %s %s %s" % (resultname, argnames[0], operator, argnames[1]) - elif len(argnames) == 3 and operator == "**": #special case, have to handle it manually - yield "%s = pow(%s, %s, %s)" % (resultname,) + argnames - else: - raise NotImplementedError, "I don't know to handle the operator %s (arity %s)" \ - % (operator, len(argnames)) - else: - opstring=Op.get(operator,None) - if opstring: - if operator in ['newlist','newtuple']: - format=(resultname,"".join([a+',' for a in argnames])) - elif operator =='newdict': - pairs = [] - for i in range(0, len(argnames), 2): - pairs.append("%s: %s, " % - (argnames[i], argnames[i+1])) - format=(resultname,",".join(pairs)) - elif operator =='simple_call': - format=(resultname,argnames[0], - ",".join(argnames[1:])) - else: - format=(resultname,)+tuple(argnames) - #print opstring,resultname,argnames,format - yield opstring %format - else: - yield Op['generic']%format + for op_string in self.build_operations(op): + yield op_string exits = block.exits if len(exits) == 1: for line in self.gen_link(block, exits[0]): yield line @@ -217,29 +184,55 @@ print "from gen_link", prevblock, "doing", block for line in self.build_block(block): yield line - + def build_operations(self,op): + argnames = [self.name(arg) for arg in op.args] + resultname = self.name(op.result) + operator = self.ops.get(op.opname, op.opname) + + if operator in ['+','-','*','**','/']: + if len(argnames) == 1: + yield "%s = %s %s" % (resultname, operator) + argnames + elif len(argnames) == 2: + yield "%s = %s %s %s" % (resultname, argnames[0], operator, argnames[1]) + elif len(argnames) == 3 and operator == "**": #special case, have to handle it manually + yield "%s = pow(%s, %s, %s)" % (resultname,) + argnames + else: + raise NotImplementedError, "I don't know to handle the operator %s (arity %s)" \ + % (operator, len(argnames)) + else: + opstring=Op.get(operator,None) + format=(resultname,)+tuple([arg for arg in argnames]) + if opstring: + if operator in ['newlist','newtuple']: + format=(resultname,"".join([a+',' for a in argnames])) + elif operator =='newdict': + pairs = [] + for i in range(0, len(argnames), 2): + pairs.append("%s: %s, " % + (argnames[i], argnames[i+1])) + format=(resultname,",".join(pairs)) + elif operator =='simple_call': + format=(resultname,argnames[0], + ",".join([arg for arg in argnames[1:]])) + #print opstring,resultname,argnames,format + yield opstring %format + elif operator == 'next': + yield "try:" + yield [" %s = %s.next()" % (resultname, argnames[0])] + yield "except StopIteration:" + yield [" last_exc = StopIteration"] + yield "else:" + yield [" last_exc = None"] + else: + format=(resultname,) + yield "%s" % format + def typeof(self,var): if isinstance(var, Constant): return self.typename(var.value) else: return self.typename(self.annotator.gettype(var)) - - def varname(self, var): - if isinstance(var, Variable): - vartype = self.typeof(var) - if vartype in (int, bool): - prefix = "i_" - elif vartype in self.annotator.getuserclasses(): - prefix = "p_" - else: - prefix = "" - return prefix + var.name - elif isinstance(var, Constant): - return self.name(var.value) - else: - raise TypeError("Unknown class: %s" % var.__class__) - def typename(self, vartype): if vartype in (int, bool): ctype = "int" From arigo at codespeak.net Thu Jun 3 12:46:48 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 12:46:48 +0200 (MEST) Subject: [pypy-svn] r4862 - in pypy/branch/src-newobjectmodel/pypy: interpreter interpreter/test objspace Message-ID: <20040603104648.395EF5BE4C@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 12:46:47 2004 New Revision: 4862 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/extmodule.py pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: More bug fixes. Soon time to clean up gateway.py... Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/extmodule.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/extmodule.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/extmodule.py Thu Jun 3 12:46:47 2004 @@ -49,11 +49,13 @@ w_builtins = space.w_builtins self.__saved_hooks = {} newhooks = {} - for name, hook in [ - ('__interplevel__exec', self.app_interplevelexec), - ('__interplevel__eval', self.app_interpleveleval), - ('__interplevel__execfile', self.app_interplevelexecfile), - ('__import__', self.app_interplevelimport)]: + + for name, impl in [ + ('__interplevel__exec', self.interplevelexec.im_func), + ('__interplevel__eval', self.interpleveleval.im_func), + ('__interplevel__execfile', self.interplevelexecfile.im_func), + ('__import__', self.interplevelimport.im_func)]: + hook = gateway.interp2app(impl).get_method(self) w_name = space.wrap(name) try: self.__saved_hooks[name] = space.getitem(w_builtins, w_name) @@ -143,11 +145,6 @@ w_modulename, w_globals, w_locals, w_fromlist) - app_interplevelexec = gateway.interp2app(interplevelexec) - app_interpleveleval = gateway.interp2app(interpleveleval) - app_interplevelexecfile = gateway.interp2app(interplevelexecfile) - app_interplevelimport = gateway.interp2app(interplevelimport) - class AppModuleHack: """For interp-level convenience: 'from __applevel__ import func' imports the app-level function 'func' via an appropriate gateway. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py Thu Jun 3 12:46:47 2004 @@ -137,30 +137,6 @@ # and the result is a wrapped version of this Function. return space.wrap(self.get_function(space)) - def __call__(self, space, *args_w, **kwds_w): - # to call the Gateway as a non-method, 'space' must be explicitely - # supplied. We build the Function object and call it. - fn = self.get_function(space) - return fn.descr_function_call(*args_w, **kwds_w) - - def __get__(self, obj, cls=None): - # to get the Gateway as a method out of an instance, we build a - # Function and get it. - if obj is None: - return self # Gateways as unbound methods not implemented - else: - # the object space is implicitely fetched out of the instance - if isinstance(self.code, BuiltinCode): - assert self.code.ismethod, ( - 'global built-in function %r used as method' % - self.code.func) - space = obj.space - fn = self.get_function(space) - if cls is None: - cls = obj.__class__ - return Method(space, space.wrap(fn), - space.wrap(obj), space.wrap(cls)) - def get_function(self, space): try: return self.functioncache[space] @@ -198,6 +174,19 @@ self.functioncache[space] = fn return fn + def get_method(self, obj): + # to get the Gateway as a method out of an instance, we build a + # Function and get it. + # the object space is implicitely fetched out of the instance + if isinstance(self.code, BuiltinCode): + assert self.code.ismethod, ( + 'global built-in function %r used as method' % + self.code.func) + space = obj.space + fn = self.get_function(space) + return Method(space, space.wrap(fn), + space.wrap(obj), space.wrap(obj.__class__)) + class app2interp(Gateway): """Build a Gateway that calls 'app' at app-level.""" @@ -220,6 +209,19 @@ def getdefaults(self, space): return [space.wrap(val) for val in self.staticdefs] + def __call__(self, space, *args_w, **kwds_w): + # to call the Gateway as a non-method, 'space' must be explicitely + # supplied. We build the Function object and call it. + fn = self.get_function(space) + return fn.descr_function_call(*args_w, **kwds_w) + + def __get__(self, obj, cls=None): + if obj is None: + return self + else: + method = self.get_method(obj) + return method.descr_method_call + class interp2app(Gateway): """Build a Gateway that calls 'f' at interp-level.""" def __init__(self, f, app_name=None): Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py Thu Jun 3 12:46:47 2004 @@ -23,7 +23,7 @@ code = space.unwrap(w_code) code.exec_code(space, w_glob, w_glob) - wrappedargs = w(args) + wrappedargs = space.newtuple(args) wrappedfunc = space.getitem(w_glob, w(functionname)) wrappedkwds = space.newdict([]) try: Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 12:46:47 2004 @@ -301,12 +301,17 @@ def _make_inplace_impl(symbol,specialnames): specialname, = specialnames + assert specialname.startswith('__i') and specialname.endswith('__') + noninplacespacemethod = specialname[3:-2] def inplace_impl(space,w_lhs,w_rhs): w_impl = space.lookup(w_lhs,specialname) - if w_impl is None: - raise OperationError(space.w_TypeError, - space.wrap("operands do not support inplace %s" % symbol)) - return space.get_and_call_function(w_impl,w_lhs,w_rhs) + if w_impl is not None: + w_res = space.get_and_call_function(w_impl,w_lhs,w_rhs) + if _check_notimplemented(space,w_res): + return w_res + # XXX fix the error message we get here + return getattr(space, noninplacespacemethod)(w_lhs,w_rhs) + return inplace_impl def _make_unaryop_impl(symbol,specialnames): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 12:46:47 2004 @@ -120,8 +120,11 @@ def is_(self, w_obj1, w_obj2): return self.unwrap(w_obj1) is self.unwrap(w_obj2) - def unpacktuple(self, w_tuple): + def unpacktuple(self, w_tuple, expected_length=None): assert isinstance(w_tuple, tuple) + if expected_length is not None and expected_length != len(w_tuple): + raise ValueError, "got a tuple of length %d instead of %d" % ( + len(w_tuple), expected_length) return list(w_tuple) def reraise(self): From arigo at codespeak.net Thu Jun 3 13:08:24 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 13:08:24 +0200 (MEST) Subject: [pypy-svn] r4863 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603110824.C700C5BE09@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 13:08:24 2004 New Revision: 4863 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Default comparison rules. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 13:08:24 2004 @@ -18,7 +18,7 @@ if not e.match(space,space.w_KeyError): raise if w_descr is not None: - return space.get(w_descr,w_obj,space.wrap(type)) + return space.get(w_descr,w_obj,space.type(w_obj)) raise OperationError(space.w_AttributeError,w_name) class DescrOperation: @@ -239,8 +239,23 @@ w_res = _invoke_binop(space,w_right_impl,w_obj2,w_obj1) if w_res is not None: return _conditional_neg(space,w_res,do_neg2) - raise OperationError(space.w_TypeError, - space.wrap("operands do not support comparison")) + # fall back to internal rules + if space.is_true(space.is_(w_obj1, w_obj2)): + return space.wrap(0) + if space.is_true(space.is_(w_obj1, space.w_None)): + return space.wrap(-1) + if space.is_true(space.is_(w_obj2, space.w_None)): + return space.wrap(1) + if space.is_true(space.is_(w_typ1, w_typ2)): + w_id1 = space.id(w_obj1) + w_id2 = space.id(w_obj2) + else: + w_id1 = space.id(w_typ1) + w_id2 = space.id(w_typ2) + if space.is_true(space.lt(w_id1, w_id2)): + return space.wrap(-1) + else: + return space.wrap(1) # regular methods def helpers Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 13:08:24 2004 @@ -359,9 +359,13 @@ return space.wrap(basedef.rawdict[name]) return None else: - for cls in w_obj.__class__.__mro__: + # hack hack hack: ignore the real 'object' and use our own + for cls in w_obj.__class__.__mro__[:-1]: if name in cls.__dict__: return cls.__dict__[name] + basedef = space.object_typedef + if name in basedef.rawdict: + return space.wrap(basedef.rawdict[name]) return None def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): From arigo at codespeak.net Thu Jun 3 15:31:39 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 15:31:39 +0200 (MEST) Subject: [pypy-svn] r4864 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603133139.B60D05BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 15:31:39 2004 New Revision: 4864 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: object.__setattr__, object.__delattr__, and tiny fixes. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Thu Jun 3 15:31:39 2004 @@ -9,8 +9,6 @@ class Wrappable(object): """A subclass of Wrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" - def __wrap__(self, space): - return self class NoValue(Exception): """Raised to signal absence of value, e.g. in the iterator accessing Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 15:31:39 2004 @@ -8,9 +8,9 @@ name = space.unwrap(w_name) w_descr = space.lookup(w_obj, name) if w_descr is not None: - if space.is_data_descr(w_descr): # + if space.is_data_descr(w_descr): return space.get(w_descr,w_obj,space.type(w_obj)) - w_dict = space.getdict(w_obj) # + w_dict = space.getdict(w_obj) if w_dict is not None: try: return space.getitem(w_dict,w_name) @@ -20,7 +20,32 @@ if w_descr is not None: return space.get(w_descr,w_obj,space.type(w_obj)) raise OperationError(space.w_AttributeError,w_name) - + + def descr__setattr__(space, w_obj, w_name, w_value): + name = space.unwrap(w_name) + w_descr = space.lookup(w_obj, name) + if w_descr is not None: + if space.is_data_descr(w_descr): + return space.set(w_descr,w_obj,w_value) + w_dict = space.getdict(w_obj) + if w_dict is not None: + return space.setitem(w_dict,w_name,w_value) + raise OperationError(space.w_AttributeError,w_name) + + def descr__delattr__(space, w_obj, w_name): + name = space.unwrap(w_name) + w_descr = space.lookup(w_obj, name) + if w_descr is not None: + if space.is_data_descr(w_descr): + return space.delete(w_descr,w_obj) + w_dict = space.getdict(w_obj) + if w_dict is not None: + return space.delitem(w_dict,w_name) + raise OperationError(space.w_AttributeError,w_name) + + def descr__init__(space, w_obj, *args_w, **kwds_w): + pass # XXX some strange checking maybe + class DescrOperation: def getdict(space, w_obj): @@ -30,9 +55,7 @@ return space.get(w_descr, w_obj, space.type(w_obj)) def is_data_descr(space, w_obj): - # XXX check this logic - return (space.lookup(w_obj, '__set__') is not None and - space.lookup(w_obj, '__get__') is not None) + return space.lookup(w_obj, '__set__') is not None def get_and_call(space, w_descr, w_obj, w_args, w_kwargs): if isinstance(w_descr, Function): # wrapped Function actually Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 15:31:39 2004 @@ -69,9 +69,12 @@ self.object_typedef = TypeDef('object', __getattribute__ = gateway.interp2app(Object.descr__getattribute__.im_func), + __setattr__ = gateway.interp2app(Object.descr__setattr__.im_func), + __delattr__ = gateway.interp2app(Object.descr__delattr__.im_func), __str__ = gateway.interp2app(lambda space, w_x: str(w_x)), __repr__ = gateway.interp2app(lambda space, w_x: repr(w_x)), __class__ = GetSetProperty(self.__class__.type), + __init__ = gateway.interp2app(Object.descr__init__.im_func), ) self.w_None = None From hpk at codespeak.net Thu Jun 3 15:42:49 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Jun 2004 15:42:49 +0200 (MEST) Subject: [pypy-svn] r4865 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603134249.BA1705BE07@thoth.codespeak.net> Author: hpk Date: Thu Jun 3 15:42:49 2004 New Revision: 4865 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: - add f_locals - fix delattr to raise attrerror correctly Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py Thu Jun 3 15:42:49 2004 @@ -82,6 +82,9 @@ self.fast2locals() return self.w_locals + def fget_getdictscope(space, self): + return self.getdictscope() + def setdictscope(self, w_locals): "Initialize the locals from a dictionary." self.w_locals = w_locals Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Thu Jun 3 15:42:49 2004 @@ -63,7 +63,8 @@ Frame.typedef = TypeDef('internal-frame', f_code = attrproperty('code'), - #f_locals = GetSetProperty(getdictscope, setdictscope), XXX + f_locals = GetSetProperty(Frame.fget_getdictscope.im_func, + ), # , setdictscope), XXX f_globals = attrproperty_w('w_globals'), ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 15:42:49 2004 @@ -40,7 +40,11 @@ return space.delete(w_descr,w_obj) w_dict = space.getdict(w_obj) if w_dict is not None: - return space.delitem(w_dict,w_name) + try: + return space.delitem(w_dict,w_name) + except OperationError, ex: + if not ex.match(space, space.w_KeyError): + raise raise OperationError(space.w_AttributeError,w_name) def descr__init__(space, w_obj, *args_w, **kwds_w): From mwh at codespeak.net Thu Jun 3 15:46:19 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 3 Jun 2004 15:46:19 +0200 (MEST) Subject: [pypy-svn] r4866 - pypy/branch/src-newobjectmodel/pypy Message-ID: <20040603134619.9AE425BE07@thoth.codespeak.net> Author: mwh Date: Thu Jun 3 15:46:19 2004 New Revision: 4866 Modified: pypy/branch/src-newobjectmodel/pypy/TODO Log: an Idea! Modified: pypy/branch/src-newobjectmodel/pypy/TODO ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/TODO (original) +++ pypy/branch/src-newobjectmodel/pypy/TODO Thu Jun 3 15:46:19 2004 @@ -43,3 +43,6 @@ http://codespeak.net/pypy/index.cgi?doc/objspace/multimethod * enhance the translator components to accept more of PyPy ... + +* add web server thread (!) that allows inspection of e.g. app-level + tracebacks (and stop clogging the user's terminal with them). \ No newline at end of file From mwh at codespeak.net Thu Jun 3 15:46:57 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 3 Jun 2004 15:46:57 +0200 (MEST) Subject: [pypy-svn] r4867 - pypy/branch/src-newobjectmodel/pypy Message-ID: <20040603134657.9E2A15BE07@thoth.codespeak.net> Author: mwh Date: Thu Jun 3 15:46:57 2004 New Revision: 4867 Modified: pypy/branch/src-newobjectmodel/pypy/TODO Log: newline at end of file Modified: pypy/branch/src-newobjectmodel/pypy/TODO ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/TODO (original) +++ pypy/branch/src-newobjectmodel/pypy/TODO Thu Jun 3 15:46:57 2004 @@ -45,4 +45,4 @@ * enhance the translator components to accept more of PyPy ... * add web server thread (!) that allows inspection of e.g. app-level - tracebacks (and stop clogging the user's terminal with them). \ No newline at end of file + tracebacks (and stop clogging the user's terminal with them). From hpk at codespeak.net Thu Jun 3 15:51:28 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Jun 2004 15:51:28 +0200 (MEST) Subject: [pypy-svn] r4868 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040603135128.83A325BE07@thoth.codespeak.net> Author: hpk Date: Thu Jun 3 15:51:27 2004 New Revision: 4868 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Log: - fixed bugs - added func_defaults Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Thu Jun 3 15:51:27 2004 @@ -170,8 +170,13 @@ space = self.space return self.call(space.newtuple(args_w), space.newdict([(space.wrap(key), w_item) - for key, w_item in kwds_w])) + for key, w_item in kwds_w.items()])) + def fget_func_defaults(space, self): + values_w = self.defs_w + if values_w is None: + return space.w_None + return space.newtuple(values_w) class Method(Wrappable): """A method is a function bound to a specific instance or class.""" @@ -205,4 +210,4 @@ space = self.space return self.call(space.newtuple(args_w), space.newdict([(space.wrap(key), w_item) - for key, w_item in kwds_w])) + for key, w_item in kwds_w.items()])) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Thu Jun 3 15:51:27 2004 @@ -15,6 +15,9 @@ class GetSetProperty(Wrappable): def __init__(self, fget, fset=None, fdel=None, doc=None): + fget = getattr(fget, 'im_func', fget) + fset = getattr(fset, 'im_func', fset) + fdel = getattr(fdel, 'im_func', fdel) self.fget = fget self.fset = fset self.fdel = fdel @@ -100,6 +103,7 @@ func_doc = attrproperty('doc'), func_name = attrproperty('name'), func_dict = attrproperty_w('w_func_dict'), + func_defaults = GetSetProperty(Function.fget_func_defaults), __doc__ = attrproperty('doc'), __name__ = attrproperty('name'), __dict__ = attrproperty_w('w_func_dict'), From hpk at codespeak.net Thu Jun 3 15:56:34 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Jun 2004 15:56:34 +0200 (MEST) Subject: [pypy-svn] r4869 - pypy/branch/src-newobjectmodel/pypy/interpreter/test Message-ID: <20040603135634.33C2F5BE07@thoth.codespeak.net> Author: hpk Date: Thu Jun 3 15:56:33 2004 New Revision: 4869 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py Log: fixed broken inter2app test that relied on __call__ Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py Thu Jun 3 15:56:33 2004 @@ -51,7 +51,13 @@ def g3(space, w_a, w_b): return space.add(w_a, w_b) app_g3 = gateway.interp2app(g3) - self.assertEqual_w(app_g3(self.space, w('foo'), w('bar')), w('foobar')) + w_app_g3 = space.wrap(app_g3) + self.assertEqual_w( + space.call(w_app_g3, + space.newtuple(w('foo'), w('bar')), w('foobar')) + self.assertEqual_w( + space.call_function(w_app_g3, + w('foo'), w('bar')), w('foobar')) def test_importall(self): w = self.space.wrap From hpk at codespeak.net Thu Jun 3 16:05:03 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Jun 2004 16:05:03 +0200 (MEST) Subject: [pypy-svn] r4870 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040603140503.33DAD5BE07@thoth.codespeak.net> Author: hpk Date: Thu Jun 3 16:05:02 2004 New Revision: 4870 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py Log: revived the interal generator __iter__ hack ... (obsolete if armin suceeds soon) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py Thu Jun 3 16:05:02 2004 @@ -79,10 +79,10 @@ # XXX the following is for TrivialObjSpace only, when iteration is # done by C code (e.g. when calling 'list(g())'). def __iter__(self): - class hack: + class hack(object): def next(h): try: - return self.pypy_next() + return self.descr_next() except NoValue: raise StopIteration return hack() From arigo at codespeak.net Thu Jun 3 16:29:50 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 16:29:50 +0200 (MEST) Subject: [pypy-svn] r4871 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603142950.960E55BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 16:29:49 2004 New Revision: 4871 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Added the CPyWrappers for the trivial object space. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Thu Jun 3 16:29:49 2004 @@ -9,6 +9,8 @@ class Wrappable(object): """A subclass of Wrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" + def __spacebind__(self, space): + return self class NoValue(Exception): """Raised to signal absence of value, e.g. in the iterator accessing Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py Thu Jun 3 16:29:49 2004 @@ -113,7 +113,7 @@ return function(*argarray, **keywords) -class Gateway(object): +class Gateway(Wrappable): """General-purpose utility for the interpreter-level to create callables that transparently invoke code objects (and thus possibly interpreted app-level code).""" @@ -132,10 +132,10 @@ # staticglobals # staticdefs - def __wrap__(self, space): + def __spacebind__(self, space): # to wrap a Gateway, we first make a real Function object out of it # and the result is a wrapped version of this Function. - return space.wrap(self.get_function(space)) + return self.get_function(space) def get_function(self, space): try: Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Thu Jun 3 16:29:49 2004 @@ -11,7 +11,10 @@ self.rawdict = rawdict def mro(self, space): - return [self, space.object_typedef] + if self is space.object_typedef: + return [self] + else: + return [self, space.object_typedef] class GetSetProperty(Wrappable): def __init__(self, fget, fset=None, fdel=None, doc=None): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Thu Jun 3 16:29:49 2004 @@ -62,24 +62,26 @@ return space.lookup(w_obj, '__set__') is not None def get_and_call(space, w_descr, w_obj, w_args, w_kwargs): - if isinstance(w_descr, Function): # wrapped Function actually + descr = space.unwrap_builtin(w_descr) + if isinstance(descr, Function): # special-case Functions to avoid infinite recursion args_w = space.unpacktuple(w_args) args_w = [w_obj] + args_w w_args = space.newtuple(args_w) - return w_descr.call(w_args, w_kwargs) + return descr.call(w_args, w_kwargs) else: w_impl = space.get(w_descr, w_obj, space.type(w_obj)) return space.call(w_impl, w_args, w_kwargs) def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w): - if isinstance(w_descr, Function): # wrapped Function actually + descr = space.unwrap_builtin(w_descr) + if isinstance(descr, Function): # special-case Functions to avoid infinite recursion args_w = [w_obj] + list(args_w) w_args = space.newtuple(args_w) w_kwargs = space.newdict([(space.wrap(key), w_item) for key, w_item in kwargs_w]) - return w_descr.call(w_args, w_kwargs) + return descr.call(w_args, w_kwargs) else: w_impl = space.get(w_descr, w_obj, space.type(w_obj)) return space.call_function(w_impl, *args_w, **kwargs_w) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 16:29:49 2004 @@ -10,6 +10,9 @@ import operator, types, new, sys import __builtin__ as cpy_builtin +class CPyWrapper(object): + pass + class TrivialObjSpace(ObjSpace, DescrOperation): def clone_exception_hierarchy(self): @@ -110,15 +113,56 @@ # general stuff def wrap(self, x): - if hasattr(type(x), '__wrap__'): - return x.__wrap__(self) + if isinstance(x, Wrappable): + x = x.__spacebind__(self) + wrapperclass = self.hackwrapperclass(x.typedef) + instance = CPyWrapper.__new__(wrapperclass) + instancedict = CPyWrapper.__dict__['__dict__'].__get__(instance) + instancedict['__internalpypyobject__'] = x + return instance else: + # optional check for double-wrapping + if isinstance(x, CPyWrapper): + raise TypeError, "wrapping an already-wrapped object" return x def unwrap(self, w): - #if hasattr(type(w), '__unwrap__'): - # w = w.__unwrap__() - return w + if isinstance(w, CPyWrapper): + instancedict = CPyWrapper.__dict__['__dict__'].__get__(w) + return instancedict['__internalpypyobject__'] + else: + return w + + def hackwrapperclass(self, typedef): + try: + return typedef.trivialwrapperclass + except AttributeError: + # make the base first (assuming single inheritance) + mro = typedef.mro(self) + if len(mro) > 1: + bases = (self.hackwrapperclass(mro[1]),) + else: + bases = (CPyWrapper,) + # make the class dict with descriptors redirecting to the ones + # in rawdict + descrdict = {} + for descrname, descr in typedef.rawdict.items(): + def fget(w_obj, w_descr=descr, space=self): + return space.get(w_descr, w_obj, space.type(w_obj)) + def fset(w_obj, w_value, w_descr=descr, space=self): + return space.set(w_descr, w_obj, w_value) + def fdel(w_obj, w_descr=descr, space=self): + return space.set(w_descr, w_obj) + descrdict[descrname] = property(fget, fset, fdel) + cls = type(typedef.name, bases, descrdict) + typedef.trivialwrapperclass = cls + return cls + + def unwrap_builtin(self, w_obj): + if isinstance(w_obj, CPyWrapper): + return self.unwrap(w_obj) + else: + return None def is_(self, w_obj1, w_obj2): return self.unwrap(w_obj1) is self.unwrap(w_obj2) @@ -356,8 +400,10 @@ # return round(*args) def lookup(space, w_obj, name): - if isinstance(w_obj, Wrappable): - for basedef in w_obj.typedef.mro(space): + assert not isinstance(w_obj, Wrappable) + if isinstance(w_obj, CPyWrapper): + obj = space.unwrap(w_obj) + for basedef in obj.typedef.mro(space): if name in basedef.rawdict: return space.wrap(basedef.rawdict[name]) return None @@ -372,7 +418,7 @@ return None def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): - if isinstance(w_descr, Wrappable): + if isinstance(w_descr, CPyWrapper): return DescrOperation.get_and_call(self, w_descr, w_obj, w_args, w_kwargs) else: @@ -383,7 +429,7 @@ self.reraise() def get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w): - if isinstance(w_descr, Wrappable): + if isinstance(w_descr, CPyWrapper): return DescrOperation.get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w) else: From arigo at codespeak.net Thu Jun 3 16:47:08 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 16:47:08 +0200 (MEST) Subject: [pypy-svn] r4872 - in pypy/branch/src-newobjectmodel/pypy/interpreter: . test Message-ID: <20040603144708.67FAE5BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 16:47:07 2004 New Revision: 4872 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Log: Added and fixed a couple of Function attributes. Fixed a test. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Thu Jun 3 16:47:07 2004 @@ -172,9 +172,10 @@ space.newdict([(space.wrap(key), w_item) for key, w_item in kwds_w.items()])) - def fget_func_defaults(space, self): + def fget_func_defaults(space, w_self): + self = space.unwrap(w_self) values_w = self.defs_w - if values_w is None: + if not values_w: return space.w_None return space.newtuple(values_w) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py Thu Jun 3 16:47:07 2004 @@ -13,7 +13,7 @@ self.assertEquals(f.func_defaults, None) self.assertEquals(f.func_dict, {}) self.assertEquals(type(f.func_globals), dict) - self.assertEquals(f.func_closure, None) + #self.assertEquals(f.func_closure, None) XXX self.assertEquals(f.func_doc, None) self.assertEquals(f.func_name, 'f') @@ -117,24 +117,25 @@ self.fn = Function(self.space, code) def test_get(self): - class X(object): - fn = self.fn - x = X() - meth = x.fn + space = self.space + w_meth = self.fn.descr_function_get(space.wrap(5), space.type(space.wrap(5))) + meth = space.unwrap(w_meth) self.failUnless(isinstance(meth, Method)) def test_call(self): - class X(object): - fn = self.fn - x = X() - self.assertEquals(x.fn(42), 42) + space = self.space + w_meth = self.fn.descr_function_get(space.wrap(5), space.type(space.wrap(5))) + meth = space.unwrap(w_meth) + w_result = meth.descr_method_call(space.wrap(42)) + self.assertEquals(space.unwrap(w_result), 42) def test_fail_call(self): - class X(object): - fn = self.fn - x = X() - self.assertRaises_w(self.space.w_TypeError, x.fn, "spam", "egg") - + space = self.space + w_meth = self.fn.descr_function_get(space.wrap(5), space.type(space.wrap(5))) + meth = space.unwrap(w_meth) + self.assertRaises_w(self.space.w_TypeError, + meth.descr_method_call, + space.wrap("spam"), space.wrap("egg")) if __name__ == '__main__': testit.main() Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Thu Jun 3 16:47:07 2004 @@ -107,6 +107,7 @@ func_name = attrproperty('name'), func_dict = attrproperty_w('w_func_dict'), func_defaults = GetSetProperty(Function.fget_func_defaults), + func_globals = attrproperty_w('w_func_globals'), __doc__ = attrproperty('doc'), __name__ = attrproperty('name'), __dict__ = attrproperty_w('w_func_dict'), From arigo at codespeak.net Thu Jun 3 16:59:55 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 16:59:55 +0200 (MEST) Subject: [pypy-svn] r4873 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603145955.2D2FC5BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 16:59:54 2004 New Revision: 4873 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Un-confused the name of the CPyWrapper subclasses. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/eval.py Thu Jun 3 16:59:54 2004 @@ -82,7 +82,8 @@ self.fast2locals() return self.w_locals - def fget_getdictscope(space, self): + def fget_getdictscope(space, w_self): + self = space.unwrap(w_self) return self.getdictscope() def setdictscope(self, w_locals): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 16:59:54 2004 @@ -154,7 +154,7 @@ def fdel(w_obj, w_descr=descr, space=self): return space.set(w_descr, w_obj) descrdict[descrname] = property(fget, fset, fdel) - cls = type(typedef.name, bases, descrdict) + cls = type('CPyWrapped '+typedef.name, bases, descrdict) typedef.trivialwrapperclass = cls return cls From arigo at codespeak.net Thu Jun 3 17:04:44 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 17:04:44 +0200 (MEST) Subject: [pypy-svn] r4874 - pypy/branch/src-newobjectmodel/pypy/interpreter/test Message-ID: <20040603150444.63C2F5BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 17:04:43 2004 New Revision: 4874 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py Log: Fixed syntax errors. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_gateway.py Thu Jun 3 17:04:43 2004 @@ -47,17 +47,20 @@ self.assertEqual_w(g3(self.space, w('foo'), w('bar')), w('foobar')) def test_interp2app(self): - w = self.space.wrap + space = self.space + w = space.wrap def g3(space, w_a, w_b): return space.add(w_a, w_b) app_g3 = gateway.interp2app(g3) w_app_g3 = space.wrap(app_g3) self.assertEqual_w( space.call(w_app_g3, - space.newtuple(w('foo'), w('bar')), w('foobar')) + space.newtuple([w('foo'), w('bar')]), + space.newdict([])), + w('foobar')) self.assertEqual_w( - space.call_function(w_app_g3, - w('foo'), w('bar')), w('foobar')) + space.call_function(w_app_g3, w('foo'), w('bar')), + w('foobar')) def test_importall(self): w = self.space.wrap From arigo at codespeak.net Thu Jun 3 17:18:25 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 17:18:25 +0200 (MEST) Subject: [pypy-svn] r4875 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603151825.E4E145BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 17:18:25 2004 New Revision: 4875 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: space.w_None is now wrapped into a CPyWrapper, to avoid confusion with the real None. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 17:18:25 2004 @@ -79,8 +79,15 @@ __class__ = GetSetProperty(self.__class__.type), __init__ = gateway.interp2app(Object.descr__init__.im_func), ) - - self.w_None = None + # make a wrapped None object + none_typedef = TypeDef('NoneType', + __repr__ = gateway.interp2app(lambda space, w_None: + space.wrap('None'))) + nonewrapperclass = self.hackwrapperclass(none_typedef) + self.w_None = CPyWrapper.__new__(nonewrapperclass) + instancedict = CPyWrapper.__dict__['__dict__'].__get__(self.w_None) + instancedict['__internalpypyobject__'] = None + self.w_True = True self.w_False = False self.w_NotImplemented = NotImplemented @@ -120,6 +127,8 @@ instancedict = CPyWrapper.__dict__['__dict__'].__get__(instance) instancedict['__internalpypyobject__'] = x return instance + elif x is None: + return self.w_None else: # optional check for double-wrapping if isinstance(x, CPyWrapper): @@ -145,7 +154,7 @@ bases = (CPyWrapper,) # make the class dict with descriptors redirecting to the ones # in rawdict - descrdict = {} + descrdict = {'__internalpypytypedef__': typedef} for descrname, descr in typedef.rawdict.items(): def fget(w_obj, w_descr=descr, space=self): return space.get(w_descr, w_obj, space.type(w_obj)) @@ -402,8 +411,8 @@ def lookup(space, w_obj, name): assert not isinstance(w_obj, Wrappable) if isinstance(w_obj, CPyWrapper): - obj = space.unwrap(w_obj) - for basedef in obj.typedef.mro(space): + typedef = type(w_obj).__internalpypytypedef__ + for basedef in typedef.mro(space): if name in basedef.rawdict: return space.wrap(basedef.rawdict[name]) return None From hpk at codespeak.net Thu Jun 3 17:38:07 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 3 Jun 2004 17:38:07 +0200 (MEST) Subject: [pypy-svn] r4876 - pypy/trunk/src/pypy/translator/tool Message-ID: <20040603153807.717955BE07@thoth.codespeak.net> Author: hpk Date: Thu Jun 3 17:38:06 2004 New Revision: 4876 Modified: pypy/trunk/src/pypy/translator/tool/make_dot.py Log: fixed a remaining problem with make_dot Modified: pypy/trunk/src/pypy/translator/tool/make_dot.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/make_dot.py (original) +++ pypy/trunk/src/pypy/translator/tool/make_dot.py Thu Jun 3 17:38:06 2004 @@ -158,7 +158,7 @@ source = dotgen.getgraph(basefilename, subgraphs) #print source dest.write(source) - psdest = dest.newext(target) + psdest = dest.new(ext=target) out = cmdexec('dot -T%s %s' % (target, str(dest))) psdest.write(out) #print "wrote", psdest From ale at codespeak.net Thu Jun 3 17:51:49 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 3 Jun 2004 17:51:49 +0200 (MEST) Subject: [pypy-svn] r4877 - pypy/trunk/src/pypy/translator Message-ID: <20040603155149.D46E05BE07@thoth.codespeak.net> Author: ale Date: Thu Jun 3 17:51:49 2004 New Revision: 4877 Modified: pypy/trunk/src/pypy/translator/genpyrex.py Log: A little beautified. Test of Sieves_of_erastothenes doesnt work Modified: pypy/trunk/src/pypy/translator/genpyrex.py ============================================================================== --- pypy/trunk/src/pypy/translator/genpyrex.py (original) +++ pypy/trunk/src/pypy/translator/genpyrex.py Thu Jun 3 17:51:49 2004 @@ -7,6 +7,7 @@ from pypy.objspace.flow.model import mkentrymap from pypy.translator.annrpython import RPythonAnnotator from pypy.annotation.model import SomeMethod +import inspect class Op: def __init__(self, operation, gen, block): @@ -180,6 +181,7 @@ def gen_graph(self): fun = self.functiongraph self.entrymap = mkentrymap(fun) + for block in self.entrymap : check_consistent_exits(block) currentlines = self.lines self.lines = [] self.indent += 1 @@ -201,10 +203,10 @@ hackedargs = ', '.join([var.name for var in fun.getargs()]) self.putline("def %s(%s):" % (fun.name, hackedargs)) self.indent += 1 - self.putline("return %s(%s)" % (self._hackname(function_object), hackedargs)) + self.putline("return %s(%s)" % (self.getfunctionname(function_object), hackedargs)) self.indent -= 1 # go ahead with the mandled header and body of the function - self.putline("def %s(%s):" % (self._hackname(function_object), params)) + self.putline("def %s(%s):" % (self.getfunctionname(function_object), params)) self.indent += 1 #self.putline("# %r" % self.annotations) decllines = [] @@ -254,14 +256,11 @@ if vartype in (int, bool): ctype = "int" elif self.annotator and vartype in self.annotator.getuserclasses(): - ctype = self.get_classname(vartype) + ctype = self.getclassname(vartype) else: ctype = "object" return ctype - def get_classname(self, userclass): - return self._hackname(userclass) - def _vardecl(self, var): vartype, varname = self._paramvardecl(var) if vartype != "object": @@ -269,29 +268,36 @@ else: return "" - def _hackname(self, value): - try: - name = value.__name__ - except AttributeError: - pass - else: - import types - if isinstance(value, (types.FunctionType, types.ClassType, type)): - # XXX! use the id of the value to make unique function and - # class names - return '%s__%x' % (name, id(value)) - elif isinstance(value, types.BuiltinFunctionType): - return str(name) - if isinstance(value, int): - value = int(value) # cast subclasses of int (i.e. bools) to ints - return repr(value) + def getclassname(self,cls): + assert inspect.isclass(cls) + return '%s__%x' % (cls.__name__, id(cls))#self._hackname(cls) + + def getfunctionname(self,func): + assert inspect.isfunction(func) or inspect.ismethod(func) + return '%s__%x' % (func.__name__, id(func))#self._hackname(func) + + def getvarname(self,var): + assert inspect.isclass(var) + return self._hackname(var) def _str(self, obj, block): if isinstance(obj, Variable): #self.variablelocations[obj] = block return self.get_varname(obj) elif isinstance(obj, Constant): - return self._hackname(obj.value) + import types + if isinstance(obj.value,(types.ClassType,type)): + fff=self.getclassname(obj.value) + elif isinstance(obj.value,(types.FunctionType,type)): + fff=self.getfunctionname(obj.value) + elif isinstance(obj.value, types.BuiltinFunctionType): + fff=str(obj.value.__name__) + else: + #fff=self._hackname(obj.value) + fff=repr(obj.value) + if isinstance(obj.value, int): + fff = repr(int(obj.value)) + return fff else: raise TypeError("Unknown class: %s" % obj.__class__) @@ -359,10 +365,10 @@ delay_methods={} for cls in self.annotator.getuserclassdefinitions(): if cls.basedef: - bdef="(%s)" % (self.get_classname(cls.basedef.cls)) + bdef="(%s)" % (self.getclassname(cls.basedef.cls)) else: bdef="" - self.putline("cdef class %s%s:" % (self.get_classname(cls.cls),bdef)) + self.putline("cdef class %s%s:" % (self.getclassname(cls.cls),bdef)) self.indent += 1 empty = True for attr,s_value in cls.attrs.items(): @@ -380,7 +386,7 @@ hackedargs = ', '.join([var.name for var in fun.getargs()]) self.putline("def %s(%s):" % (py_fun.__name__, hackedargs)) self.indent += 1 - self.putline("return %s(%s)" % (self._hackname(py_fun), + self.putline("return %s(%s)" % (self.getfunctionname(py_fun), hackedargs)) self.indent -= 1 empty = False @@ -391,3 +397,10 @@ return '\n'.join(self.lines) else: return '' + +def check_consistent_exits(block): + for exit in block.exits : + if len(exit.args) != len(exit.target.inputargs): + print "inconsistent block exit", block,exit,exit.args + print "more", exit.target,exit.target.inputargs + \ No newline at end of file From ale at codespeak.net Thu Jun 3 18:26:34 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 3 Jun 2004 18:26:34 +0200 (MEST) Subject: [pypy-svn] r4878 - pypy/trunk/src/pypy/translator/test Message-ID: <20040603162634.5BCF95BE07@thoth.codespeak.net> Author: ale Date: Thu Jun 3 18:26:33 2004 New Revision: 4878 Modified: pypy/trunk/src/pypy/translator/test/test_translator.py Log: Some more test (factorial,factorial2,sieve_of_erastothenes) Modified: pypy/trunk/src/pypy/translator/test/test_translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_translator.py (original) +++ pypy/trunk/src/pypy/translator/test/test_translator.py Thu Jun 3 18:26:33 2004 @@ -19,11 +19,31 @@ inheritance2 = t.compile() self.assertEquals(inheritance2(), ((-12, -12), (3, "world"))) + def test_factorial2(self): + t = Translator(snippet.factorial2) + t.annotate([int]) + factorial2 = t.compile() + self.assertEquals(factorial2(5), 120) + + def test_factorial(self): + t = Translator(snippet.factorial) + t.annotate([int]) + factorial = t.compile() + self.assertEquals(factorial(5), 120) + def test_simple_method(self): t = Translator(snippet.simple_method) t.annotate([int]).simplify() simple_method = t.compile() self.assertEquals(simple_method(55), 55) + def test_sieve_of_eratosthenes(self): + t = Translator(snippet.sieve_of_eratosthenes) + t.simplify() + t.annotate([]).simplify() + #t.view() + sieve_of_eratosthenes = t.compile() + self.assertEquals(sieve_of_eratosthenes(), 1028) + if __name__ == '__main__': testit.main() From arigo at codespeak.net Thu Jun 3 18:27:33 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 18:27:33 +0200 (MEST) Subject: [pypy-svn] r4879 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040603162733.CBD8D5BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 18:27:33 2004 New Revision: 4879 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Obscure hacks. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Thu Jun 3 18:27:33 2004 @@ -158,7 +158,9 @@ def descr_function_get(self, w_obj, w_cls): space = self.space wrap = space.wrap - if not space.is_true(space.is_(w_obj, space.w_None)): + asking_for_bound = (not space.is_true(space.is_(w_obj, space.w_None)) or + space.is_true(space.is_(w_cls, space.type(space.w_None)))) + if asking_for_bound: if space.is_true(space.is_(w_cls, space.w_None)): w_cls = space.type(w_obj) return wrap(Method(space, wrap(self), w_obj, w_cls)) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 18:27:33 2004 @@ -74,7 +74,7 @@ __getattribute__ = gateway.interp2app(Object.descr__getattribute__.im_func), __setattr__ = gateway.interp2app(Object.descr__setattr__.im_func), __delattr__ = gateway.interp2app(Object.descr__delattr__.im_func), - __str__ = gateway.interp2app(lambda space, w_x: str(w_x)), + __str__ = gateway.interp2app(lambda space, w_x: space.repr(w_x)), __repr__ = gateway.interp2app(lambda space, w_x: repr(w_x)), __class__ = GetSetProperty(self.__class__.type), __init__ = gateway.interp2app(Object.descr__init__.im_func), @@ -146,6 +146,8 @@ try: return typedef.trivialwrapperclass except AttributeError: + from pypy.interpreter.gateway import interp2app + # make the base first (assuming single inheritance) mro = typedef.mro(self) if len(mro) > 1: @@ -156,12 +158,24 @@ # in rawdict descrdict = {'__internalpypytypedef__': typedef} for descrname, descr in typedef.rawdict.items(): - def fget(w_obj, w_descr=descr, space=self): - return space.get(w_descr, w_obj, space.type(w_obj)) - def fset(w_obj, w_value, w_descr=descr, space=self): - return space.set(w_descr, w_obj, w_value) - def fdel(w_obj, w_descr=descr, space=self): - return space.set(w_descr, w_obj) + if isinstance(descr, interp2app): + def fget(w_obj, descr=descr, space=self): + fn = descr.get_function() + return space.wrap(Method(space, space.wrap(fn), w_obj, + space.type(w_obj))) + fset = None + fdel = None + else: + # more generally, defining a property + def fget(w_obj, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.get(w_descr, w_obj, space.type(w_obj)) + def fset(w_obj, w_value, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.set(w_descr, w_obj, w_value) + def fdel(w_obj, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.set(w_descr, w_obj) descrdict[descrname] = property(fget, fset, fdel) cls = type('CPyWrapped '+typedef.name, bases, descrdict) typedef.trivialwrapperclass = cls From arigo at codespeak.net Thu Jun 3 18:32:41 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 18:32:41 +0200 (MEST) Subject: [pypy-svn] r4880 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603163241.F39F95BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 18:32:41 2004 New Revision: 4880 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Even more obscure fixes. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 18:32:41 2004 @@ -446,8 +446,10 @@ w_args, w_kwargs) else: try: - impl = w_descr.__get__(w_obj, type(w_obj)) - return impl(*w_args, **w_kwargs) + obj = self.unwrap(w_obj) + if hasattr(w_descr, '__get__'): + obj = w_descr.__get__(obj, type(obj)) + return obj(*w_args, **w_kwargs) except: self.reraise() @@ -457,8 +459,10 @@ *args_w, **kwargs_w) else: try: - impl = w_descr.__get__(w_obj, type(w_obj)) - return impl(*args_w, **kwargs_w) + obj = self.unwrap(w_obj) + if hasattr(w_descr, '__get__'): + obj = w_descr.__get__(obj, type(obj)) + return obj(*args_w, **kwargs_w) except: #import traceback; traceback.print_exc() self.reraise() From ale at codespeak.net Thu Jun 3 18:45:08 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 3 Jun 2004 18:45:08 +0200 (MEST) Subject: [pypy-svn] r4881 - pypy/trunk/src/pypy/translator/test Message-ID: <20040603164508.8A3635BE07@thoth.codespeak.net> Author: ale Date: Thu Jun 3 18:45:07 2004 New Revision: 4881 Modified: pypy/trunk/src/pypy/translator/test/test_translator.py Log: All tests work now. (dont do simplify on the annotator when generating pyrex code) Modified: pypy/trunk/src/pypy/translator/test/test_translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_translator.py (original) +++ pypy/trunk/src/pypy/translator/test/test_translator.py Thu Jun 3 18:45:07 2004 @@ -40,7 +40,7 @@ def test_sieve_of_eratosthenes(self): t = Translator(snippet.sieve_of_eratosthenes) t.simplify() - t.annotate([]).simplify() + t.annotate([])#.simplify() #t.view() sieve_of_eratosthenes = t.compile() self.assertEquals(sieve_of_eratosthenes(), 1028) From lac at codespeak.net Thu Jun 3 19:02:02 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Thu, 3 Jun 2004 19:02:02 +0200 (MEST) Subject: [pypy-svn] r4882 - pypy/trunk/src/pypy/tool Message-ID: <20040603170202.9DE3D5BE07@thoth.codespeak.net> Author: lac Date: Thu Jun 3 19:02:00 2004 New Revision: 4882 Modified: pypy/trunk/src/pypy/tool/option.py Log: Unneeded at this time? Ancient -- refers to Annotate, not Flow .... we can put it back if somebody needs the thing. Modified: pypy/trunk/src/pypy/tool/option.py ============================================================================== --- pypy/trunk/src/pypy/tool/option.py (original) +++ pypy/trunk/src/pypy/tool/option.py Thu Jun 3 19:02:00 2004 @@ -21,6 +21,8 @@ '-T', action="callback", callback=objspace_callback, callback_args=("trivial",), help="run in trivial object space")) + """ + unneeded options that don't even make sense any more? options.append(make_option( '-P', action="callback", callback=objspace_callback, callback_args=("trace",), @@ -29,6 +31,7 @@ '-A', action="callback", callback=objspace_callback, callback_args=("ann",), help="run in annotation object space")) + """ options.append(make_option( '-v', action="count", dest="verbose", help="verbose")) From arigo at codespeak.net Thu Jun 3 19:59:29 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 3 Jun 2004 19:59:29 +0200 (MEST) Subject: [pypy-svn] r4883 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040603175929.952F95BE07@thoth.codespeak.net> Author: arigo Date: Thu Jun 3 19:59:26 2004 New Revision: 4883 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Oups. It works and all the tests (minus 1) suddenly pass. Go figure out why exactly. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Thu Jun 3 19:59:26 2004 @@ -157,26 +157,27 @@ # make the class dict with descriptors redirecting to the ones # in rawdict descrdict = {'__internalpypytypedef__': typedef} - for descrname, descr in typedef.rawdict.items(): - if isinstance(descr, interp2app): - def fget(w_obj, descr=descr, space=self): - fn = descr.get_function() - return space.wrap(Method(space, space.wrap(fn), w_obj, - space.type(w_obj))) - fset = None - fdel = None - else: - # more generally, defining a property - def fget(w_obj, descr=descr, space=self): - w_descr = space.wrap(descr) - return space.get(w_descr, w_obj, space.type(w_obj)) - def fset(w_obj, w_value, descr=descr, space=self): - w_descr = space.wrap(descr) - return space.set(w_descr, w_obj, w_value) - def fdel(w_obj, descr=descr, space=self): - w_descr = space.wrap(descr) - return space.set(w_descr, w_obj) - descrdict[descrname] = property(fget, fset, fdel) + if typedef.name != 'object': + for descrname, descr in typedef.rawdict.items(): + if isinstance(descr, interp2app): + def make_stuff(descr=descr, descrname=descrname, space=self): + def stuff(w_obj, *args, **kwds): + fn = descr.get_function(space) + return fn.descr_function_call(w_obj, *args, **kwds) + return stuff + descrdict[descrname] = make_stuff() + else: + # more generally, defining a property + def fget(w_obj, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.get(w_descr, w_obj, space.type(w_obj)) + def fset(w_obj, w_value, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.set(w_descr, w_obj, w_value) + def fdel(w_obj, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.set(w_descr, w_obj) + descrdict[descrname] = property(fget, fset, fdel) cls = type('CPyWrapped '+typedef.name, bases, descrdict) typedef.trivialwrapperclass = cls return cls @@ -431,13 +432,9 @@ return space.wrap(basedef.rawdict[name]) return None else: - # hack hack hack: ignore the real 'object' and use our own - for cls in w_obj.__class__.__mro__[:-1]: + for cls in w_obj.__class__.__mro__: if name in cls.__dict__: return cls.__dict__[name] - basedef = space.object_typedef - if name in basedef.rawdict: - return space.wrap(basedef.rawdict[name]) return None def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): From hpk at codespeak.net Fri Jun 4 09:30:52 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 09:30:52 +0200 (MEST) Subject: [pypy-svn] r4892 - in pypy/branch/src-newobjectmodel/pypy: interpreter interpreter/test objspace Message-ID: <20040604073052.37D455BE09@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 09:30:50 2004 New Revision: 4892 Added: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_typedef.py - copied, changed from r4883, pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_objspace.py Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py pypy/branch/src-newobjectmodel/pypy/interpreter/pyopcode.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: - get rid of NoValue specialty and raise/catch the good old boring OperationError - added a test for traceback attributes Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Fri Jun 4 09:30:50 2004 @@ -3,7 +3,7 @@ from pypy.interpreter.miscutils import Stack, getthreadlocals import pypy.module -__all__ = ['ObjSpace', 'OperationError', 'NoValue', 'Wrappable'] +__all__ = ['ObjSpace', 'OperationError', 'Wrappable'] class Wrappable(object): @@ -12,11 +12,6 @@ def __spacebind__(self, space): return self -class NoValue(Exception): - """Raised to signal absence of value, e.g. in the iterator accessing - method 'op.next()' of object spaces.""" - - class ObjSpace: """Base class for the interpreter-level implementations of object spaces. http://codespeak.net/moin/pypy/moin.cgi/ObjectSpace""" @@ -121,7 +116,9 @@ while True: try: w_item = self.next(w_iterator) - except NoValue: + except OperationError, e: + if not e.match(self, self.w_StopIteration): + raise break # done if expected_length is not None and len(items) == expected_length: raise ValueError, "too many values to unpack" @@ -308,5 +305,5 @@ # newstring([w_1, w_2,...]) -> w_string from ascii numbers (bytes) # newdict([(w_key,w_value),...]) -> w_dict #newslice(w_start,w_stop,w_step) -> w_slice (any argument may be a real None) -# next(w_iter) -> w_value or raise NoValue +# next(w_iter) -> w_value or raise StopIteration # Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/generator.py Fri Jun 4 09:30:50 2004 @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import NoValue +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.eval import Frame from pypy.interpreter.pyframe import ControlFlowException, ExitFrame from pypy.interpreter import function, gateway @@ -36,7 +36,7 @@ YIELD_STMT = YIELD_VALUE # misnamed in old versions of dis.opname -class GeneratorIterator(object): +class GeneratorIterator(Wrappable): "An iterator created by a generator." def __init__(self, frame): @@ -48,45 +48,24 @@ return self.space.wrap(self) def descr_next(self): - # raise NoValue when exhausted + space = self.frame.space if self.running: - space = self.frame.space raise OperationError(space.w_ValueError, space.wrap('generator already executing')) if self.frame.exhausted: - raise NoValue + raise OperationError(space.w_StopIteration, space.w_None) self.running = True try: - try: return Frame.run(self.frame) + try: + return Frame.run(self.frame) except OperationError, e: if e.match(self.space, self.space.w_StopIteration): - raise NoValue + raise OperationError(space.w_StopIteration, space.w_None) else: raise finally: self.running = False - # XXX the next two methods we don't really want here, - # it appears to be there for trivial object space - def next(self): - try: - return self.descr_next() # - except NoValue: - raise OperationError(self.space.w_StopIteration, - self.space.w_None) - app_next = gateway.interp2app(next) - - # XXX the following is for TrivialObjSpace only, when iteration is - # done by C code (e.g. when calling 'list(g())'). - def __iter__(self): - class hack(object): - def next(h): - try: - return self.descr_next() - except NoValue: - raise StopIteration - return hack() - # # the specific ControlFlowExceptions used by generators # @@ -102,4 +81,4 @@ """Signals a 'return' statement inside a generator.""" def emptystack(self, frame): frame.exhausted = True - raise NoValue + raise OperationError(frame.space.w_StopIteration, frame.space.w_None) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/pyopcode.py Fri Jun 4 09:30:50 2004 @@ -4,7 +4,7 @@ pyfastscope.py and pynestedscope.py. """ -from pypy.interpreter.baseobjspace import OperationError, NoValue +from pypy.interpreter.baseobjspace import OperationError from pypy.interpreter.eval import UNDEFINED from pypy.interpreter import baseobjspace, gateway, function from pypy.interpreter import pyframe, pytraceback @@ -649,7 +649,9 @@ w_iterator = f.valuestack.top() try: w_nextitem = f.space.next(w_iterator) - except NoValue: + except OperationError, e: + if not e.match(f.space, f.space.w_StopIteration): + raise # iterator exhausted f.valuestack.pop() f.next_instr += jumpby Copied: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_typedef.py (from r4883, pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_objspace.py) ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_typedef.py Fri Jun 4 09:30:50 2004 @@ -4,115 +4,26 @@ # this test isn't so much to test that the objspace interface *works* # -- it's more to test that it's *there* -class TestObjSpace(testit.TestCase): - - def setUp(self): - self.space = testit.objspace() - - def tearDown(self): - pass +class TestTraceBackAttributes(testit.AppTestCase): def test_newstring(self): - w = self.space.wrap - s = 'abc' - chars_w = [w(ord(c)) for c in s] - self.assertEqual_w(w(s), self.space.newstring(chars_w)) - - def test_newstring_fail(self): - w = self.space.wrap - s = 'abc' - not_chars_w = [w(c) for c in s] - self.assertRaises_w(self.space.w_TypeError, - self.space.newstring, - not_chars_w) - self.assertRaises_w(self.space.w_ValueError, - self.space.newstring, - [w(-1)]) - - def test_newlist(self): - w = self.space.wrap - l = range(10) - w_l = self.space.newlist([w(i) for i in l]) - self.assertEqual_w(w_l, w(l)) - - def test_newdict(self): - w = self.space.wrap - items = [(0, 1), (3, 4)] - items_w = [(w(k), w(v)) for (k, v) in items] - d = dict(items) - w_d = self.space.newdict(items_w) - self.assertEqual_w(w_d, w(d)) - - def test_newtuple(self): - w = self.space.wrap - t = tuple(range(10)) - w_t = self.space.newtuple([w(i) for i in t]) - self.assertEqual_w(w_t, w(t)) - - def test_is_true(self): - w = self.space.wrap - true = (1==1) - false = (1==0) - w_true = w(true) - w_false = w(false) - self.failUnless(self.space.is_true(w_true)) - self.failIf(self.space.is_true(w_false)) - - def test_is_(self): - w_l = self.space.newlist([]) - w_m = self.space.newlist([]) - self.assertEqual(self.space.is_(w_l, w_l), self.space.w_True) - self.assertEqual(self.space.is_(w_l, w_m), self.space.w_False) - - def test_newbool(self): - self.assertEqual(self.space.newbool(0), self.space.w_False) - self.assertEqual(self.space.newbool(1), self.space.w_True) - - def test_unpackiterable(self): - w = self.space.wrap - l = [w(1), w(2), w(3), w(4)] - w_l = self.space.newlist(l) - self.assertEqual(self.space.unpackiterable(w_l), l) - self.assertEqual(self.space.unpackiterable(w_l, 4), l) - self.assertRaises(ValueError, self.space.unpackiterable, w_l, 3) - self.assertRaises(ValueError, self.space.unpackiterable, w_l, 5) - - def test_unpacktuple(self): - w = self.space.wrap - l = [w(1), w(2), w(3), w(4)] - w_l = self.space.newtuple(l) - self.assertEqual(self.space.unpacktuple(w_l), l) - self.assertEqual(self.space.unpacktuple(w_l, 4), l) - self.assertRaises(ValueError, self.space.unpacktuple, w_l, 3) - self.assertRaises(ValueError, self.space.unpacktuple, w_l, 5) - - def test_exception_match(self): - self.failUnless(self.space.exception_match(self.space.w_ValueError, - self.space.w_ValueError)) - self.failUnless(self.space.exception_match(self.space.w_IndexError, - self.space.w_LookupError)) - self.failIf(self.space.exception_match(self.space.w_ValueError, - self.space.w_LookupError)) - -class ModuleMinimalTest(testit.IntTestCase): - def setUp(self): - self.space = testit.objspace() - - def test_sys_exists(self): - w_sys = self.space.get_builtin_module('sys') - self.assert_(self.space.is_true(w_sys)) - - def test_import_exists(self): - space = self.space - w_builtin = space.get_builtin_module('__builtin__') - self.assert_(space.is_true(w_builtin)) - w_name = space.wrap('__import__') - w_import = self.space.getattr(w_builtin, w_name) - self.assert_(space.is_true(w_import)) - - def test_sys_import(self): - from pypy.interpreter.main import run_string - run_string('import sys', space=self.space) + import sys + def f(): + raise TypeError, "hello" + + def g(): + f() + + try: + g() + except: + typ,val,tb = sys.exc_info() + else: + raise AssertionError, "should have raised" + self.assert_(hasattr(tb, 'tb_frame')) + self.assert_(hasattr(tb, 'tb_lasti')) + self.assert_(hasattr(tb, 'tb_lineno')) + self.assert_(hasattr(tb, 'tb_next')) if __name__ == '__main__': testit.main() Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Fri Jun 4 09:30:50 2004 @@ -123,10 +123,10 @@ ) PyTraceback.typedef = TypeDef("traceback", - tb_frame = attrproperty('tb_frame'), - tb_lasti = attrproperty('tb_lasti'), - tb_lineno = attrproperty('tb_line'), - tb_next = attrproperty('tb_next'), + tb_frame = attrproperty('frame'), + tb_lasti = attrproperty('lasti'), + tb_lineno = attrproperty('lineno'), + tb_next = attrproperty('next'), ) GeneratorIterator.typedef = TypeDef("generator", Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Fri Jun 4 09:30:50 2004 @@ -1,6 +1,6 @@ import operator from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import ObjSpace, NoValue +from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.function import Function class Object: @@ -167,12 +167,7 @@ if w_descr is None: raise OperationError(space.w_TypeError, space.wrap("iterator has no next() method")) - try: - return space.get_and_call_function(w_descr,w_obj) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - raise NoValue + return space.get_and_call_function(w_descr,w_obj) def getitem(space,w_obj,w_key): w_descr = space.lookup(w_obj,'__getitem__') Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Fri Jun 4 09:30:50 2004 @@ -33,7 +33,8 @@ # of the exceptions... self.w_Exception = type('Exception', (), - {'__init__':__init__, '__str__': __str__}) + {'__init__':__init__, '__str__': __str__, + 'originalex': Exception}) done = {'Exception': self.w_Exception} @@ -61,6 +62,7 @@ base = done[b.__name__] newtype = type(next, (base,), {}) setattr(self, 'w_' + next, newtype) + newtype.originalex = v done[next] = newtype stack.pop() else: @@ -163,7 +165,14 @@ def make_stuff(descr=descr, descrname=descrname, space=self): def stuff(w_obj, *args, **kwds): fn = descr.get_function(space) - return fn.descr_function_call(w_obj, *args, **kwds) + try: + return fn.descr_function_call(w_obj, *args, **kwds) + except OperationError, e: + if not hasattr(e.w_type, 'originalex'): + raise # XXX + # XXX normalize ... + #if isinstance(e.w_value, e.w_type): + raise e.w_type.originalex(repr(e.w_value)) # e.w_value) return stuff descrdict[descrname] = make_stuff() else: @@ -203,7 +212,6 @@ #traceback.print_exc() #ec = self.getexecutioncontext() # .framestack.items[-1] #ec.print_detailed_traceback(self) - etype, evalue, etb = sys.exc_info() if etype is OperationError: raise etype, evalue, etb # just re-raise it From mwh at codespeak.net Fri Jun 4 09:44:14 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 09:44:14 +0200 (MEST) Subject: [pypy-svn] r4893 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040604074414.EF9205BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 09:44:14 2004 New Revision: 4893 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: Unsatisfactory change to make test_interpreter.TestInterpreter.test_except3 pass again. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Fri Jun 4 09:44:14 2004 @@ -304,7 +304,7 @@ if w_res is not None: return w_res raise OperationError(space.w_TypeError, - space.wrap("operands do not support binary %s" % symbol)) + space.wrap("unsupported operand type(s) for %s" % symbol)) return binop_impl def _make_comparison_impl(symbol,specialnames): From mwh at codespeak.net Fri Jun 4 09:45:56 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 09:45:56 +0200 (MEST) Subject: [pypy-svn] r4894 - pypy/branch/src-newobjectmodel/pypy/interpreter/test Message-ID: <20040604074556.E1BBF5BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 09:45:56 2004 New Revision: 4894 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py Log: these tests pass! Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py Fri Jun 4 09:45:56 2004 @@ -3,7 +3,6 @@ class TestClassApp(testit.AppTestCase): - def test_class(self): class C: @@ -12,7 +11,7 @@ c = C() self.assertEquals(c.__class__, C) - def dont_test_metaclass_explicit(self): + def test_metaclass_explicit(self): class M(type): pass class C: @@ -21,7 +20,7 @@ c = C() self.assertEquals(c.__class__, C) - def dont_test_metaclass_inherited(self): + def test_metaclass_inherited(self): class M(type): pass class B: @@ -32,12 +31,14 @@ c = C() self.assertEquals(c.__class__, C) - def dont_test_metaclass_global(self): + def test_metaclass_global(self): d = {} metatest_text = """ class M(type): pass + __metaclass__ = M + class C: pass """ From arigo at codespeak.net Fri Jun 4 10:11:49 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 4 Jun 2004 10:11:49 +0200 (MEST) Subject: [pypy-svn] r4895 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040604081149.C75485BE07@thoth.codespeak.net> Author: arigo Date: Fri Jun 4 10:11:49 2004 New Revision: 4895 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Minifix. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Fri Jun 4 10:11:49 2004 @@ -93,9 +93,6 @@ w_id_y = self.id(w_y) return self.eq(w_id_x, w_id_y) - def not_(self, w_obj): # default implementation - return self.wrap(not self.is_true(w_obj)) - def unwrapdefault(self, w_value, default): if w_value is None or w_value == self.w_None: return default Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Fri Jun 4 10:11:49 2004 @@ -253,6 +253,9 @@ for _name in ('id', 'type', 'ord', 'round'): _auto(_name, _name, locals()) + def not_(self, w_obj): # default implementation + return self.wrap(not self.is_true(w_obj)) + # for _name in ('id', 'type', 'iter', 'repr', 'str', 'len', # 'pow', 'divmod', 'hash', 'setattr', 'delattr', 'hex', # 'oct', 'ord', 'getattr'): From hpk at codespeak.net Fri Jun 4 10:29:11 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 10:29:11 +0200 (MEST) Subject: [pypy-svn] r4896 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040604082911.D759D5BE07@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 10:29:11 2004 New Revision: 4896 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/userobject.py Log: NoValue -> OperationError(...) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py Fri Jun 4 10:29:11 2004 @@ -27,9 +27,9 @@ try: w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index)) except OperationError, e: - if e.match(space, space.w_IndexError): - raise NoValue - raise + if not e.match(space, space.w_IndexError): + raise + raise OperationError(space, space.w_StopIteration, space.w_None) w_seqiter.index += 1 return w_item Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py Fri Jun 4 10:29:11 2004 @@ -52,7 +52,9 @@ while True: try: w_item = space.next(w_iterator) - except NoValue: + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise break # done _ins1(w_list, w_list.ob_size, w_item) else: Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Fri Jun 4 10:29:11 2004 @@ -178,11 +178,7 @@ "Call the next() multimethod." mm = self.code.slice().get(self.space) args = self.fastlocals_w - try: - return mm(*args) - except NoValue: - raise OperationError(self.space.w_StopIteration, - self.space.w_None) + return mm(*args) class NonZeroMmFrame(eval.Frame): def run(self): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/userobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/userobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/userobject.py Fri Jun 4 10:29:11 2004 @@ -143,12 +143,7 @@ def next_call(self, space, *args_w): "For .next()." # don't accept NotImplemented nor a real None, but catch StopIteration - try: - return self.do_call(space, args_w) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - raise NoValue + return self.do_call(space, args_w) def nonzero_call(self, space, *args_w): "For __nonzero__()." From hpk at codespeak.net Fri Jun 4 10:38:40 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 10:38:40 +0200 (MEST) Subject: [pypy-svn] r4897 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040604083840.7717F5BE07@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 10:38:39 2004 New Revision: 4897 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: fixed wrong operationError instantiation Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py Fri Jun 4 10:38:39 2004 @@ -29,7 +29,7 @@ except OperationError, e: if not e.match(space, space.w_IndexError): raise - raise OperationError(space, space.w_StopIteration, space.w_None) + raise OperationError(space.w_StopIteration, space.w_None) w_seqiter.index += 1 return w_item Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Fri Jun 4 10:38:39 2004 @@ -90,7 +90,8 @@ self.newtuple([]), self.newdict([(w('__init__'), w_init), (w('__str__'), w_str)])) - self.w_IndexError = self.w_Exception + + self.w_IndexError = self.w_StopIteration = self.w_Exception done = {'Exception': self.w_Exception} From hpk at codespeak.net Fri Jun 4 11:05:44 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 11:05:44 +0200 (MEST) Subject: [pypy-svn] r4898 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040604090544.551465BE07@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 11:05:43 2004 New Revision: 4898 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py Log: some more missing NoValue->OperationError ... Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py Fri Jun 4 11:05:43 2004 @@ -298,8 +298,6 @@ return obj.pypy_next() try: result = obj.next() - except StopIteration: - raise NoValue except: wrap_exception(space) return space.wrap(result) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py Fri Jun 4 11:05:43 2004 @@ -204,7 +204,9 @@ while 1: try: w_next = space.next(w_iter) - except NoValue: + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise return space.w_False if space.is_true(space.eq(w_next, w_lookfor)): return space.w_True From mwh at codespeak.net Fri Jun 4 12:35:18 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 12:35:18 +0200 (MEST) Subject: [pypy-svn] r4899 - pypy/branch/src-newobjectmodel/pypy/tool Message-ID: <20040604103518.45B0C5BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 12:35:17 2004 New Revision: 4899 Modified: pypy/branch/src-newobjectmodel/pypy/tool/testit.py Log: enable debugging failures Modified: pypy/branch/src-newobjectmodel/pypy/tool/testit.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/testit.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/testit.py Fri Jun 4 12:35:17 2004 @@ -110,7 +110,7 @@ #from pypy.tool.testitpm import TestPM #c = TestPM(efs) #c.cmdloop() - for test, (exc_type, exc_value, exc_tb) in self.errors: + for test, (exc_type, exc_value, exc_tb) in self.errors + self.failures: import pdb; pdb.post_mortem(exc_tb) def printErrors(self): From mwh at codespeak.net Fri Jun 4 14:15:53 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 14:15:53 +0200 (MEST) Subject: [pypy-svn] r4900 - in pypy/branch/src-newobjectmodel/pypy: interpreter tool Message-ID: <20040604121553.696AD5BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 14:15:52 2004 New Revision: 4900 Added: pypy/branch/src-newobjectmodel/pypy/tool/tb_server.py Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/error.py pypy/branch/src-newobjectmodel/pypy/interpreter/py.py pypy/branch/src-newobjectmodel/pypy/tool/option.py Log: Beginnings of the debugging web server. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/error.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/error.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/error.py Fri Jun 4 14:15:52 2004 @@ -95,6 +95,8 @@ interpr_file = LinePrefixer(file, '||') print >> interpr_file, "Traceback (interpreter-level):" traceback.print_tb(self.debug_tbs[i], file=interpr_file) + from pypy.tool import tb_server + tb_server.publish_tb(self.debug_tbs[0]) self.print_app_tb_only(file) if space is None: exc_typename = str(self.w_type) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/py.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/py.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/py.py Fri Jun 4 14:15:52 2004 @@ -32,33 +32,42 @@ return options def main_(argv=None): + from pypy.tool import tb_server args = option.process_options(get_main_options(), Options, argv[1:]) - space = option.objspace() - go_interactive = Options.interactive - banner = '' - if Options.command: - args = ['-c'] - for arg in args: - space.call_method(space.sys.w_argv, 'append', space.wrap(arg)) - if Options.command: - try: - main.run_string(Options.command[0], '', space) - except error.PyPyError, pypyerr: - pypyerr.operationerr.print_detailed_traceback(pypyerr.space) - elif args: - try: - main.run_file(args[0], space) - except error.PyPyError, pypyerr: - pypyerr.operationerr.print_detailed_traceback(pypyerr.space) - else: - go_interactive = 1 - banner = None - if go_interactive: - con = interactive.PyPyConsole(space) - if banner == '': - banner = '%s / %s'%(con.__class__.__name__, - space.__class__.__name__) - con.interact(banner) + print 'options processed' + try: + space = option.objspace() + go_interactive = Options.interactive + banner = '' + if Options.command: + args = ['-c'] + for arg in args: + space.call_method(space.sys.w_argv, 'append', space.wrap(arg)) + if Options.command: + try: + main.run_string(Options.command[0], '', space) + except error.PyPyError, pypyerr: + pypyerr.operationerr.print_detailed_traceback(pypyerr.space) + elif args: + try: + main.run_file(args[0], space) + except error.PyPyError, pypyerr: + pypyerr.operationerr.print_detailed_traceback(pypyerr.space) + else: + go_interactive = 1 + banner = None + if go_interactive: + con = interactive.PyPyConsole(space) + if banner == '': + banner = '%s / %s'%(con.__class__.__name__, + space.__class__.__name__) + con.interact(banner) + except: + sys.excepthook(*sys.exc_info()) + print 'waiting' + tb_server.wait_until_interrupt() + + tb_server.stop() if __name__ == '__main__': try: Modified: pypy/branch/src-newobjectmodel/pypy/tool/option.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/option.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/option.py Fri Jun 4 14:15:52 2004 @@ -5,7 +5,11 @@ class Options: verbose = 0 showwarning = 0 - spaces = [] + spaces = [] + +def run_tb_server(option, opt, value, parser): + from pypy.tool import tb_server + tb_server.start() def get_standard_options(): options = [] @@ -35,6 +39,11 @@ options.append(make_option( '-w', action="store_true", dest="showwarning", help="enable warnings (disabled by default)")) + options.append(make_option( + '-H', action="callback", + callback=run_tb_server, + help="use web browser for traceback info")) + return options Added: pypy/branch/src-newobjectmodel/pypy/tool/tb_server.py ============================================================================== --- (empty file) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server.py Fri Jun 4 14:15:52 2004 @@ -0,0 +1,78 @@ +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +import threading +import sys + +global content +content = '' +server_thread = None + +class TBRequestHandler(BaseHTTPRequestHandler): + def do_GET(self): + if self.path == '/quit': + global server_thread + server_thread = None + raise SystemExit + self.send_response(200) + self.send_header("Content-Type", "text/plain") + self.end_headers() + self.wfile.write(content) + + def log_message(self, format, *args): + pass + +class TBServer(HTTPServer): + def handle_error(self, request, client_address): + exc = sys.exc_info()[1] + if isinstance(exc, (SystemExit, KeyboardInterrupt)): + raise + else: + HTTPServer.handle_error(self, request, client_address) + +def serve(): + port = 8080 + while 1: + try: + server = TBServer(('localhost', port), TBRequestHandler) + except socket.error: + port += 1 + continue + else: + break + global server_port + server_port = port + print "serving on", port + server.serve_forever() + +def start(): + global server_thread + server_thread = threading.Thread(target=serve) + server_thread.start() + return server_thread + +def stop(): + if server_thread is None: + return + import urllib2 + try: + urllib2.urlopen('http://localhost:%s/quit'%(server_port,)) + except urllib2.HTTPError: + pass + +def wait_until_interrupt(): + if server_thread is None: + return + import signal + try: + signal.pause() + except KeyboardInterrupt: + stop() + +def publish_tb(tb): + import traceback + s = traceback.format_tb(tb) + global content + content = ''.join(s) + +if __name__ == "__main__": + t = main() + wait_until_interrupt() From mwh at codespeak.net Fri Jun 4 14:27:48 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 14:27:48 +0200 (MEST) Subject: [pypy-svn] r4901 - in pypy/branch/src-newobjectmodel/pypy/tool: . tb_server Message-ID: <20040604122748.77C635BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 14:27:47 2004 New Revision: 4901 Added: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/__init__.py (contents, props changed) - copied, changed from r4898, pypy/branch/src-newobjectmodel/pypy/tool/__init__.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py - copied unchanged from r4900, pypy/branch/src-newobjectmodel/pypy/tool/tb_server.py Removed: pypy/branch/src-newobjectmodel/pypy/tool/tb_server.py Log: packagize tb_server Deleted: /pypy/branch/src-newobjectmodel/pypy/tool/tb_server.py ============================================================================== --- /pypy/branch/src-newobjectmodel/pypy/tool/tb_server.py Fri Jun 4 14:27:47 2004 +++ (empty file) @@ -1,78 +0,0 @@ -from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer -import threading -import sys - -global content -content = '' -server_thread = None - -class TBRequestHandler(BaseHTTPRequestHandler): - def do_GET(self): - if self.path == '/quit': - global server_thread - server_thread = None - raise SystemExit - self.send_response(200) - self.send_header("Content-Type", "text/plain") - self.end_headers() - self.wfile.write(content) - - def log_message(self, format, *args): - pass - -class TBServer(HTTPServer): - def handle_error(self, request, client_address): - exc = sys.exc_info()[1] - if isinstance(exc, (SystemExit, KeyboardInterrupt)): - raise - else: - HTTPServer.handle_error(self, request, client_address) - -def serve(): - port = 8080 - while 1: - try: - server = TBServer(('localhost', port), TBRequestHandler) - except socket.error: - port += 1 - continue - else: - break - global server_port - server_port = port - print "serving on", port - server.serve_forever() - -def start(): - global server_thread - server_thread = threading.Thread(target=serve) - server_thread.start() - return server_thread - -def stop(): - if server_thread is None: - return - import urllib2 - try: - urllib2.urlopen('http://localhost:%s/quit'%(server_port,)) - except urllib2.HTTPError: - pass - -def wait_until_interrupt(): - if server_thread is None: - return - import signal - try: - signal.pause() - except KeyboardInterrupt: - stop() - -def publish_tb(tb): - import traceback - s = traceback.format_tb(tb) - global content - content = ''.join(s) - -if __name__ == "__main__": - t = main() - wait_until_interrupt() Copied: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/__init__.py (from r4898, pypy/branch/src-newobjectmodel/pypy/tool/__init__.py) ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/__init__.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/__init__.py Fri Jun 4 14:27:47 2004 @@ -1 +1 @@ -#empty +from server import start, stop, publish_tb, wait_until_interrupt From hpk at codespeak.net Fri Jun 4 15:13:42 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 15:13:42 +0200 (MEST) Subject: [pypy-svn] r4903 - in pypy/branch/src-newobjectmodel: . pypy/tool/tb_server Message-ID: <20040604131342.36B5D5BE07@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 15:13:41 2004 New Revision: 4903 Added: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Modified: pypy/branch/src-newobjectmodel/ (props changed) pypy/branch/src-newobjectmodel/pypy/tool/tb_server/ (props changed) pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py (contents, props changed) Log: - added xpy for the time being - tb-rendering is more designed now ... more to follow Added: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- (empty file) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 15:13:41 2004 @@ -0,0 +1,34 @@ +from pypy.tool.tb_server.server import TBRequestHandler +from xpy import html, xml +import traceback + +views = TBRequestHandler.views +### +class TracebackView: + def __init__(self, tb): + self.name = 'traceback%d' % len(views) + views[self.name] = self + self.tb = tb + + def render(self, args): + tag = html.html( + html.head(), + html.body( + self.render_tb(args) + ) + ) + return tag.to_unicode() + + def render_tb(self, args): + try: + return self.render_tb_really(args) + except: + import sys, traceback + lines = traceback.format_tb(sys.exc_info()[2]) + return html.pre( + xml.escape(''.join(['Internal Rendering Error, traceback follows\n'] + lines))) + + def render_tb_really(self, args): + raise ValueError + + Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Fri Jun 4 15:13:41 2004 @@ -2,20 +2,36 @@ import threading import sys -global content -content = '' server_thread = None +server_port = None class TBRequestHandler(BaseHTTPRequestHandler): + views = {} + def do_GET(self): if self.path == '/quit': global server_thread server_thread = None raise SystemExit - self.send_response(200) - self.send_header("Content-Type", "text/plain") - self.end_headers() - self.wfile.write(content) + parts = [x for x in self.path.split('/') if x] + if not parts: + tb_name = 'traceback' + args = [] + else: + tb_name = parts[0] + args = parts[1:] + if not self.views.has_key(tb_name): + self.send_response(404) + self.send_header("Content-Type", "text/plain") + self.end_headers() + self.wfile.write('traceback named %r not found' % tb_name) + else: + tbview = self.views[tb_name] + s = tbview.render(args) + self.send_response(200) + self.send_header("Content-Type", "text/html ; charset=utf-8") + self.end_headers() + self.wfile.write(unicode(s).encode('utf8')) def log_message(self, format, *args): pass @@ -29,6 +45,7 @@ HTTPServer.handle_error(self, request, client_address) def serve(): + import socket port = 8080 while 1: try: @@ -68,10 +85,9 @@ stop() def publish_tb(tb): - import traceback - s = traceback.format_tb(tb) - global content - content = ''.join(s) + from pypy.tool.tb_server.render import TracebackView + x = TracebackView(tb) + print "traceback is at http://localhost:%d/%s" % (server_port, x.name) if __name__ == "__main__": t = main() From mwh at codespeak.net Fri Jun 4 15:18:29 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 15:18:29 +0200 (MEST) Subject: [pypy-svn] r4904 - pypy/branch/src-newobjectmodel/pypy/tool/tb_server Message-ID: <20040604131829.246985BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 15:18:28 2004 New Revision: 4904 Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Log: format Content-Type better Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Fri Jun 4 15:18:28 2004 @@ -29,7 +29,7 @@ tbview = self.views[tb_name] s = tbview.render(args) self.send_response(200) - self.send_header("Content-Type", "text/html ; charset=utf-8") + self.send_header("Content-Type", "text/html; charset=utf-8") self.end_headers() self.wfile.write(unicode(s).encode('utf8')) From mwh at codespeak.net Fri Jun 4 15:41:31 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 15:41:31 +0200 (MEST) Subject: [pypy-svn] r4908 - pypy/branch/src-newobjectmodel/pypy/tool/tb_server Message-ID: <20040604134131.78DF55BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 15:41:30 2004 New Revision: 4908 Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Log: start rendering tracebacks for real Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 15:41:30 2004 @@ -1,9 +1,13 @@ from pypy.tool.tb_server.server import TBRequestHandler from xpy import html, xml + +from std.magic import dyncode + import traceback -views = TBRequestHandler.views -### +views = TBRequestHandler.views + + class TracebackView: def __init__(self, tb): self.name = 'traceback%d' % len(views) @@ -29,6 +33,18 @@ xml.escape(''.join(['Internal Rendering Error, traceback follows\n'] + lines))) def render_tb_really(self, args): - raise ValueError + lines = html.pre() + for tb in dyncode.listtb(self.tb): + filename = tb.tb_frame.f_code.co_filename + lineno = tb.tb_lineno + name = tb.tb_frame.f_code.co_name + lines.append(' File "%s", line %d, in %s\n'%( + html.a(filename, href=filename).to_unicode().encode('utf-8'), + lineno, name)) + lines.append(dyncode.getline(filename, lineno)) + return lines + + + From arigo at codespeak.net Fri Jun 4 16:16:46 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 4 Jun 2004 16:16:46 +0200 (MEST) Subject: [pypy-svn] r4909 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace objspace/std Message-ID: <20040604141646.73D925BE07@thoth.codespeak.net> Author: arigo Date: Fri Jun 4 16:16:45 2004 New Revision: 4909 Added: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/itertype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/multimethod.py pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/nonetype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: First round at fixing the standard object space to adapt it to the new, descriptor-based object model. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Fri Jun 4 16:16:45 2004 @@ -161,7 +161,8 @@ def call_function(self, w_func, *args_w, **kw_w): w_kw = self.newdict([(self.wrap(k), w_v) for k, w_v in kw_w.iteritems()]) - return self.call(w_func, self.newtuple(list(args_w)), w_kw) + w_args = self.newtuple(list(args_w)) + return self.call(w_func, w_args, w_kw) def call_method(self, w_obj, methname, *arg_w, **kw_w): w_meth = self.getattr(w_obj, self.wrap(methname)) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Fri Jun 4 16:16:45 2004 @@ -47,12 +47,12 @@ # We try to give error messages following CPython's, which are # very informative. # - if w_kwds is None or not space.is_true(w_kwds): - w_kwargs = space.newdict([]) - else: - # space.is_true() above avoids infinite recursion copy<->parse_args - w_kwargs = space.call_method(w_kwds, "copy") - + if w_kwds is not None: + if space.is_true(w_kwds): + # space.is_true() avoids infinite recursion copy<->parse_args + w_kwargs = space.call_method(w_kwds, "copy") + else: + w_kwargs = None co_argcount = len(argnames) # expected formal arguments, without */** # put as many positional input arguments into place as available @@ -61,17 +61,19 @@ input_argcount = len(scope_w) # check that no keyword argument conflicts with these - for name in argnames[:input_argcount]: - w_name = space.wrap(name) - if space.is_true(space.contains(w_kwargs, w_name)): - self.raise_argerr_multiple_values(name) + if w_kwargs is not None: + for name in argnames[:input_argcount]: + w_name = space.wrap(name) + if space.is_true(space.contains(w_kwargs, w_name)): + self.raise_argerr_multiple_values(name) if input_argcount < co_argcount: # not enough args, fill in kwargs or defaults if exists def_first = co_argcount - len(self.defs_w) for i in range(input_argcount, co_argcount): w_name = space.wrap(argnames[i]) - if space.is_true(space.contains(w_kwargs, w_name)): + if (w_kwargs is not None and + space.is_true(space.contains(w_kwargs, w_name))): scope_w.append(space.getitem(w_kwargs, w_name)) space.delitem(w_kwargs, w_name) elif i >= def_first: @@ -86,11 +88,15 @@ self.raise_argerr(w_args, w_kwds, True) # collect extra keyword arguments into the **kwarg - if kwargname is not None: - # XXX this doesn't check that the keys of kwargs are strings - scope_w.append(w_kwargs) - elif space.is_true(w_kwargs): - self.raise_argerr_unknown_kwds(w_kwds) + if w_kwargs: + if kwargname is not None: + # XXX this doesn't check that the keys of kwargs are strings + scope_w.append(w_kwargs) + elif space.is_true(w_kwargs): + self.raise_argerr_unknown_kwds(w_kwds) + else: + if kwargname is not None: + scope_w.append(space.newdict([])) return scope_w # helper functions to build error message for the above @@ -170,7 +176,7 @@ def descr_function_call(self, *args_w, **kwds_w): # XXX refactor to avoid unwrapping and rewrapping all around space = self.space - return self.call(space.newtuple(args_w), + return self.call(space.newtuple(list(args_w)), space.newdict([(space.wrap(key), w_item) for key, w_item in kwds_w.items()])) @@ -211,6 +217,6 @@ def descr_method_call(self, *args_w, **kwds_w): # XXX refactor to avoid unwrapping and rewrapping all around space = self.space - return self.call(space.newtuple(args_w), + return self.call(space.newtuple(list(args_w)), space.newdict([(space.wrap(key), w_item) for key, w_item in kwds_w.items()])) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Fri Jun 4 16:16:45 2004 @@ -86,12 +86,15 @@ w_impl = space.get(w_descr, w_obj, space.type(w_obj)) return space.call_function(w_impl, *args_w, **kwargs_w) + def unwrap_builtin(self, w_obj): + return w_obj # hook for hack by TrivialObjSpace + def call(space, w_obj, w_args, w_kwargs): #print "call %r, %r, %r" %(w_obj, w_args, w_kwargs) w_descr = space.lookup(w_obj, '__call__') if w_descr is None: raise OperationError(space.w_TypeError, - space.wrap('object is not callable')) + space.wrap('object %r is not callable' % (w_obj,))) return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) def get(space,w_descr,w_obj,w_type): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py Fri Jun 4 16:16:45 2004 @@ -1,18 +1,9 @@ -""" -Reviewed 03-06-21 -There are no new methods here, since everything is inherited -from int, except: - -__repr__ tested, OK -""" - from pypy.objspace.std.objspace import * -from booltype import W_BoolType import intobject class W_BoolObject(W_Object): - statictype = W_BoolType + from booltype import bool_typedef as typedef def __init__(w_self, space, boolval): W_Object.__init__(w_self, space) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py Fri Jun 4 16:16:45 2004 @@ -1,34 +1,15 @@ -""" -Reviewed 03-06-21 -""" +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.inttype import int_typedef -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject -from inttype import W_IntType - -class W_BoolType(W_TypeObject): - - typename = 'bool' - staticbases = (W_IntType,) - -registerimplementation(W_BoolType) - -def type_new__BoolType_BoolType(space, w_basetype, w_booltype, w_args, w_kwds): - if space.is_true(w_kwds): - raise OperationError(space.w_TypeError, - space.wrap("no keyword arguments expected")) - args = space.unpackiterable(w_args) - if len(args) == 0: - return space.w_False, True - elif len(args) == 1: - arg = args[0] - if space.is_true(arg): - return space.w_True, True - else: - return space.w_False, True +def descr__new__(space, w_booltype, w_obj=None): + if space.is_true(w_obj): + return space.w_True else: - raise OperationError(space.w_TypeError, - space.wrap("bool() takes at most 1 argument")) + return space.w_False + +# ____________________________________________________________ -register_all(vars()) +bool_typedef = StdTypeDef("bool", [int_typedef], + __new__ = newmethod(descr__new__), + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py Fri Jun 4 16:16:45 2004 @@ -23,8 +23,7 @@ def __repr__(w_self): """ representation for debugging purposes """ - return "wrap(%r)" % (w_self.cpyobj,) - + return "cpyobj(%r)" % (w_self.cpyobj,) registerimplementation(W_CPythonObject) @@ -216,8 +215,8 @@ raise ValueError, '_arity too large' arglist = [W_CPythonObject] + [W_ANY]*(_arity-1) - if _name == 'getattr': _name = 'getattribute' # XXX hack - multimethod = getattr(StdObjSpace, _name) + #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: @@ -302,7 +301,7 @@ wrap_exception(space) return space.wrap(result) -def call__CPython_ANY_ANY(space, w_obj, w_arguments, w_keywords): +def call__CPython(space, w_obj, w_arguments, w_keywords): # XXX temporary hack similar to objspace.trivial.call() callable = space.unwrap(w_obj) if hasattr(callable, 'pypy_call'): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py Fri Jun 4 16:16:45 2004 @@ -18,11 +18,12 @@ # __nonzero__ falls back to __len__ def is_true__Object(space, w_obj): - try: - w_len = space.len.perform_call((w_obj,)) - except FailedToImplement: - return True # everything is True unless otherwise specified - return space.is_true(space.ne(w_len, space.newint(0))) + w_descr = space.lookup(w_obj, '__len__') + if w_descr is None: + return True + else: + w_len = space.get_and_call_function(w_descr, w_obj) + return space.is_true(w_len) # in-place operators fall back to their non-in-place counterpart @@ -31,160 +32,160 @@ def default_inplace(space, w_1, w_2, baseop=_name[8:]): op = getattr(space, baseop) return op(w_1, w_2) - getattr(StdObjSpace, _name).register(default_inplace, - W_Object, W_ANY) + getattr(StdObjSpace.MM, _name).register(default_inplace, + W_Object, W_ANY) # '__get__(descr, inst, cls)' returns 'descr' by default -def get__Object_ANY_ANY(space, w_descr, w_inst, w_cls): - return w_descr +#def get__Object_ANY_ANY(space, w_descr, w_inst, w_cls): +# return w_descr -def is_data_descr__Object(space, w_descr): - return 0 +#def is_data_descr__Object(space, w_descr): +# return 0 # give objects some default attributes and a default way to complain # about missing attributes -def getattribute__Object_ANY(space, w_obj, w_attr): - # XXX build a nicer error message along these lines: - #w_type = space.type(w_obj) - #w_typename = space.getattr(w_type, space.wrap('__name__')) - #... - - w_type = space.type(w_obj) - if space.is_true(space.eq(w_attr, space.wrap('__class__'))): - return w_type - - # 1) look for descriptor - # 2) if data descriptor, call it - # 3) check __dict__ - # 4) if present, return that - # 5) if descriptor found in 2), call that - # 6) raise AttrbuteError - - w_descr = None - - from typeobject import W_TypeObject - if isinstance(w_type, W_TypeObject): # XXX must always be true at some point - try: - w_descr = w_type.lookup(w_attr) - except KeyError: - pass - else: - if space.is_data_descr(w_descr): - return space.get(w_descr, w_obj, w_type) # XXX 3rd arg is wrong +##def getattribute__Object_ANY(space, w_obj, w_attr): +## # XXX build a nicer error message along these lines: +## #w_type = space.type(w_obj) +## #w_typename = space.getattr(w_type, space.wrap('__name__')) +## #... + +## w_type = space.type(w_obj) +## if space.is_true(space.eq(w_attr, space.wrap('__class__'))): +## return w_type + +## # 1) look for descriptor +## # 2) if data descriptor, call it +## # 3) check __dict__ +## # 4) if present, return that +## # 5) if descriptor found in 2), call that +## # 6) raise AttrbuteError + +## w_descr = None + +## from typeobject import W_TypeObject +## if isinstance(w_type, W_TypeObject): # XXX must always be true at some point +## try: +## w_descr = w_type.lookup(w_attr) +## except KeyError: +## pass +## else: +## if space.is_data_descr(w_descr): +## return space.get(w_descr, w_obj, w_type) # XXX 3rd arg is wrong - try: - w_dict = space.getdict(w_obj) - except OperationError, e: - if not e.match(space, space.w_TypeError): # 'unsupported type for getdict' - raise - else: - if space.is_true(space.eq(w_attr, space.wrap('__dict__'))): - return w_dict - try: - w_value = space.getitem(w_dict, w_attr) - except OperationError, e: - if not e.match(space, space.w_KeyError): - raise - else: - return w_value # got a value from 'obj.__dict__[attr]' +## try: +## w_dict = space.getdict(w_obj) +## except OperationError, e: +## if not e.match(space, space.w_TypeError): # 'unsupported type for getdict' +## raise +## else: +## if space.is_true(space.eq(w_attr, space.wrap('__dict__'))): +## return w_dict +## try: +## w_value = space.getitem(w_dict, w_attr) +## except OperationError, e: +## if not e.match(space, space.w_KeyError): +## raise +## else: +## return w_value # got a value from 'obj.__dict__[attr]' - if w_descr is not None: - return space.get(w_descr, w_obj, w_type) +## if w_descr is not None: +## return space.get(w_descr, w_obj, w_type) - raise OperationError(space.w_AttributeError, w_attr) +## raise OperationError(space.w_AttributeError, w_attr) # set attributes, complaining about read-only ones -- # a more declarative way to define attributes would be welcome -def setattr__Object_ANY_ANY(space, w_obj, w_attr, w_value): - - # 1) look for descriptor - # 2) if data descriptor, call it - # 3) try to set item in __dict__ - - w_type = space.type(w_obj) - if space.is_true(space.eq(w_attr, space.wrap('__class__'))): - raise OperationError(space.w_AttributeError, - space.wrap("read-only attribute")) - if space.is_true(space.eq(w_attr, space.wrap('__dict__'))): - raise OperationError(space.w_AttributeError, - space.wrap("read-only attribute")) +##def setattr__Object_ANY_ANY(space, w_obj, w_attr, w_value): - from typeobject import W_TypeObject - if isinstance(w_type, W_TypeObject): - try: - w_descr = w_type.lookup(w_attr) - except KeyError: - pass - else: - if space.is_data_descr(w_descr): - return space.set(w_descr, w_obj, w_value) +## # 1) look for descriptor +## # 2) if data descriptor, call it +## # 3) try to set item in __dict__ + +## w_type = space.type(w_obj) +## if space.is_true(space.eq(w_attr, space.wrap('__class__'))): +## raise OperationError(space.w_AttributeError, +## space.wrap("read-only attribute")) +## if space.is_true(space.eq(w_attr, space.wrap('__dict__'))): +## raise OperationError(space.w_AttributeError, +## space.wrap("read-only attribute")) + +## from typeobject import W_TypeObject +## if isinstance(w_type, W_TypeObject): +## try: +## w_descr = w_type.lookup(w_attr) +## except KeyError: +## pass +## else: +## if space.is_data_descr(w_descr): +## return space.set(w_descr, w_obj, w_value) - try: - w_dict = space.getdict(w_obj) - except OperationError, e: - if not e.match(space, space.w_TypeError): # "unsupported type for getdict" - raise - raise OperationError(space.w_AttributeError, w_attr) - else: - space.setitem(w_dict, w_attr, w_value) +## try: +## w_dict = space.getdict(w_obj) +## except OperationError, e: +## if not e.match(space, space.w_TypeError): # "unsupported type for getdict" +## raise +## raise OperationError(space.w_AttributeError, w_attr) +## else: +## space.setitem(w_dict, w_attr, w_value) -def delattr__Object_ANY(space, w_obj, w_attr): - w_type = space.type(w_obj) - if space.is_true(space.eq(w_attr, space.wrap('__class__'))): - raise OperationError(space.w_AttributeError, - space.wrap("read-only attribute")) - if space.is_true(space.eq(w_attr, space.wrap('__dict__'))): - raise OperationError(space.w_AttributeError, - space.wrap("read-only attribute")) - - from typeobject import W_TypeObject - if isinstance(w_type, W_TypeObject): - try: - w_descr = w_type.lookup(w_attr) - except KeyError: - pass - else: - #space.type(w_descr).lookup(space.wrap('__delete__')) - if space.is_data_descr(w_descr): - return space.delete(w_descr, w_obj) +##def delattr__Object_ANY(space, w_obj, w_attr): +## w_type = space.type(w_obj) +## if space.is_true(space.eq(w_attr, space.wrap('__class__'))): +## raise OperationError(space.w_AttributeError, +## space.wrap("read-only attribute")) +## if space.is_true(space.eq(w_attr, space.wrap('__dict__'))): +## raise OperationError(space.w_AttributeError, +## space.wrap("read-only attribute")) + +## from typeobject import W_TypeObject +## if isinstance(w_type, W_TypeObject): +## try: +## w_descr = w_type.lookup(w_attr) +## except KeyError: +## pass +## else: +## #space.type(w_descr).lookup(space.wrap('__delete__')) +## if space.is_data_descr(w_descr): +## return space.delete(w_descr, w_obj) - try: - w_dict = space.getdict(w_obj) - except OperationError, e: - if not e.match(space, space.w_TypeError): # "unsupported type for getdict" - raise - raise OperationError(space.w_AttributeError, w_attr) - else: - try: - space.delitem(w_dict, w_attr) - except OperationError, e: - if not e.match(space, space.w_KeyError): - raise - raise OperationError(space.w_AttributeError, w_attr) +## try: +## w_dict = space.getdict(w_obj) +## except OperationError, e: +## if not e.match(space, space.w_TypeError): # "unsupported type for getdict" +## raise +## raise OperationError(space.w_AttributeError, w_attr) +## else: +## try: +## space.delitem(w_dict, w_attr) +## except OperationError, e: +## if not e.match(space, space.w_KeyError): +## raise +## raise OperationError(space.w_AttributeError, w_attr) # static types -def type__Object(space, w_obj): - if w_obj.statictype is None: - # XXX remove me, temporary - return space.wrap(space.unwrap(w_obj).__class__) - else: - w_type = space.get_typeinstance(w_obj.statictype) - return w_type +##def type__Object(space, w_obj): +## if w_obj.statictype is None: +## # XXX remove me, temporary +## return space.wrap(space.unwrap(w_obj).__class__) +## else: +## w_type = space.get_typeinstance(w_obj.statictype) +## return w_type # repr(), str(), hash() -def repr__Object(space, w_obj): - return space.wrap('<%s object at %s>'%( - space.type(w_obj).typename, space.unwrap(space.id(w_obj)))) +##def repr__Object(space, w_obj): +## return space.wrap('<%s object at %s>'%( +## space.type(w_obj).typename, space.unwrap(space.id(w_obj)))) -def str__Object(space, w_obj): - return space.repr(w_obj) +##def str__Object(space, w_obj): +## return space.repr(w_obj) def hash__Object(space, w_obj): return space.id(w_obj) @@ -211,5 +212,13 @@ if space.is_true(space.eq(w_next, w_lookfor)): return space.w_True +# ugh + +def unwrap__ANY(space, w_obj): + if isinstance(w_obj, Wrappable): + return w_obj + else: + raise TypeError, 'cannot unwrap %r' % (w_obj,) + register_all(vars()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py Fri Jun 4 16:16:45 2004 @@ -7,7 +7,6 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from dicttype import W_DictType from stringobject import W_StringObject class _NoValueInCell: pass @@ -39,7 +38,7 @@ class W_DictObject(W_Object): - statictype = W_DictType + from pypy.objspace.std.dicttype import dict_typedef as typedef def __init__(w_self, space, list_pairs_w): W_Object.__init__(w_self, space) @@ -125,7 +124,13 @@ cell.make_empty() return raise OperationError(space.w_KeyError, w_lookup) - + +def is_true__Dict(space, w_dict): + # this must be implemented in addition to len() for dictionaries + # for infinite recursion reasons (is_true -> len -> call to len -> + # checking for keywords -> is_true etc.) + return not not w_dict.non_empties() + def len__Dict(space, w_dict): return space.wrap(len(w_dict.non_empties())) @@ -226,5 +231,5 @@ return "{%s}" % ', '.join(items) repr__Dict = str__Dict = gateway.app2interp(app_str__Dict) -register_all(vars(), W_DictType) - +from pypy.objspace.std import dicttype +register_all(vars(), dicttype) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py Fri Jun 4 16:16:45 2004 @@ -1,40 +1,24 @@ -""" -Reviewed 03-06-22 -""" - -from pypy.objspace.std.objspace import * -from pypy.interpreter import gateway -from typeobject import W_TypeObject -from listobject import W_ListObject - -class W_DictType(W_TypeObject): - - typename = 'dict' - - dict_copy = MultiMethod('copy', 1) - dict_items = MultiMethod('items', 1) - dict_keys = MultiMethod('keys', 1) - dict_values = MultiMethod('values', 1) - dict_has_key = MultiMethod('has_key', 2) - dict_clear = MultiMethod('clear', 1) - dict_get = MultiMethod('get', 3, defaults=(None,)) - dict_pop = MultiMethod('pop', 2, varargs=True) - dict_popitem = MultiMethod('popitem', 1) - dict_setdefault = MultiMethod('setdefault', 3, defaults=(None,)) - dict_update = MultiMethod('update', 2) - dict_iteritems = MultiMethod('iteritems', 1) - dict_iterkeys = MultiMethod('iterkeys', 1) - dict_itervalues = MultiMethod('itervalues', 1) - dict_fromkeys = MultiMethod('fromkeys', 2, varargs=True) - # This can return when multimethods have been fixed - #dict_str = StdObjSpace.str - -registerimplementation(W_DictType) - - -def type_new__DictType_DictType(space, w_basetype, w_dicttype, w_args, w_kwds): - return space.newdict([]), True - +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef +from pypy.objspace.std.register_all import register_all + +dict_copy = MultiMethod('copy', 1) +dict_items = MultiMethod('items', 1) +dict_keys = MultiMethod('keys', 1) +dict_values = MultiMethod('values', 1) +dict_has_key = MultiMethod('has_key', 2) +dict_clear = MultiMethod('clear', 1) +dict_get = MultiMethod('get', 3, defaults=(None,)) +dict_pop = MultiMethod('pop', 2, varargs=True) +dict_popitem = MultiMethod('popitem', 1) +dict_setdefault = MultiMethod('setdefault', 3, defaults=(None,)) +dict_update = MultiMethod('update', 2) +dict_iteritems = MultiMethod('iteritems', 1) +dict_iterkeys = MultiMethod('iterkeys', 1) +dict_itervalues = MultiMethod('itervalues', 1) +#dict_fromkeys = MultiMethod('fromkeys', 2, varargs=True) +# This can return when multimethods have been fixed +#dict_str = StdObjSpace.str # default application-level implementations for some operations @@ -85,15 +69,17 @@ def app_dict_itervalues__ANY(d): return iter(d.values()) -def app_dict_fromkeys__ANY_List(d, seq, value): - d = {} - if value: - value = value[0] - else: - value = None - for item in seq: - d[item] = value - return d +#def app_dict_fromkeys__ANY_List(d, seq, value): +# d = {} +# if value: +# value = value[0] +# else: +# value = None +# for item in seq: +# d[item] = value +# return d +#XXX implement dict.fromkeys() which must be a static method +#XXX accepting any iterable # This can return when multimethods have been fixed """ @@ -104,4 +90,17 @@ return "{%s}" % ', '.join(items) """ gateway.importall(globals()) -register_all(vars(), W_DictType) +register_all(vars(), globals()) + +# ____________________________________________________________ + +def descr__new__(space, w_dicttype, *args_w, **kwds_w): + from pypy.objspace.std.dictobject import W_DictObject + return W_DictObject(space, []) + +# ____________________________________________________________ + +dict_typedef = StdTypeDef("dict", [object_typedef], + __new__ = newmethod(descr__new__), + ) +dict_typedef.registermethods(globals()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py Fri Jun 4 16:16:45 2004 @@ -1,6 +1,5 @@ from pypy.objspace.std.objspace import * from noneobject import W_NoneObject -from floattype import W_FloatType ############################################################## # for the time being, all calls that are made to some external @@ -15,7 +14,7 @@ """This is a reimplementation of the CPython "PyFloatObject" it is assumed that the constructor takes a real Python float as an argument""" - statictype = W_FloatType + from pypy.objspace.std.floattype import float_typedef as typedef def __init__(w_self, space, floatval): W_Object.__init__(w_self, space) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py Fri Jun 4 16:16:45 2004 @@ -1,34 +1,18 @@ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef - -class W_FloatType(W_TypeObject): - - typename = 'float' - -registerimplementation(W_FloatType) - - -def type_new__FloatType_FloatType(space, w_basetype, w_floattype, w_args, w_kwds): - if space.is_true(w_kwds): - raise OperationError(space.w_TypeError, - space.wrap("no keyword arguments expected")) - args = space.unpackiterable(w_args) - if len(args) == 0: - return space.newfloat(0), True - elif len(args) == 1: - arg = args[0] - if space.is_true(space.issubtype(space.type(arg), - space.w_str)): - try: - return space.newfloat(float(space.unwrap(arg))), True - except ValueError, e: - raise OperationError(space.w_ValueError, - space.wrap(str(e))) - else: - return space.float(args[0]), True +def descr__new__(space, w_floattype, w_value=0): + if space.is_true(space.isinstance(w_value, space.w_str)): + try: + return space.newfloat(float(space.unwrap(w_value))) + except ValueError, e: + raise OperationError(space.w_ValueError, + space.wrap(str(e))) else: - raise OperationError(space.w_TypeError, - space.wrap("float() takes at most 1 argument")) + return space.float(w_value) + +# ____________________________________________________________ -register_all(vars()) +float_typedef = StdTypeDef("float", [object_typedef], + __new__ = newmethod(descr__new__), + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py Fri Jun 4 16:16:45 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.objspace import * -from inttype import W_IntType from noneobject import W_NoneObject from restricted_int import r_int, LONG_BIT @@ -19,7 +18,7 @@ """ class W_IntObject(W_Object): - statictype = W_IntType + from inttype import int_typedef as typedef def __init__(w_self, space, intval): W_Object.__init__(w_self, space) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py Fri Jun 4 16:16:45 2004 @@ -1,32 +1,17 @@ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef -class W_IntType(W_TypeObject): - - typename = 'int' - -registerimplementation(W_IntType) - - -def type_new__IntType_IntType(space, w_basetype, w_inttype, w_args, w_kwds): - if space.is_true(w_kwds): - raise OperationError(space.w_TypeError, - space.wrap("no keyword arguments expected")) - args = space.unpackiterable(w_args) - arglen = len(args) - - if arglen == 0: - return space.newint(0), True - elif arglen > 2: - raise OperationError(space.w_TypeError, - space.wrap("int() takes at most 2 arguments")) - elif space.is_true(space.issubtype(space.type(args[0]), space.w_str)): +def descr__new__(space, w_inttype, w_value=0, w_base=None): + from intobject import W_IntObject + if w_base == space.w_None: + return space.int(w_value) + else: + # XXX write the logic for int("str", base) + s = space.unwrap(w_value) + base = space.unwrap(w_base) try: - if arglen == 1: - return space.newint(int(space.unwrap(args[0]))), True - else: - return space.newint(int(space.unwrap(args[0]),space.unwrap(args[1]))), True + value = int(s, base) except TypeError, e: raise OperationError(space.w_TypeError, space.wrap(str(e))) @@ -36,10 +21,10 @@ except OverflowError, e: raise OperationError(space.w_OverflowError, space.wrap(str(e))) - elif arglen == 2: - raise OperationError(space.w_TypeError, - space.wrap("int() can't convert non-string with explicit base")) - else: - return space.int(args[0]), True + return W_IntObject(value) + +# ____________________________________________________________ -register_all(vars()) +int_typedef = StdTypeDef("int", [object_typedef], + __new__ = newmethod(descr__new__), + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/iterobject.py Fri Jun 4 16:16:45 2004 @@ -5,12 +5,11 @@ for function-iteration. """ from pypy.objspace.std.objspace import * -from itertype import W_SeqIterType class W_SeqIterObject(W_Object): - statictype = W_SeqIterType - + from pypy.objspace.std.itertype import iter_typedef as typedef + def __init__(w_self, space, w_seq, index=0): W_Object.__init__(w_self, space) w_self.w_seq = w_seq Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/itertype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/itertype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/itertype.py Fri Jun 4 16:16:45 2004 @@ -1,12 +1,10 @@ """ Reviewed 03-06-22 """ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef +# ____________________________________________________________ -class W_SeqIterType(W_TypeObject): - - typename = 'SeqIterType' - -registerimplementation(W_SeqIterType) +iter_typedef = StdTypeDef("sequence-iterator", [object_typedef], + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py Fri Jun 4 16:16:45 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.objspace import * -from listtype import W_ListType from intobject import W_IntObject from sliceobject import W_SliceObject from tupleobject import W_TupleObject @@ -10,8 +9,8 @@ class W_ListObject(W_Object): - statictype = W_ListType - + from pypy.objspace.std.listtype import list_typedef as typedef + def __init__(w_self, space, wrappeditems): W_Object.__init__(w_self, space) w_self.ob_item = [] @@ -54,7 +53,7 @@ w_item = space.next(w_iterator) except OperationError, e: if not e.match(space, space.w_StopIteration): - raise + raise break # done _ins1(w_list, w_list.ob_size, w_item) else: @@ -535,4 +534,5 @@ }; """ -register_all(vars(), W_ListType) +from pypy.objspace.std import listtype +register_all(vars(), listtype) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py Fri Jun 4 16:16:45 2004 @@ -1,25 +1,25 @@ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef from sys import maxint -class W_ListType(W_TypeObject): - - typename = 'list' - - list_append = MultiMethod('append', 2) - list_insert = MultiMethod('insert', 3) - list_extend = MultiMethod('extend', 2) - list_pop = MultiMethod('pop', 2, defaults=(-1,)) - list_remove = MultiMethod('remove', 2) - list_index = MultiMethod('index', 4, defaults=(0,maxint)) - list_count = MultiMethod('count', 2) - list_reverse= MultiMethod('reverse',1) - list_sort = MultiMethod('sort', 2, defaults=(None,)) - -registerimplementation(W_ListType) - - -def type_new__ListType_ListType(space, w_basetype, w_listtype, w_args, w_kwds): - return space.newlist([]), True - -register_all(vars()) +list_append = MultiMethod('append', 2) +list_insert = MultiMethod('insert', 3) +list_extend = MultiMethod('extend', 2) +list_pop = MultiMethod('pop', 2, defaults=(-1,)) +list_remove = MultiMethod('remove', 2) +list_index = MultiMethod('index', 4, defaults=(0,maxint)) +list_count = MultiMethod('count', 2) +list_reverse= MultiMethod('reverse',1) +list_sort = MultiMethod('sort', 2, defaults=(None,)) + +# ____________________________________________________________ + +def descr__new__(space, w_listtype, *args_w, **kwds_w): + return space.newlist([]) + +# ____________________________________________________________ + +list_typedef = StdTypeDef("list", [object_typedef], + __new__ = newmethod(descr__new__), + ) +list_typedef.registermethods(globals()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/multimethod.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/multimethod.py Fri Jun 4 16:16:45 2004 @@ -6,7 +6,7 @@ class W_ANY: "Catch-all in case multimethods don't find anything else." - statictype = None + typedef = None # This file defines three major classes: @@ -364,7 +364,7 @@ # restriction of the present UnboundMultiMethod. # Only accept an exact match; having merely subclass should # be taken care of by the general look-up rules. - t = types[self.bound_position].statictype + t = types[self.bound_position].typedef return t is self.typeclass def __get__(self, space, cls=None): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py Fri Jun 4 16:16:45 2004 @@ -5,10 +5,9 @@ """ from pypy.objspace.std.objspace import * -from nonetype import W_NoneType class W_NoneObject(W_Object): - statictype = W_NoneType + from pypy.objspace.std.nonetype import none_typedef as typedef registerimplementation(W_NoneObject) def unwrap__None(space, w_none): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/nonetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/nonetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/nonetype.py Fri Jun 4 16:16:45 2004 @@ -1,9 +1,8 @@ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef -class W_NoneType(W_TypeObject): +# ____________________________________________________________ - typename = 'NoneType' - -registerimplementation(W_NoneType) +none_typedef = StdTypeDef("NoneType", [object_typedef], + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py Fri Jun 4 16:16:45 2004 @@ -4,12 +4,7 @@ class W_ObjectObject(W_Object): """Instances of this class are what the user can directly see with an 'object()' call.""" - #statictype = W_ObjectType (hacked into place below) - - -import objecttype -W_ObjectObject.statictype = objecttype.W_ObjectType -registerimplementation(W_ObjectObject) + from pypy.objspace.std.objecttype import object_typedef as typedef # any-to-object delegation is quite trivial, because W_ObjectObject is. @@ -18,8 +13,8 @@ delegate__ANY.result_class = W_ObjectObject delegate__ANY.priority = PRIORITY_PARENT_TYPE -def object_init__Object(space, w_object, w_args, w_kwds): - pass +#def object_init__Object(space, w_object, w_args, w_kwds): +# pass register_all(vars()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py Fri Jun 4 16:16:45 2004 @@ -1,35 +1,41 @@ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.descroperation import Object +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.register_all import register_all +object_init = MultiMethod('__init__', 1, varargs=True, keywords=True) -class W_ObjectType(W_TypeObject): - """The single instance of W_ObjectType is what the user sees as - '__builtin__.object'.""" +def object_init__ANY(space, w_obj, w_args, w_kwds): + pass - typename = 'object' - staticbases = () +register_all(vars(), globals()) - # all multimethods that we want to be visible as object.__xxx__ - # should be defined here. +# ____________________________________________________________ - object_getattr = StdObjSpace.getattribute - object_setattr = StdObjSpace.setattr - object_delattr = StdObjSpace.delattr - object_type = StdObjSpace.type - object_repr = StdObjSpace.repr - object_str = StdObjSpace.str - object_hash = StdObjSpace.hash +def descr__repr__(space, w_obj): + w = space.wrap + classname = space.unwrap(space.getattr(space.type(w_obj), w("__name__"))) + id = space.unwrap(space.id(w_obj)) + return w("<%s object at 0x%x>" % (classname, id)) - # this is a method in 'object' because it is not an object space operation - object_init = MultiMethod('__init__', 1, varargs=True, keywords=True) +def descr__str__(space, w_obj): + return space.repr(w_obj) -registerimplementation(W_ObjectType) +def descr__class__(space, w_obj): + return space.type(w_obj) - -def type_new__ObjectType_ObjectType(space, w_basetype, w_objecttype, w_args, w_kwds): +def descr__new__(space, w_type, *args_w, **kwds_w): # XXX 2.2 behavior: ignoring all arguments from objectobject import W_ObjectObject - return W_ObjectObject(space), True + return W_ObjectObject(space) +# ____________________________________________________________ -register_all(vars(), W_ObjectType) +object_typedef = StdTypeDef("object", [], + __getattribute__ = gateway.interp2app(Object.descr__getattribute__.im_func), + __setattr__ = gateway.interp2app(Object.descr__setattr__.im_func), + __delattr__ = gateway.interp2app(Object.descr__delattr__.im_func), + __str__ = gateway.interp2app(descr__str__), + __repr__ = gateway.interp2app(descr__repr__), + __class__ = GetSetProperty(descr__class__), + __new__ = newmethod(descr__new__), + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Fri Jun 4 16:16:45 2004 @@ -1,11 +1,12 @@ -from register_all import register_all +from pypy.objspace.std.register_all import register_all from pypy.interpreter.baseobjspace import * -from multimethod import * +from pypy.objspace.std.multimethod import * +from pypy.objspace.descroperation import DescrOperation class W_Object: "Parent base class for wrapped objects." - statictype = None + typedef = None def __init__(w_self, space): w_self.space = space # XXX not sure this is ever used any more @@ -13,16 +14,10 @@ def __repr__(self): return '' % ( self.__class__.__name__, - getattr(self, 'statictype', '') + #', '.join(['%s=%r' % keyvalue for keyvalue in self.__dict__.items()]) + getattr(self, 'name', '') ) -class W_AbstractTypeObject(W_Object): - "Do not use. For W_TypeObject only." - - -BoundMultiMethod.ASSERT_BASE_TYPE = W_Object -MultiMethod.BASE_TYPE_OBJECT = W_AbstractTypeObject - # delegation priorities PRIORITY_SAME_TYPE = 2 # converting between several impls of the same type PRIORITY_PARENT_TYPE = 1 # converting to a base type (e.g. bool -> int) @@ -32,14 +27,14 @@ def registerimplementation(implcls): # this function should ultimately register the implementation class somewhere - # it may be modified to take 'statictype' instead of requiring it to be + # it may be modified to take 'typedef' instead of requiring it to be # stored in 'implcls' itself assert issubclass(implcls, W_Object) ################################################################## -class StdObjSpace(ObjSpace): +class StdObjSpace(ObjSpace, DescrOperation): """The standard object space, implementing a general-purpose object library in Restricted Python.""" @@ -49,21 +44,21 @@ class result: "Import here the types you want to have appear in __builtin__." - from objecttype import W_ObjectType - from booltype import W_BoolType - from inttype import W_IntType - from floattype import W_FloatType - from tupletype import W_TupleType - from listtype import W_ListType - from dicttype import W_DictType - from stringtype import W_StringType - from typetype import W_TypeType - from slicetype import W_SliceType + from objecttype import object_typedef + #from booltype import W_BoolType + from inttype import int_typedef + #from floattype import W_FloatType + #from tupletype import W_TupleType + #from listtype import W_ListType + #from dicttype import W_DictType + #from stringtype import W_StringType + from typetype import type_typedef + #from slicetype import W_SliceType return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look def clone_exception_hierarchy(self): - from usertype import W_UserType + from pypy.objspace.std.typeobject import W_TypeObject from pypy.interpreter import gateway w = self.wrap def app___init__(self, *args): @@ -84,15 +79,12 @@ # but being able to do that depends on the existence of some # of the exceptions... - self.w_Exception = W_UserType( + self.w_Exception = W_TypeObject( self, - w('Exception'), - self.newtuple([]), - self.newdict([(w('__init__'), w_init), - (w('__str__'), w_str)])) - - self.w_IndexError = self.w_StopIteration = self.w_Exception - + 'Exception', + [], + {'__init__': w_init, + '__str__': w_str}) done = {'Exception': self.w_Exception} # some of the complexity of the following is due to the fact @@ -115,11 +107,11 @@ continue else: base = done[b.__name__] - newtype = self.call_function( - self.w_type, - w(next), - self.newtuple([base]), - self.newdict([])) + newtype = W_TypeObject( + self, + next, + [base], + {}) setattr(self, 'w_' + next, newtype) @@ -132,7 +124,6 @@ def initialize(self): from noneobject import W_NoneObject from boolobject import W_BoolObject - from cpythonobject import W_CPythonObject # singletons self.w_None = W_NoneObject(self) @@ -151,10 +142,10 @@ # types self.types_w = {} - for typeclass in self.standard_types(): - w_type = self.get_typeinstance(typeclass) - setattr(self, 'w_' + typeclass.typename, w_type) - for_builtins[typeclass.typename] = w_type + for typedef in self.standard_types(): + w_type = self.gettypeobject(typedef) + setattr(self, 'w_' + typedef.name, w_type) + for_builtins[typedef.name] = w_type # exceptions for_builtins.update(self.clone_exception_hierarchy()) @@ -165,14 +156,14 @@ for key, w_value in for_builtins.items(): self.setitem(self.w_builtins, self.wrap(key), w_value) - def get_typeinstance(self, typeclass): - assert typeclass.typename is not None, ( - "get_typeinstance() cannot be used for %r" % typeclass) - # types_w maps each W_XxxType class to its unique-for-this-space instance + def gettypeobject(self, typedef): + # types_w maps each StdTypeDef instance to its + # unique-for-this-space W_TypeObject instance try: - w_type = self.types_w[typeclass] - except: - w_type = self.types_w[typeclass] = typeclass(self) + w_type = self.types_w[typedef] + except KeyError: + from pypy.objspace.std.stdtypedef import buildtypeobject + w_type = self.types_w[typedef] = buildtypeobject(typedef, self) return w_type def wrap(self, x): @@ -207,8 +198,8 @@ wrappeditems = [self.wrap(item) for item in x] import listobject return listobject.W_ListObject(self, wrappeditems) - if hasattr(type(x), '__wrap__'): - return x.__wrap__(self) + if isinstance(x, Wrappable): + return x.__spacebind__(self) #print "wrapping %r (%s)" % (x, type(x)) import cpythonobject return cpythonobject.W_CPythonObject(self, x) @@ -222,6 +213,7 @@ return floatobject.W_FloatObject(self, int_w) def newtuple(self, list_w): + assert isinstance(list_w, list) import tupleobject return tupleobject.W_TupleObject(self, list_w) @@ -250,37 +242,41 @@ import stringobject return stringobject.W_StringObject(self, ''.join(chars)) - # special multimethods + def type(self, w_obj): + assert w_obj.typedef, w_obj + return self.gettypeobject(w_obj.typedef) + + def lookup(self, w_obj, name): + from pypy.objspace.std.cpythonobject import W_CPythonObject + if not isinstance(w_obj, W_CPythonObject): + # usual case + w_type = self.type(w_obj) + return w_type.lookup(name) + else: + # hack + for cls in w_obj.cpyobj.__class__.__mro__: + if name in cls.__dict__: + return self.wrap(cls.__dict__[name]) + return None + + def unpacktuple(self, w_tuple): + import tupleobject + assert isinstance(w_tuple, tupleobject.W_TupleObject) + return w_tuple.wrappeditems + + # special visible multimethods delegate = DelegateMultiMethod() # delegators unwrap = MultiMethod('unwrap', 1, []) # returns an unwrapped object is_true = MultiMethod('nonzero', 1, []) # returns an unwrapped bool - is_data_descr = MultiMethod('is_data_descr', 1, []) # returns an unwrapped bool - - getdict = MultiMethod('getdict', 1, []) # get '.__dict__' attribute - next = MultiMethod('next', 1, []) # iterator interface - call = MultiMethod('call', 3, [], varargs=True, keywords=True) - getattribute = MultiMethod('getattr', 2, ['__getattribute__']) # XXX hack - usergetattr = MultiMethod('usergetattr', 2, ['__getattr__']) # XXX hack + issubtype = MultiMethod('issubtype', 2, []) - def getattr(self, w_obj, w_attr): - try: - return self.getattribute(w_obj, w_attr) - except OperationError, e: - if not e.match(self, self.w_AttributeError): - raise - result = self.getattr_try_harder(w_obj, w_attr) - if result is None: - raise - return result - - def getattr_try_harder(self, *args_w): - # this needs to be in another function so that the exception caught - # here doesn't prevent the bare 'raise' in self.getattr() to - # re-raise the previous OperationError with correct traceback. - try: - return self.usergetattr.perform_call(args_w) - except FailedToImplement: - return None + class MM: + "Container for multimethods." + #is_data_descr = MultiMethod('is_data_descr', 1, []) # returns an unwrapped bool + #getdict = MultiMethod('getdict', 1, []) # get '.__dict__' attribute + next = MultiMethod('next', 1, ['next']) # iterator interface + call = MultiMethod('call', 1, ['__call__'], varargs=True, keywords=True) + #getattribute = MultiMethod('getattr', 2, ['__getattribute__']) # XXX hack def is_(self, w_one, w_two): # XXX a bit of hacking to gain more speed @@ -297,8 +293,9 @@ # add all regular multimethods to StdObjSpace for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if not hasattr(StdObjSpace,_name): - setattr(StdObjSpace, _name, MultiMethod(_symbol, _arity, _specialnames)) + if (not hasattr(StdObjSpace.MM, _name) and # XXX! + not isinstance(getattr(StdObjSpace, _name, None), MultiMethod)): + setattr(StdObjSpace.MM, _name, MultiMethod(_symbol, _arity, _specialnames)) # import the common base W_ObjectObject as well as Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py Fri Jun 4 16:16:45 2004 @@ -14,7 +14,7 @@ for registration. """ from pypy.objspace.std.objspace import StdObjSpace, W_ANY, W_Object - namespaces = [StdObjSpace] + namespaces = [StdObjSpace.MM, StdObjSpace] if alt_ns: namespaces.insert(0, alt_ns) @@ -53,19 +53,23 @@ def hack_func_by_name(funcname, namespaces): for ns in namespaces: - if hasattr(ns, funcname): - return getattr(ns, funcname) - import typetype + if isinstance(ns, dict): + if funcname in ns: + return ns[funcname] + else: + if hasattr(ns, funcname): + return getattr(ns, funcname) + #import typetype + #try: + # return getattr(typetype.W_TypeType, funcname) + #except AttributeError: + # pass # catches not only the getattr() but the typetype.W_TypeType + # # in case it is not fully imported yet :-(((( + from pypy.objspace.std import objecttype try: - return getattr(typetype.W_TypeType, funcname) + return getattr(objecttype, funcname) except AttributeError: - pass # catches not only the getattr() but the typetype.W_TypeType - # in case it is not fully imported yet :-(((( - import objecttype - try: - return getattr(objecttype.W_ObjectType, funcname) - except AttributeError: - pass # same comment + pass raise NameError, ("trying hard but not finding a multimethod named %s" % funcname) @@ -109,10 +113,10 @@ from pypy.objspace.std.objspace import StdObjSpace, W_ANY originaltable = {} for op in OPERATORS: - originaltable[op] = getattr(StdObjSpace, op).dispatch_table.copy() + originaltable[op] = getattr(StdObjSpace.MM, op).dispatch_table.copy() for op1, op2, correspondance in OP_CORRESPONDANCES: - mirrorfunc = getattr(StdObjSpace, op2) + mirrorfunc = getattr(StdObjSpace.MM, op2) for types, functions in originaltable[op1].iteritems(): t1, t2 = types if t1 is t2: Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py Fri Jun 4 16:16:45 2004 @@ -6,11 +6,10 @@ """ from pypy.objspace.std.objspace import * -from slicetype import W_SliceType class W_SliceObject(W_Object): - statictype = W_SliceType + from pypy.objspace.std.slicetype import slice_typedef as typedef def __init__(w_self, space, w_start, w_stop, w_step): W_Object.__init__(w_self, space) @@ -21,7 +20,8 @@ registerimplementation(W_SliceObject) -def getattribute__Slice_ANY(space, w_slice, w_attr): +def getattr__Slice_ANY(space, w_slice, w_attr): + # XXX later if space.is_true(space.eq(w_attr, space.wrap('start'))): if w_slice.w_start is None: return space.w_None Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py Fri Jun 4 16:16:45 2004 @@ -1,40 +1,8 @@ -from pypy.objspace.std.objspace import * -from pypy.interpreter import gateway -from typeobject import W_TypeObject - - -class W_SliceType(W_TypeObject): - - typename = 'slice' - - slice_indices = MultiMethod('indices', 2) - - -registerimplementation(W_SliceType) - - -def type_new__SliceType_SliceType(space, w_basetype, w_slicetype, w_args, w_kwds): - if space.is_true(w_kwds): - raise OperationError(space.w_TypeError, - space.wrap("no keyword arguments expected")) - args = space.unpackiterable(w_args) - start = space.w_None - stop = space.w_None - step = space.w_None - if len(args) == 1: - stop, = args - elif len(args) == 2: - start, stop = args - elif len(args) == 3: - start, stop, step = args - elif len(args) > 3: - raise OperationError(space.w_TypeError, - space.wrap("slice() takes at most 3 arguments")) - else: - raise OperationError(space.w_TypeError, - space.wrap("slice() takes at least 1 argument")) - return space.newslice(start, stop, step), True +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef +from pypy.objspace.std.register_all import register_all +slice_indices = MultiMethod('indices', 2) # default application-level implementations for some operations @@ -108,5 +76,31 @@ return (space.unwrap(w_1), space.unwrap(w_2), space.unwrap(w_3), space.unwrap(w_4)) +register_all(vars(), globals()) + +# ____________________________________________________________ + +def descr__new__(space, w_slicetype, *args_w): + w_start = space.w_None + w_stop = space.w_None + w_step = space.w_None + if len(args_w) == 1: + w_stop, = args_w + elif len(args_w) == 2: + w_start, w_stop = args_w + elif len(args_w) == 3: + w_start, w_stop, w_step = args_w + elif len(args) > 3: + raise OperationError(space.w_TypeError, + space.wrap("slice() takes at most 3 arguments")) + else: + raise OperationError(space.w_TypeError, + space.wrap("slice() takes at least 1 argument")) + return space.newslice(w_start, w_stop, w_step) + +# ____________________________________________________________ -register_all(vars(), W_SliceType) +slice_typedef = StdTypeDef("slice", [object_typedef], + __new__ = newmethod(descr__new__), + ) +slice_typedef.registermethods(globals()) Added: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- (empty file) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Fri Jun 4 16:16:45 2004 @@ -0,0 +1,180 @@ +from pypy.interpreter import eval, function, gateway +from pypy.interpreter.typedef import TypeDef, GetSetProperty +from pypy.interpreter.typedef import attrproperty, attrproperty_w +from pypy.objspace.std.multimethod import MultiMethod + +__all__ = ['StdTypeDef', 'newmethod', 'gateway', + 'GetSetProperty', 'attrproperty', 'attrproperty_w', + 'MultiMethod'] + + +class StdTypeDef(TypeDef): + + def __init__(self, name, bases, **rawdict): + TypeDef.__init__(self, name, **rawdict) + self.bases = bases + self.local_multimethods = [] + + def registermethods(self, namespace): + self.local_multimethods += hack_out_multimethods(namespace) + + def mro(self, space): + assert len(self.bases) <= 1 + if self.bases: + return [self] + self.bases[0].mro() + else: + return [self] + +def newmethod(descr_new): + # XXX make the result a staticmethod + return gateway.interp2app(descr_new) + +# ____________________________________________________________ +# +# All the code below fishes from the multimethod registration tables +# the descriptors to put into the W_TypeObjects. +# + +def buildtypeobject(typedef, space): + # build a W_TypeObject from this StdTypeDef + from pypy.objspace.std.typeobject import W_TypeObject + + w = space.wrap + rawdict = typedef.rawdict.copy() + + if isinstance(typedef, StdTypeDef): + # get all the sliced multimethods + multimethods = slicemultimethods(space.__class__, typedef) + for name, code in multimethods.items(): + #print typedef.name, ':', name + fn = function.Function(space, code, defs_w=code.getdefaults(space)) + assert name not in rawdict, 'name clash: %s in %s_typedef' % ( + name, typedef.name) + rawdict[name] = fn + bases_w = [space.gettypeobject(basedef) for basedef in typedef.bases] + else: + from pypy.objspace.std.objecttype import object_typedef + bases_w = [space.gettypeobject(object_typedef)] + + # wrap everything + dict_w = {} + for descrname, descrvalue in rawdict.items(): + dict_w[descrname] = w(descrvalue) + + return W_TypeObject(space, typedef.name, bases_w, dict_w) + +def hack_out_multimethods(ns): + result = [] + for value in ns.itervalues(): + if isinstance(value, MultiMethod): + result.append(value) + return result + +def slicemultimethods(spaceclass, typeclass): + result = {} + # import and slice all multimethods of the space.MM container + for multimethod in (hack_out_multimethods(spaceclass.MM.__dict__) + + typeclass.local_multimethods): + for i in range(len(multimethod.specialnames)): + # each MultimethodCode embeds a multimethod + name = multimethod.specialnames[i] + if name in result: + # conflict between e.g. __lt__ and + # __lt__-as-reversed-version-of-__gt__ + code = result[name] + if code.bound_position < i: + continue + mmframeclass = multimethod.extras.get('mmframeclass') + if mmframeclass is None: + if len(multimethod.specialnames) > 1: + mmframeclass = SpecialMmFrame + else: + mmframeclass = MmFrame + code = MultimethodCode(multimethod, mmframeclass, typeclass, i) + result[name] = code + # add some more multimethods with a special interface + code = MultimethodCode(spaceclass.MM.next, MmFrame, typeclass) + result['next'] = code + code = MultimethodCode(spaceclass.is_true, NonZeroMmFrame, typeclass) + result['__nonzero__'] = code + # remove the empty slices + for name, code in result.items(): + if code.slice().is_empty(): + del result[name] + return result + +class MultimethodCode(eval.Code): + """A code object that invokes a multimethod.""" + + def __init__(self, multimethod, framecls, typeclass, bound_position=0): + eval.Code.__init__(self, multimethod.operatorsymbol) + self.basemultimethod = multimethod + self.typeclass = typeclass + self.bound_position = bound_position + self.framecls = framecls + argnames = ['x%d'%(i+1) for i in range(multimethod.arity)] + argnames.insert(0, argnames.pop(self.bound_position)) + varargname = kwargname = None + if multimethod.extras.get('varargs', False): + varargname = 'args' + if multimethod.extras.get('keywords', False): + kwargname = 'keywords' + self.sig = argnames, varargname, kwargname + + def signature(self): + return self.sig + + def getdefaults(self, space): + return [space.wrap(x) + for x in self.basemultimethod.extras.get('defaults', ())] + + def slice(self): + return self.basemultimethod.slice(self.typeclass, self.bound_position) + + def create_frame(self, space, w_globals, closure=None): + return self.framecls(space, self) + +class MmFrame(eval.Frame): + def run(self): + "Call the multimethod, raising a TypeError if not implemented." + mm = self.code.slice().get(self.space) + args = self.fastlocals_w + #print mm.multimethod.operatorsymbol, args + #print + w_result = mm(*args) + # we accept a real None from operations with no return value + if w_result is None: + w_result = self.space.w_None + return w_result + +class SpecialMmFrame(eval.Frame): + def run(self): + "Call the multimethods, possibly returning a NotImplemented." + mm = self.code.slice().get(self.space) + args = self.fastlocals_w + try: + return mm.perform_call(args) + except FailedToImplement, e: + if e.args: + raise OperationError(*e.args) + else: + return self.space.w_NotImplemented + +##class NextMmFrame(eval.Frame): +## def run(self): +## "Call the next() multimethod." +## mm = self.code.slice().get(self.space) +## args = self.fastlocals_w +## try: +## return mm(*args) +## except NoValue: +## raise OperationError(self.space.w_StopIteration, +## self.space.w_None) + +class NonZeroMmFrame(eval.Frame): + def run(self): + "Call the is_true() multimethods." + mm = self.code.slice().get(self.space) + args = self.fastlocals_w + result = mm(*args) + return self.space.newbool(result) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py Fri Jun 4 16:16:45 2004 @@ -73,10 +73,9 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from stringtype import W_StringType from intobject import W_IntObject from sliceobject import W_SliceObject -import slicetype +#import slicetype from listobject import W_ListObject from noneobject import W_NoneObject from tupleobject import W_TupleObject @@ -86,7 +85,7 @@ class W_StringObject(W_Object): - statictype = W_StringType + from stringtype import str_typedef as typedef def __init__(w_self, space, str): W_Object.__init__(w_self, space) @@ -1005,7 +1004,6 @@ mod__String_ANY = gateway.app2interp(app_mod__String_ANY) -# register all methods -register_all(vars(), W_StringType) - - +# register all methods +from pypy.objspace.std import stringtype +register_all(vars(), stringtype) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py Fri Jun 4 16:16:45 2004 @@ -1,58 +1,47 @@ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef - -class W_StringType(W_TypeObject): - - typename = 'str' - - str_join = MultiMethod('join', 2) - str_split = MultiMethod('split', 3, defaults=(None,-1)) - str_isdigit = MultiMethod('isdigit', 1) - str_isalpha = MultiMethod('isalpha', 1) - str_isspace = MultiMethod('isspace', 1) - str_isupper = MultiMethod('isupper', 1) - str_islower = MultiMethod('islower', 1) - str_istitle = MultiMethod('istitle', 1) - str_isalnum = MultiMethod('isalnum', 1) - str_ljust = MultiMethod('ljust', 2) - str_rjust = MultiMethod('rjust', 2) - str_upper = MultiMethod('upper', 1) - str_lower = MultiMethod('lower', 1) - str_swapcase = MultiMethod('swapcase', 1) - str_capitalize = MultiMethod('capitalize', 1) - str_title = MultiMethod('title', 1) - str_find = MultiMethod('find', 4, defaults=(None, None)) - str_rfind = MultiMethod('rfind', 4, defaults=(None, None)) - str_index = MultiMethod('index', 4, defaults=(None, None)) - str_rindex = MultiMethod('rindex', 4, defaults=(None, None)) - str_replace = MultiMethod('replace', 4, defaults=(-1,)) - str_zfill = MultiMethod('zfill', 2) - str_strip = MultiMethod('strip', 2, defaults=('', ' ')) - str_rstrip = MultiMethod('rstrip', 2, defaults=('', ' ')) - str_lstrip = MultiMethod('lstrip', 2, defaults=('', ' ')) - str_center = MultiMethod('center', 2, ) - str_count = MultiMethod('count', 4, defaults=(None,None)) - str_endswith = MultiMethod('endswith', 2) #[optional arguments not supported now] - str_expandtabs = MultiMethod('expandtabs', 2, defaults=(8,)) - 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 - -registerimplementation(W_StringType) - - -def type_new__StringType_StringType(space, w_basetype, w_stringtype, w_args, w_kwds): - if space.is_true(w_kwds): - raise OperationError(space.w_TypeError, - space.wrap("no keyword arguments expected")) - args = space.unpackiterable(w_args) - if len(args) == 0: - return space.newstring([]), True - elif len(args) == 1: - return space.str(args[0]), True - else: - raise OperationError(space.w_TypeError, - space.wrap("str() takes at most 1 argument")) - -register_all(vars()) +str_join = MultiMethod('join', 2) +str_split = MultiMethod('split', 3, defaults=(None,-1)) +str_isdigit = MultiMethod('isdigit', 1) +str_isalpha = MultiMethod('isalpha', 1) +str_isspace = MultiMethod('isspace', 1) +str_isupper = MultiMethod('isupper', 1) +str_islower = MultiMethod('islower', 1) +str_istitle = MultiMethod('istitle', 1) +str_isalnum = MultiMethod('isalnum', 1) +str_ljust = MultiMethod('ljust', 2) +str_rjust = MultiMethod('rjust', 2) +str_upper = MultiMethod('upper', 1) +str_lower = MultiMethod('lower', 1) +str_swapcase = MultiMethod('swapcase', 1) +str_capitalize = MultiMethod('capitalize', 1) +str_title = MultiMethod('title', 1) +str_find = MultiMethod('find', 4, defaults=(None, None)) +str_rfind = MultiMethod('rfind', 4, defaults=(None, None)) +str_index = MultiMethod('index', 4, defaults=(None, None)) +str_rindex = MultiMethod('rindex', 4, defaults=(None, None)) +str_replace = MultiMethod('replace', 4, defaults=(-1,)) +str_zfill = MultiMethod('zfill', 2) +str_strip = MultiMethod('strip', 2, defaults=('', ' ')) +str_rstrip = MultiMethod('rstrip', 2, defaults=('', ' ')) +str_lstrip = MultiMethod('lstrip', 2, defaults=('', ' ')) +str_center = MultiMethod('center', 2, ) +str_count = MultiMethod('count', 4, defaults=(None,None)) +str_endswith = MultiMethod('endswith', 2) #[optional arguments not supported now] +str_expandtabs = MultiMethod('expandtabs', 2, defaults=(8,)) +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 + +# ____________________________________________________________ + +def descr__new__(space, w_stringtype, w_obj=''): + return space.str(w_obj) + +# ____________________________________________________________ + +str_typedef = StdTypeDef("str", [object_typedef], + __new__ = newmethod(descr__new__), + ) +str_typedef.registermethods(globals()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py Fri Jun 4 16:16:45 2004 @@ -1,13 +1,12 @@ from pypy.objspace.std.objspace import * -from tupletype import W_TupleType from intobject import W_IntObject from sliceobject import W_SliceObject import slicetype class W_TupleObject(W_Object): - statictype = W_TupleType - + from pypy.objspace.std.tupletype import tuple_typedef as typedef + def __init__(w_self, space, wrappeditems): W_Object.__init__(w_self, space) w_self.wrappeditems = wrappeditems # a list of wrapped values Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py Fri Jun 4 16:16:45 2004 @@ -1,26 +1,13 @@ -from pypy.objspace.std.objspace import * -from typeobject import W_TypeObject +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef -class W_TupleType(W_TypeObject): +def descr__new__(space, w_tupletype, w_items=()): + tuple_w = space.unpackiterable(w_items) + return space.newtuple(tuple_w) - typename = 'tuple' +# ____________________________________________________________ -registerimplementation(W_TupleType) - - -def type_new__TupleType_TupleType(space, w_basetype, w_tupletype, w_args, w_kwds): - if space.is_true(w_kwds): - raise OperationError(space.w_TypeError, - space.wrap("no keyword arguments expected")) - args = space.unpackiterable(w_args) - if len(args) == 0: - tuple_w = [] - elif len(args) == 1: - tuple_w = space.unpackiterable(args[0]) - else: - raise OperationError(space.w_TypeError, - space.wrap("tuple() takes at most 1 argument")) - return space.newtuple(tuple_w), True - -register_all(vars()) +tuple_typedef = StdTypeDef("tuple", [object_typedef], + __new__ = newmethod(descr__new__), + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Fri Jun 4 16:16:45 2004 @@ -1,203 +1,185 @@ -from pypy.interpreter import eval, function from pypy.objspace.std.objspace import * -class W_TypeObject(W_AbstractTypeObject): - """This class is abstract. Subclasses are defined in 'xxxtype.py' files. - The instances of these subclasses are what the user sees as Python's - type objects. This class defines all general type-oriented behavior - like attribute lookup and method resolution order. Inheritance - relationships are implemented *only* with the getbases() methods of - W_TypeObject subclasses, *not* with interpreter-level inheritance between - W_Xxx classes *nor* with multimethod delegation.""" - - typename = None # to be overridden by subclasses or instances - #statictype = W_TypeType (hacked into place below) - staticbases = None # defaults to (W_ObjectType,) +class W_TypeObject(W_Object): + from pypy.objspace.std.typetype import type_typedef as typedef - def __init__(w_self, space): + def __init__(w_self, space, name, bases_w, dict_w): W_Object.__init__(w_self, space) - w_self.w_tpname = space.wrap(w_self.typename) - - def __repr__(self): - return '' % ( - self.__class__.__name__, - getattr(self, 'statictype', '') - ) - - def getbases(w_self): - parents = w_self.staticbases - if parents is None: - # Note: this code is duplicated in multimethod.py - import objecttype - parents = (objecttype.W_ObjectType,) - basetypes = [w_self.space.get_typeinstance(parent) for parent in parents] - return tuple(basetypes) + w_self.name = name + w_self.bases_w = bases_w + w_self.dict_w = dict_w def getmro(w_self): # XXX this is something that works not too bad right now - # XXX do the complete mro thing later + # XXX do the complete mro thing later (see mro.py) mro = [w_self] - for w_parent in w_self.getbases(): + for w_parent in w_self.bases_w: mro += w_parent.getmro() - return tuple(mro) + return mro - def lookup(w_self, w_key): + def lookup(w_self, key): # note that this doesn't call __get__ on the result at all # XXX this should probably also return the (parent) class in which # the attribute was found + space = w_self.space for w_class in w_self.getmro(): try: - return w_class.lookup_exactly_here(w_key) + return w_class.dict_w[key] except KeyError: pass - raise KeyError + return None - def lookup_exactly_here(w_self, w_key): - space = w_self.space - multimethods = getmultimethods(space.__class__, w_self.__class__) - key = space.unwrap(w_key) - if not isinstance(key, str): - raise OperationError(space.w_TypeError, - space.wrap('attribute name must be string')) - try: - code = multimethods[key] - except KeyError: - raise KeyError # pass on the KeyError - if code.slice().is_empty(): - raise KeyError - fn = function.Function(space, code, defs_w=code.getdefaults(space)) - return space.wrap(fn) - - -import typetype, objecttype -W_TypeObject.statictype = typetype.W_TypeType -registerimplementation(W_TypeObject) - - -def hack_out_multimethods(cls): - result = [] - for base in cls.__bases__: - result += hack_out_multimethods(base) - for value in cls.__dict__.itervalues(): - if isinstance(value, MultiMethod): - result.append(value) - return result - -AllSlicedMultimethods = {} - -def getmultimethods(spaceclass, typeclass): - try: - multimethods = AllSlicedMultimethods[spaceclass, typeclass] - except KeyError: - multimethods = AllSlicedMultimethods[spaceclass, typeclass] = {} - # import all multimethods of the type class and of the objspace - for multimethod in (hack_out_multimethods(typeclass) + - hack_out_multimethods(spaceclass)): - for i in range(len(multimethod.specialnames)): - # each MultimethodCode embeds a multimethod - name = multimethod.specialnames[i] - if name in multimethods: - # conflict between e.g. __lt__ and - # __lt__-as-reversed-version-of-__gt__ - code = multimethods[name] - if code.bound_position < i: - continue - mmframeclass = multimethod.extras.get('mmframeclass') - if mmframeclass is None: - if len(multimethod.specialnames) > 1: - mmframeclass = SpecialMmFrame - else: - mmframeclass = MmFrame - code = MultimethodCode(multimethod, mmframeclass, typeclass, i) - multimethods[name] = code - # add some more multimethods with a special interface - code = MultimethodCode(spaceclass.next, NextMmFrame, typeclass) - multimethods['next'] = code - code = MultimethodCode(spaceclass.is_true, NonZeroMmFrame, typeclass) - multimethods['__nonzero__'] = code - return multimethods +## def lookup_exactly_here(w_self, w_key): +## space = w_self.space +## multimethods = getmultimethods(space.__class__, w_self.__class__) +## key = space.unwrap(w_key) +## if not isinstance(key, str): +## raise OperationError(space.w_TypeError, +## space.wrap('attribute name must be string')) +## try: +## code = multimethods[key] +## except KeyError: +## raise KeyError # pass on the KeyError +## if code.slice().is_empty(): +## raise KeyError +## fn = function.Function(space, code, defs_w=code.getdefaults(space)) +## return space.wrap(fn) + + +##def hack_out_multimethods(cls): +## result = [] +## for base in cls.__bases__: +## result += hack_out_multimethods(base) +## for value in cls.__dict__.itervalues(): +## if isinstance(value, MultiMethod): +## result.append(value) +## return result + +##AllSlicedMultimethods = {} + +##def getmultimethods(spaceclass, typeclass): +## try: +## multimethods = AllSlicedMultimethods[spaceclass, typeclass] +## except KeyError: +## multimethods = AllSlicedMultimethods[spaceclass, typeclass] = {} +## # import all multimethods of the type class and of the objspace +## for multimethod in (hack_out_multimethods(typeclass) + +## hack_out_multimethods(spaceclass)): +## for i in range(len(multimethod.specialnames)): +## # each MultimethodCode embeds a multimethod +## name = multimethod.specialnames[i] +## if name in multimethods: +## # conflict between e.g. __lt__ and +## # __lt__-as-reversed-version-of-__gt__ +## code = multimethods[name] +## if code.bound_position < i: +## continue +## mmframeclass = multimethod.extras.get('mmframeclass') +## if mmframeclass is None: +## if len(multimethod.specialnames) > 1: +## mmframeclass = SpecialMmFrame +## else: +## mmframeclass = MmFrame +## code = MultimethodCode(multimethod, mmframeclass, typeclass, i) +## multimethods[name] = code +## # add some more multimethods with a special interface +## code = MultimethodCode(spaceclass.next, NextMmFrame, typeclass) +## multimethods['next'] = code +## code = MultimethodCode(spaceclass.is_true, NonZeroMmFrame, typeclass) +## multimethods['__nonzero__'] = code +## return multimethods -class MultimethodCode(eval.Code): - """A code object that invokes a multimethod.""" +##class MultimethodCode(eval.Code): +## """A code object that invokes a multimethod.""" - def __init__(self, multimethod, framecls, typeclass, bound_position=0): - eval.Code.__init__(self, multimethod.operatorsymbol) - self.basemultimethod = multimethod - self.typeclass = typeclass - self.bound_position = bound_position - self.framecls = framecls - argnames = ['x%d'%(i+1) for i in range(multimethod.arity)] - argnames.insert(0, argnames.pop(self.bound_position)) - varargname = kwargname = None - if multimethod.extras.get('varargs', False): - varargname = 'args' - if multimethod.extras.get('keywords', False): - kwargname = 'keywords' - self.sig = argnames, varargname, kwargname +## def __init__(self, multimethod, framecls, typeclass, bound_position=0): +## eval.Code.__init__(self, multimethod.operatorsymbol) +## self.basemultimethod = multimethod +## self.typeclass = typeclass +## self.bound_position = bound_position +## self.framecls = framecls +## argnames = ['x%d'%(i+1) for i in range(multimethod.arity)] +## argnames.insert(0, argnames.pop(self.bound_position)) +## varargname = kwargname = None +## if multimethod.extras.get('varargs', False): +## varargname = 'args' +## if multimethod.extras.get('keywords', False): +## kwargname = 'keywords' +## self.sig = argnames, varargname, kwargname - def signature(self): - return self.sig +## def signature(self): +## return self.sig - def getdefaults(self, space): - return [space.wrap(x) - for x in self.basemultimethod.extras.get('defaults', ())] - - def slice(self): - return self.basemultimethod.slice(self.typeclass, self.bound_position) - - def create_frame(self, space, w_globals, closure=None): - return self.framecls(space, self) - -class MmFrame(eval.Frame): - def run(self): - "Call the multimethod, raising a TypeError if not implemented." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w - w_result = mm(*args) - # we accept a real None from operations with no return value - if w_result is None: - w_result = self.space.w_None - return w_result - -class SpecialMmFrame(eval.Frame): - def run(self): - "Call the multimethods, possibly returning a NotImplemented." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w - try: - return mm.perform_call(args) - except FailedToImplement, e: - if e.args: - raise OperationError(*e.args) - else: - return self.space.w_NotImplemented - -class NextMmFrame(eval.Frame): - def run(self): - "Call the next() multimethod." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w - return mm(*args) - -class NonZeroMmFrame(eval.Frame): - def run(self): - "Call the is_true() multimethods." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w - result = mm(*args) - return self.space.newbool(result) - -# see also class NewMmFrame in typetype.py - - -def call__Type_ANY_ANY(space, w_type, w_args, w_kwds): - type_new = typetype.W_TypeType.type_new.get(space) - w_newobject, callinit = type_new(w_type, w_type, w_args, w_kwds) - if callinit: - import objecttype - object_init = objecttype.W_ObjectType.object_init.get(space) - object_init(w_newobject, w_args, w_kwds) +## def getdefaults(self, space): +## return [space.wrap(x) +## for x in self.basemultimethod.extras.get('defaults', ())] + +## def slice(self): +## return self.basemultimethod.slice(self.typeclass, self.bound_position) + +## def create_frame(self, space, w_globals, closure=None): +## return self.framecls(space, self) + +##class MmFrame(eval.Frame): +## def run(self): +## "Call the multimethod, raising a TypeError if not implemented." +## mm = self.code.slice().get(self.space) +## args = self.fastlocals_w +## w_result = mm(*args) +## # we accept a real None from operations with no return value +## if w_result is None: +## w_result = self.space.w_None +## return w_result + +##class SpecialMmFrame(eval.Frame): +## def run(self): +## "Call the multimethods, possibly returning a NotImplemented." +## mm = self.code.slice().get(self.space) +## args = self.fastlocals_w +## try: +## return mm.perform_call(args) +## except FailedToImplement, e: +## if e.args: +## raise OperationError(*e.args) +## else: +## return self.space.w_NotImplemented + +##class NextMmFrame(eval.Frame): +## def run(self): +## "Call the next() multimethod." +## mm = self.code.slice().get(self.space) +## args = self.fastlocals_w +## try: +## return mm(*args) +## except NoValue: +## raise OperationError(self.space.w_StopIteration, +## self.space.w_None) + +##class NonZeroMmFrame(eval.Frame): +## def run(self): +## "Call the is_true() multimethods." +## mm = self.code.slice().get(self.space) +## args = self.fastlocals_w +## result = mm(*args) +## return self.space.newbool(result) + + +def call__Type(space, w_type, w_args, w_kwds): + args_w = space.unpacktuple(w_args) + # special case for type(x) + if (space.is_true(space.is_(w_type, space.w_type)) and + len(args_w) == 1 and not space.is_true(w_kwds)): + return space.type(args_w[0]) + # invoke the __new__ of the type + w_descr = w_type.lookup('__new__') + w_extendedargs = space.newtuple([w_type] + args_w) + w_newobject = space.call(w_descr, w_extendedargs, w_kwds) + # maybe invoke the __init__ of the type + if space.is_true(space.isinstance(w_newobject, w_type)): + w_descr = space.lookup(w_newobject, '__init__') + if w_descr is not None: + space.get_and_call(w_descr, w_newobject, w_args, w_kwds) return w_newobject def issubtype__Type_Type(space, w_type1, w_type2): @@ -206,19 +188,23 @@ def repr__Type(space, w_obj): return space.wrap("" % w_obj.typename) # XXX remove 'pypy' -def getattribute__Type_ANY(space, w_type, w_attr): - # XXX mwh doubts this is the Right Way to do this... - if space.is_true(space.eq(w_attr, space.wrap('__name__'))): - return w_type.w_tpname - if space.is_true(space.eq(w_attr, space.wrap('__mro__'))): - return space.newtuple(list(w_type.getmro())) - if space.is_true(space.eq(w_attr, space.wrap('__bases__'))): - return space.newtuple(list(w_type.getbases())) - try: - desc = w_type.lookup(w_attr) - except KeyError: - raise FailedToImplement #OperationError(space.w_AttributeError,w_attr) - return space.get(desc, space.w_None, w_type) +def getattr__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): + return space.get(w_descr,w_type,space.type(w_type)) + w_value = w_type.lookup(name) + if w_value is not None: + # __get__(None, type): turns e.g. functions into unbound methods + return space.get(w_value, space.w_None, w_type) + if w_descr is not None: + return space.get(w_descr,w_type,space.type(w_type)) + raise OperationError(space.w_AttributeError,w_name) + +# XXX __setattr__ +# XXX __delattr__ +# XXX __hash__ ?? register_all(vars()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Fri Jun 4 16:16:45 2004 @@ -1,51 +1,39 @@ -from pypy.objspace.std.objspace import * -from pypy.objspace.std.register_all import register_all -from pypy.interpreter import eval -from typeobject import W_TypeObject - - -class NewMmFrame(eval.Frame): - def run(self): - "Call the __new__() method of typetype.py." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w - w_result, callinit = mm(*args) - return w_result - - -class W_TypeType(W_TypeObject): - """The single instance of this class is the object the user sees as - '__builtin__.type'.""" - - typename = 'type' - - # XXX this is worth tons of comments. - # the four arguments are (T, S, args, kw) for the expression - # T.__new__(S, *args, **kw). There is no (known?) way to get it as - # an unbound method, because 'type.__new__' means reading from the - # instance 'type' of the class 'type', as opposed to reading from - # the class 'type'. - # Attention, this internally returns a tuple (w_result, flag), - # where 'flag' specifies whether we would like __init__() to be called. - type_new = MultiMethod('__new__', 2, varargs=True, keywords=True, - mmframeclass=NewMmFrame) - -registerimplementation(W_TypeType) - -def type_new__TypeType_TypeType(space, w_basetype, w_typetype, w_args, w_kwds): - if space.is_true(w_kwds): - raise OperationError(space.w_TypeError, - space.wrap("no keyword arguments expected")) - args = space.unpackiterable(w_args) - if len(args) == 1: - return space.type(args[0]), False # don't call __init__() on that - elif len(args) == 3: - from usertype import W_UserType - w_name, w_bases, w_dict = args - w_usertype = W_UserType(space, w_name, w_bases, w_dict) - return w_usertype, True - else: - raise OperationError(space.w_TypeError, - space.wrap("type() takes 1 or 3 arguments")) +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef -register_all(vars()) + +def descr__new__(space, w_typetype, w_name, w_bases, w_dict): + # XXX staticmethod-ify w_dict['__new__'] + from pypy.objspace.std.typeobject import W_TypeObject + # XXX check types + name = space.unwrap(w_name) + assert isinstance(name, str) + bases_w = space.unpackiterable(w_bases) + dict_w = {} + dictkeys_w = space.unpackiterable(w_dict) + for w_key in dictkeys_w: + key = space.unwrap(w_key) + assert isinstance(key, str) + dict_w[key] = space.getitem(w_dict, w_key) + return W_TypeObject(space, name, bases_w, dict_w) + +def descr_get__mro__(space, w_type): + # XXX this should be inside typeobject.py + return space.newtuple(w_type.getmro()) + +def descr__dict__(space, w_type): + # XXX should return a + dictspec = [] + for key, w_value in w_type.dict_w.items(): + dictspec.append((space.wrap(key), w_value)) + return space.newdict(dictspec) + +# ____________________________________________________________ + +type_typedef = StdTypeDef("type", [object_typedef], + __new__ = newmethod(descr__new__), + __name__ = attrproperty('name'), + #__bases__ = XXX use newtuple + __dict__ = GetSetProperty(descr__dict__), + __mro__ = GetSetProperty(descr_get__mro__), + ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Fri Jun 4 16:16:45 2004 @@ -200,6 +200,9 @@ def is_(self, w_obj1, w_obj2): return self.unwrap(w_obj1) is self.unwrap(w_obj2) + def id(self, w_obj): + return id(self.unwrap(w_obj)) + def unpacktuple(self, w_tuple, expected_length=None): assert isinstance(w_tuple, tuple) if expected_length is not None and expected_length != len(w_tuple): @@ -250,7 +253,7 @@ is_true = operator.truth # 'is_true' is not called 'truth' because it returns a *non-wrapped* boolean - for _name in ('id', 'type', 'ord', 'round'): + for _name in ('type', 'ord', 'round'): _auto(_name, _name, locals()) def not_(self, w_obj): # default implementation From mwh at codespeak.net Fri Jun 4 16:20:19 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 16:20:19 +0200 (MEST) Subject: [pypy-svn] r4910 - pypy/branch/src-newobjectmodel/pypy/tool/tb_server Message-ID: <20040604142019.8D2B05BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 16:20:18 2004 New Revision: 4910 Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Log: add 'FileSystemView', add links to files from tracebacks Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 16:20:18 2004 @@ -7,44 +7,58 @@ views = TBRequestHandler.views - -class TracebackView: - def __init__(self, tb): - self.name = 'traceback%d' % len(views) - views[self.name] = self - self.tb = tb - - def render(self, args): +class Renderer: + def render(self, args): + try: + inner = self.render_self(args) + except: + import sys, traceback + lines = traceback.format_exception(*sys.exc_info()) + inner = html.pre( + xml.escape(''.join( + ['Internal Rendering Error, traceback follows\n'] + lines))) + tag = html.html( html.head(), html.body( - self.render_tb(args) + inner ) ) return tag.to_unicode() + - def render_tb(self, args): - try: - return self.render_tb_really(args) - except: - import sys, traceback - lines = traceback.format_tb(sys.exc_info()[2]) - return html.pre( - xml.escape(''.join(['Internal Rendering Error, traceback follows\n'] + lines))) +class TracebackView(Renderer): + def __init__(self, tb): + self.name = 'traceback%d' % len(views) + views[self.name] = self + self.tb = tb - def render_tb_really(self, args): + def render_self(self, args): lines = html.pre() for tb in dyncode.listtb(self.tb): filename = tb.tb_frame.f_code.co_filename lineno = tb.tb_lineno name = tb.tb_frame.f_code.co_name lines.append(' File "%s", line %d, in %s\n'%( - html.a(filename, href=filename).to_unicode().encode('utf-8'), + html.a(filename, href='/file' + filename + '#' + str(lineno)).to_unicode().encode('utf-8'), lineno, name)) lines.append(dyncode.getline(filename, lineno)) return lines - - - - + + +def ln(lineno): + return html.a(name=str(lineno)) + +class FileSystemView(Renderer): + def render_self(self, args): + fname = '/' + '/'.join(args) + lines = html.pre() + i = 1 + for line in open(fname): + lines.append(ln(i)) + lines.append(xml.escape(line)[:-1]) + i += 1 + return lines + +views['file'] = FileSystemView() From mwh at codespeak.net Fri Jun 4 16:25:38 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 16:25:38 +0200 (MEST) Subject: [pypy-svn] r4911 - in pypy/branch/src-newobjectmodel/pypy: interpreter tool/tb_server Message-ID: <20040604142538.47E155BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 16:25:37 2004 New Revision: 4911 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/py.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Log: make http server less obnoxious Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/py.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/py.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/py.py Fri Jun 4 16:25:37 2004 @@ -34,7 +34,6 @@ def main_(argv=None): from pypy.tool import tb_server args = option.process_options(get_main_options(), Options, argv[1:]) - print 'options processed' try: space = option.objspace() go_interactive = Options.interactive @@ -64,7 +63,6 @@ con.interact(banner) except: sys.excepthook(*sys.exc_info()) - print 'waiting' tb_server.wait_until_interrupt() tb_server.stop() Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Fri Jun 4 16:25:37 2004 @@ -78,6 +78,7 @@ def wait_until_interrupt(): if server_thread is None: return + print "waiting" import signal try: signal.pause() From arigo at codespeak.net Fri Jun 4 16:33:04 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 4 Jun 2004 16:33:04 +0200 (MEST) Subject: [pypy-svn] r4912 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace Message-ID: <20040604143304.B63325BE07@thoth.codespeak.net> Author: arigo Date: Fri Jun 4 16:33:04 2004 New Revision: 4912 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: attrproperty fix. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Fri Jun 4 16:33:04 2004 @@ -35,13 +35,13 @@ def attrproperty(name): def fget(space, w_obj): - obj = space.unwrap(w_obj) + obj = space.unwrap_builtin(w_obj) return space.wrap(getattr(obj, name)) return GetSetProperty(fget) def attrproperty_w(name): def fget(space, w_obj): - obj = space.unwrap(w_obj) + obj = space.unwrap_builtin(w_obj) w_value = getattr(obj, name) if w_value is None: return space.w_None Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Fri Jun 4 16:33:04 2004 @@ -144,6 +144,8 @@ else: return w + unwrap_builtin = unwrap + def hackwrapperclass(self, typedef): try: return typedef.trivialwrapperclass @@ -191,12 +193,6 @@ typedef.trivialwrapperclass = cls return cls - def unwrap_builtin(self, w_obj): - if isinstance(w_obj, CPyWrapper): - return self.unwrap(w_obj) - else: - return None - def is_(self, w_obj1, w_obj2): return self.unwrap(w_obj1) is self.unwrap(w_obj2) From arigo at codespeak.net Fri Jun 4 16:33:32 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 4 Jun 2004 16:33:32 +0200 (MEST) Subject: [pypy-svn] r4913 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040604143332.03FEA5BE07@thoth.codespeak.net> Author: arigo Date: Fri Jun 4 16:33:32 2004 New Revision: 4913 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Log: Classes get object as a default base. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Fri Jun 4 16:33:32 2004 @@ -82,7 +82,7 @@ self.w_Exception = W_TypeObject( self, 'Exception', - [], + [self.w_object], {'__init__': w_init, '__str__': w_str}) done = {'Exception': self.w_Exception} @@ -269,6 +269,7 @@ unwrap = MultiMethod('unwrap', 1, []) # returns an unwrapped object is_true = MultiMethod('nonzero', 1, []) # returns an unwrapped bool issubtype = MultiMethod('issubtype', 2, []) + id = MultiMethod('id', 1, []) class MM: "Container for multimethods." @@ -293,9 +294,12 @@ # add all regular multimethods to StdObjSpace for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if (not hasattr(StdObjSpace.MM, _name) and # XXX! - not isinstance(getattr(StdObjSpace, _name, None), MultiMethod)): - setattr(StdObjSpace.MM, _name, MultiMethod(_symbol, _arity, _specialnames)) + if not hasattr(StdObjSpace.MM, _name): + if isinstance(getattr(StdObjSpace, _name, None), MultiMethod): + mm = getattr(StdObjSpace, _name) + else: + mm = MultiMethod(_symbol, _arity, _specialnames) + setattr(StdObjSpace.MM, _name, mm) # import the common base W_ObjectObject as well as Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Fri Jun 4 16:33:32 2004 @@ -15,7 +15,7 @@ key = space.unwrap(w_key) assert isinstance(key, str) dict_w[key] = space.getitem(w_dict, w_key) - return W_TypeObject(space, name, bases_w, dict_w) + return W_TypeObject(space, name, bases_w or [space.w_object], dict_w) def descr_get__mro__(space, w_type): # XXX this should be inside typeobject.py From hpk at codespeak.net Fri Jun 4 16:46:21 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 16:46:21 +0200 (MEST) Subject: [pypy-svn] r4914 - pypy/branch/src-newobjectmodel/pypy/tool/tb_server Message-ID: <20040604144621.9F3585BE07@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 16:46:21 2004 New Revision: 4914 Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Log: some improvements on the file-view and anchoring ... Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 16:46:21 2004 @@ -52,11 +52,18 @@ class FileSystemView(Renderer): def render_self(self, args): fname = '/' + '/'.join(args) - lines = html.pre() + lines = html.table() i = 1 for line in open(fname): - lines.append(ln(i)) - lines.append(xml.escape(line)[:-1]) + row = html.tr( + html.td(html.a("%03d" % i, name=str(i)), + style='text-align: left;'), + html.td( + html.pre(xml.escape(line)[:-1]), + #style="white-space: pre; font-family: monospace;" + ), + ) + lines.append(row) i += 1 return lines Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Fri Jun 4 16:46:21 2004 @@ -86,6 +86,8 @@ stop() def publish_tb(tb): + if server_thread is None: + return from pypy.tool.tb_server.render import TracebackView x = TracebackView(tb) print "traceback is at http://localhost:%d/%s" % (server_port, x.name) From ale at codespeak.net Fri Jun 4 17:12:39 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 4 Jun 2004 17:12:39 +0200 (MEST) Subject: [pypy-svn] r4915 - pypy/trunk/src/pypy/translator/tool Message-ID: <20040604151239.EBC635BE07@thoth.codespeak.net> Author: ale Date: Fri Jun 4 17:12:39 2004 New Revision: 4915 Modified: pypy/trunk/src/pypy/translator/tool/make_dot.py Log: Change to enable binary file support for windows (works only for PNG files) Modified: pypy/trunk/src/pypy/translator/tool/make_dot.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/make_dot.py (original) +++ pypy/trunk/src/pypy/translator/tool/make_dot.py Fri Jun 4 17:12:39 2004 @@ -159,8 +159,10 @@ #print source dest.write(source) psdest = dest.new(ext=target) - out = cmdexec('dot -T%s %s' % (target, str(dest))) - psdest.write(out) + out = cmdexec('dot -T%s %s>%s' % (target, str(dest),str(psdest))) +## This is the old code, which doesnt work on binary files on windows +## out = cmdexec('dot -T%s %s' % (target, str(dest))) +## psdest.write(out) #print "wrote", psdest return psdest From mwh at codespeak.net Fri Jun 4 17:13:38 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 17:13:38 +0200 (MEST) Subject: [pypy-svn] r4916 - in pypy/branch/src-newobjectmodel/pypy: interpreter tool/tb_server Message-ID: <20040604151338.5A5345BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 17:13:37 2004 New Revision: 4916 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/error.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/__init__.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Log: print error messages as well as tracebacks! Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/error.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/error.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/error.py Fri Jun 4 17:13:37 2004 @@ -1,3 +1,4 @@ +from pypy.tool.tb_server import publish_exc import os, sys AUTO_DEBUG = os.getenv('PYPY_DEBUG') @@ -24,7 +25,7 @@ self.w_type = w_type self.w_value = w_value self.application_traceback = tb - self.debug_tbs = [] + self.debug_excs = [] def match(self, space, w_check_class): "Check if this application-level exception matches 'w_check_class'." @@ -52,7 +53,7 @@ """Records the current traceback inside the interpreter. This traceback is only useful to debug the interpreter, not the application.""" - self.debug_tbs.append(sys.exc_info()[2]) + self.debug_excs.append(sys.exc_info()) def print_application_traceback(self, space, file=None): "Dump a standard application-level traceback." @@ -90,13 +91,13 @@ """Dump a nice detailed interpreter- and application-level traceback, useful to debug the interpreter.""" if file is None: file = sys.stderr - for i in range(len(self.debug_tbs)-1, -1, -1): + for i in range(len(self.debug_excs)-1, -1, -1): import traceback interpr_file = LinePrefixer(file, '||') print >> interpr_file, "Traceback (interpreter-level):" - traceback.print_tb(self.debug_tbs[i], file=interpr_file) + traceback.print_tb(self.debug_excs[i][2], file=interpr_file) from pypy.tool import tb_server - tb_server.publish_tb(self.debug_tbs[0]) + tb_server.publish_exc(self.debug_excs[-1]) self.print_app_tb_only(file) if space is None: exc_typename = str(self.w_type) @@ -152,9 +153,11 @@ if hasattr(sys, 'excepthook'): # not implemented on PyPy def operr_excepthook(exctype, value, traceback): if issubclass(exctype, OperationError): - value.debug_tbs.append(traceback) + value.debug_excs.append((exctype, value, traceback)) value.print_detailed_traceback() else: old_excepthook(exctype, value, traceback) + publish_exc((exctype, value, traceback)) + old_excepthook = sys.excepthook sys.excepthook = operr_excepthook Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/__init__.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/__init__.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/__init__.py Fri Jun 4 17:13:37 2004 @@ -1 +1 @@ -from server import start, stop, publish_tb, wait_until_interrupt +from server import start, stop, publish_exc, wait_until_interrupt Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 17:13:37 2004 @@ -28,21 +28,23 @@ class TracebackView(Renderer): - def __init__(self, tb): + def __init__(self, exc): self.name = 'traceback%d' % len(views) views[self.name] = self - self.tb = tb + self.exc = exc def render_self(self, args): lines = html.pre() - for tb in dyncode.listtb(self.tb): + for tb in dyncode.listtb(self.exc[2]): filename = tb.tb_frame.f_code.co_filename lineno = tb.tb_lineno name = tb.tb_frame.f_code.co_name lines.append(' File "%s", line %d, in %s\n'%( html.a(filename, href='/file' + filename + '#' + str(lineno)).to_unicode().encode('utf-8'), lineno, name)) - lines.append(dyncode.getline(filename, lineno)) + lines.append(' '+dyncode.getline(filename, lineno).lstrip()) + lines.append(xml.escape( + ''.join(traceback.format_exception_only(self.exc[0], self.exc[1])))) return lines Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Fri Jun 4 17:13:37 2004 @@ -85,11 +85,11 @@ except KeyboardInterrupt: stop() -def publish_tb(tb): +def publish_exc(exc): if server_thread is None: return from pypy.tool.tb_server.render import TracebackView - x = TracebackView(tb) + x = TracebackView(exc) print "traceback is at http://localhost:%d/%s" % (server_port, x.name) if __name__ == "__main__": From ale at codespeak.net Fri Jun 4 17:15:00 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 4 Jun 2004 17:15:00 +0200 (MEST) Subject: [pypy-svn] r4917 - pypy/trunk/src/pypy/translator/test Message-ID: <20040604151500.4A9BB5BE07@thoth.codespeak.net> Author: ale Date: Fri Jun 4 17:14:59 2004 New Revision: 4917 Modified: pypy/trunk/src/pypy/translator/test/snippet.py Log: added information on types for input arguments to automate translation. reordered the functions so that the ones that dont currently work is at the end Modified: pypy/trunk/src/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/snippet.py Fri Jun 4 17:14:59 2004 @@ -19,6 +19,89 @@ But for now, none of the above applies. """ +function_info={ + 'append_five':{'arg_names': ['lst'],'arg_types':[list], + 'name': 'append_five'}, + 'branch_id': {'arg_names': ['cond', 'a', 'b'],'arg_types':[int,int,int], + 'name': 'branch_id'}, + 'break_continue': {'arg_names': ['x'],'arg_types':[int], + 'name': 'break_continue'}, + 'build_instance': {'arg_names': [],'arg_types':[], + 'name': 'build_instance'}, + 'builtinusage': {'arg_names': [],'arg_types':[], + 'name': 'builtinusage'}, + 'call_five': {'arg_names': [],'arg_types':[], + 'name': 'call_five'}, + 'choose_last': {'arg_names': [],'arg_types':[], + 'name': 'choose_last'}, + 'factorial': {'arg_names': ['n'],'arg_types':[int], + 'name': 'factorial'}, + 'factorial2': {'arg_names': ['n'],'arg_types':[int], + 'name': 'factorial2'}, + 'finallys': {'arg_names': ['lst'],'arg_types':[list], + 'name': 'finallys'}, + 'greet': {'arg_names': ['target'],'arg_types':[str], + 'name': 'greet'}, + 'half_of_n': {'arg_names': ['n'],'arg_types':[int], + 'name': 'half_of_n'}, + 'if_then_else': {'arg_names': ['cond', 'x', 'y'], + 'arg_types':[object,object,object], + 'name': 'if_then_else'}, + 'inheritance1': {'arg_names': [],'arg_types':[], + 'name': 'inheritance1'}, + 'inheritance2': {'arg_names': [],'arg_types':[], + 'name': 'inheritance2'}, + #'inheritance_nonrunnable': {'arg_names': [],'arg_types':[], + # 'name': 'inheritance_nonrunnable'}, + 'int_id': {'arg_names': ['x'],'arg_types':[int], + 'name': 'int_id'}, + 'is_perfect_number': {'arg_names': ['i'],'arg_types':[int], + 'name': 'is_perfect_number'}, + 'knownkeysdict': {'arg_names': ['b'],'arg_types':[object], + 'name': 'knownkeysdict'}, + 'merge_setattr': {'arg_names': ['x'],'arg_types':[object], + 'name': 'merge_setattr'}, + 'my_bool': {'arg_names': ['x'],'arg_types':[object], + 'name': 'my_bool'}, + 'my_gcd': {'arg_names': ['a', 'b'],'arg_types':[int,int], + 'name': 'my_gcd'}, + 'nested_whiles': {'arg_names': ['i', 'j'],'arg_types':[int,int], + 'name': 'nested_whiles'}, + 'poly_branch': {'arg_names': ['x'],'arg_types':[object], + 'name': 'poly_branch'}, + 'poor_man_range': {'arg_names': ['i'],'arg_types':[int], + 'name': 'poor_man_range'}, + 'poor_man_rev_range': {'arg_names': ['i'],'arg_types':[int], + 'name': 'poor_man__rev_range'}, + 'powerset': {'arg_names': ['x'],'arg_types':[int], + 'name': 'powerset'}, + 'prime': {'arg_names': ['n'],'arg_types':[int], + 'name': 'prime'}, + 'reverse_3': {'arg_names': ['lst'],'arg_types':[list], + 'name': 'reverse_3'}, + 's_and': {'arg_names': ['x', 'y'],'arg_types':[object,object], + 'name': 's_and'}, + 'set_attr': {'arg_names': [],'arg_types':[], + 'name': 'set_attr'}, + 'sieve_of_eratosthenes': {'arg_names': [],'arg_types':[], + 'name': 'sieve_of_eratosthenes'}, + 'simple_func': {'arg_names': ['i'],'arg_types':[int], + 'name': 'simple_func'}, + 'simple_id': {'arg_names': ['x'],'arg_types':[object], + 'name': 'simple_id'}, + 'simple_method': {'arg_names': ['v'],'arg_types':[object], + 'name': 'simple_method'}, +# 'somebug1': {'arg_names': ['n'],'arg_types':[int], +# 'name': 'somebug1'}, + 'time_waster': {'arg_names': ['n'],'arg_types':[int], + 'name': 'time_waster'}, + 'two_plus_two': {'arg_names': [],'arg_types':[], + 'name': 'two_plus_two'}, + 'while_func': {'arg_names': ['i'],'arg_types':[int], + 'name': 'while_func'}, + 'yast': {'arg_names': ['lst'],'arg_types':[list], + 'name': 'yast'} + } def if_then_else(cond, x, y): if cond: @@ -122,12 +205,6 @@ else: return b -def attrs(): - def b(): pass - b.f = 4 - b.g = 5 - return b.f + b.g - def builtinusage(): return pow(2, 2) @@ -176,36 +253,6 @@ pass return choice -def powerset(setsize): - """Powerset - - This one is from a Philippine Pythonista Hangout, an modified - version of Andy Sy's code. - - list.append is modified to list concatenation, and powerset - is pre-allocated and stored, instead of printed. - - URL is: http://lists.free.net.ph/pipermail/python/2002-November/ - """ - set = range(setsize) - maxcardinality = pow(2, setsize) - bitmask = 0L - powerset = [None] * maxcardinality - ptr = 0 - while bitmask < maxcardinality: - bitpos = 1L - index = 0 - subset = [] - while bitpos < maxcardinality: - if bitpos & bitmask: - subset = subset + [set[index]] - index += 1 - bitpos <<= 1 - powerset[ptr] = subset - ptr += 1 - bitmask += 1 - return powerset - def poly_branch(x): if x: y = [1,2,3] @@ -275,6 +322,7 @@ def append_five(lst): lst += [5] + def call_five(): a = [] @@ -314,8 +362,6 @@ lst = [d, e] return d.stuff, e.stuff -def getstuff(x): - return x.stuff def inheritance2(): d = D() @@ -324,13 +370,6 @@ e.stuff = (3, "world") return getstuff(d), getstuff(e) -def inheritance_nonrunnable(): - d = D() - d.stuff = (-12, -12) - e = E() - e.stuff = (3, "world") - return C().stuff - class F: pass class G(F): @@ -362,12 +401,6 @@ def prime(n): return len([i for i in range(1,n+1) if n%i==0]) == 2 -def somebug1(n): - l = [] - v = l.append - while n: - l[7] = 5 - return v class Z: def my_method(self): @@ -377,3 +410,60 @@ z = Z() z.my_attribute = v return z.my_method() + +# --------------------(Currently) Non runnable Functions --------------------- + +def somebug1(n): + l = [] + v = l.append + while n: + l[7] = 5 + return v + +def inheritance_nonrunnable(): + d = D() + d.stuff = (-12, -12) + e = E() + e.stuff = (3, "world") + return C().stuff + +# --------------------(Currently) Non compillable Functions --------------------- + +def attrs(): + def b(): pass + b.f = 4 + b.g = 5 + return b.f + b.g + +def powerset(setsize): + """Powerset + + This one is from a Philippine Pythonista Hangout, an modified + version of Andy Sy's code. + + list.append is modified to list concatenation, and powerset + is pre-allocated and stored, instead of printed. + + URL is: http://lists.free.net.ph/pipermail/python/2002-November/ + """ + set = range(setsize) + maxcardinality = pow(2, setsize) + bitmask = 0L + powerset = [None] * maxcardinality + ptr = 0 + while bitmask < maxcardinality: + bitpos = 1L + index = 0 + subset = [] + while bitpos < maxcardinality: + if bitpos & bitmask: + subset = subset + [set[index]] + index += 1 + bitpos <<= 1 + powerset[ptr] = subset + ptr += 1 + bitmask += 1 + return powerset + +def getstuff(x): + return x.stuff From ale at codespeak.net Fri Jun 4 17:16:20 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 4 Jun 2004 17:16:20 +0200 (MEST) Subject: [pypy-svn] r4918 - pypy/trunk/src/pypy/translator/test Message-ID: <20040604151620.957F95BE07@thoth.codespeak.net> Author: ale Date: Fri Jun 4 17:16:20 2004 New Revision: 4918 Modified: pypy/trunk/src/pypy/translator/test/test_translator.py Log: added some tests. the function call_five doesnt work as inplace operators is not properly handled Modified: pypy/trunk/src/pypy/translator/test/test_translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_translator.py (original) +++ pypy/trunk/src/pypy/translator/test/test_translator.py Fri Jun 4 17:16:20 2004 @@ -9,30 +9,35 @@ def test_set_attr(self): t = Translator(snippet.set_attr) + t.simplify() t.annotate([]) set_attr = t.compile() self.assertEquals(set_attr(), 2) def test_inheritance2(self): t = Translator(snippet.inheritance2) + t.simplify() t.annotate([]) inheritance2 = t.compile() self.assertEquals(inheritance2(), ((-12, -12), (3, "world"))) def test_factorial2(self): t = Translator(snippet.factorial2) + t.simplify() t.annotate([int]) factorial2 = t.compile() self.assertEquals(factorial2(5), 120) def test_factorial(self): t = Translator(snippet.factorial) + t.simplify() t.annotate([int]) factorial = t.compile() self.assertEquals(factorial(5), 120) def test_simple_method(self): t = Translator(snippet.simple_method) + t.simplify() t.annotate([int]).simplify() simple_method = t.compile() self.assertEquals(simple_method(55), 55) @@ -45,5 +50,19 @@ sieve_of_eratosthenes = t.compile() self.assertEquals(sieve_of_eratosthenes(), 1028) + def test_nested_whiles(self): + t = Translator(snippet.nested_whiles) + t.simplify() + t.annotate([int,int]) + nested_whiles = t.compile() + self.assertEquals(nested_whiles(5,3), '!!!!!') + + def test_call_five(self): + t = Translator(snippet.call_five) + t.simplify() + t.annotate([]) + call_five = t.compile() + self.assertEquals(call_five(), [5]) + if __name__ == '__main__': testit.main() From mwh at codespeak.net Fri Jun 4 17:48:44 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 17:48:44 +0200 (MEST) Subject: [pypy-svn] r4920 - pypy/branch/src-newobjectmodel/pypy/tool/tb_server Message-ID: <20040604154844.8194F5BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 17:48:43 2004 New Revision: 4920 Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Log: support for parameters in the url we don't like it much yet Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 17:48:43 2004 @@ -4,13 +4,29 @@ from std.magic import dyncode import traceback +import cgi views = TBRequestHandler.views +class URL(object): + attrs='scm','netloc','path','params','query','fragment' + attrindex = dict(zip(attrs, range(len(attrs)))) + # XXX authentication part is not parsed + + def __init__(self, string='', **kw): + from urlparse import urlparse + for name,value in zip(self.attrs, urlparse(string, 'http')): + setattr(self, name, value) + self.__dict__.update(kw) + + class Renderer: - def render(self, args): + def render(self, path): + url = URL(path) + args = url.path.split('/')[2:] + query = cgi.parse_qs(url.query) try: - inner = self.render_self(args) + inner = self.render_self(args, query) except: import sys, traceback lines = traceback.format_exception(*sys.exc_info()) @@ -33,14 +49,15 @@ views[self.name] = self self.exc = exc - def render_self(self, args): + def render_self(self, args, query): lines = html.pre() for tb in dyncode.listtb(self.exc[2]): filename = tb.tb_frame.f_code.co_filename lineno = tb.tb_lineno name = tb.tb_frame.f_code.co_name + link = '/file' + filename + '?line=' + str(lineno) + '#' + str(lineno) lines.append(' File "%s", line %d, in %s\n'%( - html.a(filename, href='/file' + filename + '#' + str(lineno)).to_unicode().encode('utf-8'), + html.a(filename, href=link).to_unicode().encode('utf-8'), lineno, name)) lines.append(' '+dyncode.getline(filename, lineno).lstrip()) lines.append(xml.escape( @@ -52,17 +69,22 @@ return html.a(name=str(lineno)) class FileSystemView(Renderer): - def render_self(self, args): + def render_self(self, args, query): fname = '/' + '/'.join(args) lines = html.table() i = 1 + print query + hilite = int(query.get('line', [-1])[0]) for line in open(fname): + if i == hilite: + kws = {'style': 'font-weight: bold;'} + else: + kws = {} row = html.tr( - html.td(html.a("%03d" % i, name=str(i)), - style='text-align: left;'), + html.td(html.a("%03d" % i, name=str(i))), html.td( - html.pre(xml.escape(line)[:-1]), - #style="white-space: pre; font-family: monospace;" + html.pre(xml.escape(line)[:-1], + **kws), ), ) lines.append(row) Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/server.py Fri Jun 4 17:48:43 2004 @@ -13,13 +13,12 @@ global server_thread server_thread = None raise SystemExit - parts = [x for x in self.path.split('/') if x] + i = self.path.find('/', 1) + parts = self.path[1:].split('/', 1) if not parts: - tb_name = 'traceback' - args = [] + tp_name = 'traceback' else: tb_name = parts[0] - args = parts[1:] if not self.views.has_key(tb_name): self.send_response(404) self.send_header("Content-Type", "text/plain") @@ -27,7 +26,7 @@ self.wfile.write('traceback named %r not found' % tb_name) else: tbview = self.views[tb_name] - s = tbview.render(args) + s = tbview.render(self.path) self.send_response(200) self.send_header("Content-Type", "text/html; charset=utf-8") self.end_headers() From lac at codespeak.net Fri Jun 4 18:02:57 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Fri, 4 Jun 2004 18:02:57 +0200 (MEST) Subject: [pypy-svn] r4921 - pypy/trunk/src/pypy/tool Message-ID: <20040604160257.7D8D95BE07@thoth.codespeak.net> Author: lac Date: Fri Jun 4 18:02:56 2004 New Revision: 4921 Added: pypy/trunk/src/pypy/tool/bltinchecker.py Log: About time this got checked in .... at any rate it goes along and checks cpython builtin functions and types and makes a very crude printout of what is found and missing. Just checking in the verison that works now, I am still not quite satisfied ... Added: pypy/trunk/src/pypy/tool/bltinchecker.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/tool/bltinchecker.py Fri Jun 4 18:02:56 2004 @@ -0,0 +1,80 @@ +#python imports +try: + import readline + import rlcompleter + have_readline = True + +except: + have_readline = False + +import __builtin__ as cpy_builtin + +#pypy imports +import autopath +from pypy.objspace.std import Space +from pypy.interpreter.baseobjspace import OperationError + +def found_missing(name, attrs, w_obj, space): + #we cannot do a dir on a pypy wrapped object + found_attrs = [] + missing_attrs = [] + + for a in attrs: + try: + try: + w_name = space.wrap(a) + t = space.getattr(w_obj, w_name) + found_attrs.append(a) + except OperationError: #over-broad? + missing_attrs.append(a) + + except: #something horrible happened + print 'In builtin: ', name, 'Blew Up Trying to get attr: ', repr(a) + missing_attrs.append(a) + + return found_attrs, missing_attrs + +def check_for_attrs(name, space): + try: + cpy_attrs = dir(getattr(cpy_builtin, name)) + except AttributeError: + print "AttributeError: CPython module __builtin__ has no attribute '%s'" % name + return [], [] + + try: + w_obj = space.getitem(space.w_builtins, space.wrap(name)) + except OperationError: + print "AttributeError: PyPy space %s builtins has no attribute '%s'" % (space, name) + return [], cpy_attrs + + return found_missing(name, cpy_attrs, w_obj, space) + + +def print_report(names, space): + + for n in names: + found, missing = check_for_attrs(n, space) + print + print "For the Builtin Function or Type: '%s'" % n + print + print 'Found Attributes: \t', found + print + print 'Missing Attributes: \t', missing + print + print '-------------------------' + +if __name__ == '__main__': + + from pypy.tool import option + from pypy.tool import test + args = option.process_options(option.get_standard_options(), + option.Options) + + + # Create objspace... + objspace = option.objspace() + + #names = dir(cpy_builtin) + names = ['abs', 'xxx', 'unicode', 'enumerate', 'int'] + + print_report(names, objspace) From mwh at codespeak.net Fri Jun 4 18:20:12 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 18:20:12 +0200 (MEST) Subject: [pypy-svn] r4922 - pypy/branch/src-newobjectmodel/pypy/tool/tb_server Message-ID: <20040604162012.DEB215BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 18:20:12 2004 New Revision: 4922 Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Log: less grotty options support Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 18:20:12 2004 @@ -5,6 +5,7 @@ import traceback import cgi +import urllib views = TBRequestHandler.views @@ -18,15 +19,22 @@ for name,value in zip(self.attrs, urlparse(string, 'http')): setattr(self, name, value) self.__dict__.update(kw) + self.query = cgi.parse_qs(self.query) + def link_with_options(self, *kw): + nq = self.query.copy() + nq.update(kw) + query = urllib.urlencode(nq) + from urlparse import urlunparse + return urlunparse(self.scm, self.netloc, self.path, + self.params, query, self.fragment) class Renderer: def render(self, path): url = URL(path) args = url.path.split('/')[2:] - query = cgi.parse_qs(url.query) try: - inner = self.render_self(args, query) + inner = self.render_self(url, args) except: import sys, traceback lines = traceback.format_exception(*sys.exc_info()) @@ -49,32 +57,45 @@ views[self.name] = self self.exc = exc - def render_self(self, args, query): - lines = html.pre() + def render_self(self, url, args): + lines = html.div() + opts = {} + for k in url.query: + ent, opt = k.split(':') + val = int(url.query[k][0]) + opts.setdefault(ent, {})[opt] = val + + i = 0 for tb in dyncode.listtb(self.exc[2]): - filename = tb.tb_frame.f_code.co_filename - lineno = tb.tb_lineno - name = tb.tb_frame.f_code.co_name - link = '/file' + filename + '?line=' + str(lineno) + '#' + str(lineno) - lines.append(' File "%s", line %d, in %s\n'%( - html.a(filename, href=link).to_unicode().encode('utf-8'), - lineno, name)) - lines.append(' '+dyncode.getline(filename, lineno).lstrip()) - lines.append(xml.escape( - ''.join(traceback.format_exception_only(self.exc[0], self.exc[1])))) + lines.append(self.render_tb(url, tb, i, + **opts.get('entry' + str(i), {}))) + + lines.append(html.pre(xml.escape( + ''.join(traceback.format_exception_only(self.exc[0], self.exc[1]))))) return lines + def render_tb(self, url, tb, i, showlocals=0): + lines = html.pre() + filename = tb.tb_frame.f_code.co_filename + lineno = tb.tb_lineno + name = tb.tb_frame.f_code.co_name + link = '/file' + filename + '?line=' + str(lineno) + '#' + str(lineno) + lines.append(' File "%s", line %d, in %s\n'%( + html.a(filename, href=link).to_unicode().encode('utf-8'), + lineno, name)) + lines.append(' '+dyncode.getline(filename, lineno).lstrip()) + return lines + def ln(lineno): return html.a(name=str(lineno)) class FileSystemView(Renderer): - def render_self(self, args, query): + def render_self(self, url, args): fname = '/' + '/'.join(args) lines = html.table() i = 1 - print query - hilite = int(query.get('line', [-1])[0]) + hilite = int(url.query.get('line', [-1])[0]) for line in open(fname): if i == hilite: kws = {'style': 'font-weight: bold;'} From ale at codespeak.net Fri Jun 4 18:46:04 2004 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 4 Jun 2004 18:46:04 +0200 (MEST) Subject: [pypy-svn] r4923 - in pypy/trunk/src/pypy/translator: . test Message-ID: <20040604164604.89DF35BE09@thoth.codespeak.net> Author: ale Date: Fri Jun 4 18:46:03 2004 New Revision: 4923 Added: pypy/trunk/src/pypy/translator/test/some_snippets_test.py Modified: pypy/trunk/src/pypy/translator/genpyrex.py pypy/trunk/src/pypy/translator/test/snippet.py Log: Genpyrex now handles exceptions and inpalce operators. A little reordering of snippets.py some_snippets_test.py compiles and run 38 of the 43 snippets correctly ( It should be folded into the other unittests) Modified: pypy/trunk/src/pypy/translator/genpyrex.py ============================================================================== --- pypy/trunk/src/pypy/translator/genpyrex.py (original) +++ pypy/trunk/src/pypy/translator/genpyrex.py Fri Jun 4 18:46:03 2004 @@ -20,14 +20,20 @@ def __call__(self): operator = self.gen.ops.get(self.op.opname, self.op.opname) - #print "operator, ", self.op.opname, operator, self.gen.ops - args = self.argnames if not (operator[0] >= "a" and operator[0] <= "z"): if len(args) == 1: return "%s = %s %s" % (self.resultname, operator) + args elif len(args) == 2: - return "%s = %s %s %s" % (self.resultname, args[0], operator, args[1]) + #Inplace operators + inp=['+=','-=','*=','/=','%=','^=','//=','div=','**=','<<=','>>=','!=','&='] + if operator in inp: + temp_str="temp_xx12=%s %s %s\n"%(args[0], operator[:-1], args[1]) + temp_str+="%s=temp_xx12\n"%args[0] + temp_str+="%s=temp_xx12"%self.resultname + return temp_str + else: + return "%s = %s %s %s" % (self.resultname, args[0], operator, args[1]) elif len(args) == 3 and operator == "**": #special case, have to handle it manually return "%s = pow(%s, %s, %s)" % (self.resultname,) + args else: @@ -181,7 +187,6 @@ def gen_graph(self): fun = self.functiongraph self.entrymap = mkentrymap(fun) - for block in self.entrymap : check_consistent_exits(block) currentlines = self.lines self.lines = [] self.indent += 1 @@ -200,10 +205,10 @@ except AttributeError: def function_object(): pass # XXX!!! # make the function visible from the outside under its original name - hackedargs = ', '.join([var.name for var in fun.getargs()]) - self.putline("def %s(%s):" % (fun.name, hackedargs)) + args = ', '.join([var.name for var in fun.getargs()]) + self.putline("def %s(%s):" % (fun.name, args)) self.indent += 1 - self.putline("return %s(%s)" % (self.getfunctionname(function_object), hackedargs)) + self.putline("return %s(%s)" % (self.getfunctionname(function_object), args)) self.indent -= 1 # go ahead with the mandled header and body of the function self.putline("def %s(%s):" % (self.getfunctionname(function_object), params)) @@ -270,7 +275,10 @@ def getclassname(self,cls): assert inspect.isclass(cls) - return '%s__%x' % (cls.__name__, id(cls))#self._hackname(cls) + name = cls.__name__ + if issubclass(cls,Exception): + return name + return '%s__%x' % (name, id(cls))#self._hackname(cls) def getfunctionname(self,func): assert inspect.isfunction(func) or inspect.ismethod(func) @@ -295,7 +303,7 @@ else: #fff=self._hackname(obj.value) fff=repr(obj.value) - if isinstance(obj.value, int): + if isinstance(obj.value,( int,long)): fff = repr(int(obj.value)) return fff else: @@ -397,10 +405,4 @@ return '\n'.join(self.lines) else: return '' - -def check_consistent_exits(block): - for exit in block.exits : - if len(exit.args) != len(exit.target.inputargs): - print "inconsistent block exit", block,exit,exit.args - print "more", exit.target,exit.target.inputargs - \ No newline at end of file + Modified: pypy/trunk/src/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/snippet.py Fri Jun 4 18:46:03 2004 @@ -61,6 +61,8 @@ 'name': 'knownkeysdict'}, 'merge_setattr': {'arg_names': ['x'],'arg_types':[object], 'name': 'merge_setattr'}, +# 'methodcall1': {'arg_names': ['cond'],'arg_types':[int], +# 'name': 'methodcall1'}, 'my_bool': {'arg_names': ['x'],'arg_types':[object], 'name': 'my_bool'}, 'my_gcd': {'arg_names': ['a', 'b'],'arg_types':[int,int], @@ -382,13 +384,6 @@ self.attr = 1 return E(), y -def methodcall1(cond): - if cond: - x = G() - else: - x = H() - return x.m(42) - def knownkeysdict(b): if b: d = {'a': 0} @@ -411,29 +406,6 @@ z.my_attribute = v return z.my_method() -# --------------------(Currently) Non runnable Functions --------------------- - -def somebug1(n): - l = [] - v = l.append - while n: - l[7] = 5 - return v - -def inheritance_nonrunnable(): - d = D() - d.stuff = (-12, -12) - e = E() - e.stuff = (3, "world") - return C().stuff - -# --------------------(Currently) Non compillable Functions --------------------- - -def attrs(): - def b(): pass - b.f = 4 - b.g = 5 - return b.f + b.g def powerset(setsize): """Powerset @@ -465,5 +437,37 @@ bitmask += 1 return powerset +# --------------------(Currently) Non runnable Functions --------------------- + +def somebug1(n): + l = [] + v = l.append + while n: + l[7] = 5 + return v + +def inheritance_nonrunnable(): + d = D() + d.stuff = (-12, -12) + e = E() + e.stuff = (3, "world") + return C().stuff + +# --------------------(Currently) Non compillable Functions --------------------- + +def attrs(): + def b(): pass + b.f = 4 + b.g = 5 + return b.f + b.g + def getstuff(x): return x.stuff + +def methodcall1(cond): + if cond: + x = G() + else: + x = H() + return x.m(42) + Added: pypy/trunk/src/pypy/translator/test/some_snippets_test.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/translator/test/some_snippets_test.py Fri Jun 4 18:46:03 2004 @@ -0,0 +1,100 @@ +""" + + Use all functions in snippet to test translation to pyrex + +""" +import autopath +import traceback +from pypy.tool import testit +from pypy.translator.translator import Translator + +from pypy.translator.test import snippet + +import inspect + +def compile(func,argtypes=[]): + + t = Translator(func) + t.simplify() + t.annotate(argtypes)#.simplify() + #t.view() + compiled_function = t.compile() + return compiled_function + +def compile_by_inspecting(module): + bad=0 + good=0 + funcs={} + all=module.__dict__.items() + for fu in all: + if isinstance(fu[1],type(compile)): + func_info={} + func_versions={} + try: + args=inspect.getargspec(fu[1]) + func_info['arg_names']=args[0] + func_info['name']=fu[0] + func_versions['python']=fu[1] + func_versions['pyrex']=compile(fu[1],[int]*len(args[0])) + except: + print fu[0] + bad+=1 + else: + good+=1 + funcs[fu[0]]=(func_info,func_versions) + print "Good: %i, Bad : %i, All: %i"%(good,bad,good+bad) + return funcs +def random_arg(arg): + if arg is int: + return 5 + if arg is list: + return [1,2,3,4,5,6] # [1,'ere','fggf']Doesn't work for snippet.yast + if arg is str: + return 'python' + else: + return 'object' + +def compile_by_function_info(module,info): + result={} + for func_name in info.keys(): + func=module.__dict__[func_name] + arg_types=info[func_name]['arg_types'] + try: + pyrex_func=compile(func,arg_types) + except: + traceback.print_exc() + print "Pyrex Compilation exception",func_name + args=tuple([random_arg(atype) for atype in arg_types]) + try: + pyresult=func(*args) + try: + pyrexresult=pyrex_func(*args) + except: + print "pyrex function not runnable",func_name + raise + except: + print "Python Function not runnable",func_name + print traceback.print_exc() + else: + result[func_name]=(pyresult, pyrexresult) #or (pyresult,pyrexresult) + + return result + +def get_funcs_from_module(module): + info=module.__dict__.get('function_info',None) + if info: + funcs=compile_by_function_info(module,info) + else: + funcs=compile_by_inspecting(module) + return funcs + +if __name__=='__main__': + funcs=get_funcs_from_module(snippet) + import pprint + print len(funcs) + for f in funcs.keys(): + assert funcs[f][0]==funcs[f][1],"%s!=%s"%(funcs[f][0],funcs[f][1]) + print f, + pprint.pprint(funcs[f]) + + From mwh at codespeak.net Fri Jun 4 18:53:55 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 18:53:55 +0200 (MEST) Subject: [pypy-svn] r4924 - pypy/branch/src-newobjectmodel/pypy/tool/tb_server Message-ID: <20040604165355.3808F5BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 18:53:54 2004 New Revision: 4924 Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Log: very preliminary show locals support Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 18:53:54 2004 @@ -21,13 +21,15 @@ self.__dict__.update(kw) self.query = cgi.parse_qs(self.query) - def link_with_options(self, *kw): - nq = self.query.copy() + def link_with_options(self, kw): + nq = {} + for k in self.query: + nq[k] = self.query[k][0] nq.update(kw) query = urllib.urlencode(nq) from urlparse import urlunparse - return urlunparse(self.scm, self.netloc, self.path, - self.params, query, self.fragment) + return urlunparse(('', self.netloc, self.path, + self.params, query, self.fragment)) class Renderer: def render(self, path): @@ -69,6 +71,7 @@ for tb in dyncode.listtb(self.exc[2]): lines.append(self.render_tb(url, tb, i, **opts.get('entry' + str(i), {}))) + i += 1 lines.append(html.pre(xml.escape( ''.join(traceback.format_exception_only(self.exc[0], self.exc[1]))))) @@ -83,7 +86,15 @@ lines.append(' File "%s", line %d, in %s\n'%( html.a(filename, href=link).to_unicode().encode('utf-8'), lineno, name)) - lines.append(' '+dyncode.getline(filename, lineno).lstrip()) + lines.append(html.a('locals', href=url.link_with_options( + {'entry%s:showlocals'%i:1-showlocals}))) + lines.append(' ' + + dyncode.getline(filename, lineno).lstrip()) + if showlocals: + for k, v in tb.tb_frame.f_locals.items(): + if k[0] == '_': + continue + lines.append(xml.escape('%s=%s\n'%(k, repr(v)[:50]))) return lines From arigo at codespeak.net Fri Jun 4 18:55:45 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 4 Jun 2004 18:55:45 +0200 (MEST) Subject: [pypy-svn] r4925 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace/std Message-ID: <20040604165545.5906D5BE09@thoth.codespeak.net> Author: arigo Date: Fri Jun 4 18:55:43 2004 New Revision: 4925 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/debug.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Log: Fixes fixes fixes. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/debug.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/debug.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/debug.py Fri Jun 4 18:55:43 2004 @@ -5,7 +5,7 @@ import pdb, sys def fire(operationerr): - if not operationerr.debug_tbs: + if not operationerr.debug_excs: return - tb = operationerr.debug_tbs[-1] + exc, val, tb = operationerr.debug_excs[-1] pdb.post_mortem(tb) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Fri Jun 4 18:55:43 2004 @@ -27,10 +27,29 @@ self.doc = doc def descr_property_get(space, w_property, w_obj, w_ignored): - return space.unwrap(w_property).fget(space, w_obj) + if w_obj == space.w_None: + return w_property + else: + return space.unwrap(w_property).fget(space, w_obj) + + def descr_property_set(space, w_property, w_obj, w_value): + fset = space.unwrap(w_property).fset + if fset is None: + complains + else: + do_it + + def descr_property_del(space, w_property, w_obj): + fset = space.unwrap(w_property).fset + if fset is None: + complains + else: + do_it typedef = TypeDef("GetSetProperty", __get__ = interp2app(descr_property_get), + __set__ = interp2app(descr_property_set), + __delete__ = interp2app(descr_property_del), ) def attrproperty(name): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/dicttype.py Fri Jun 4 18:55:43 2004 @@ -96,7 +96,8 @@ def descr__new__(space, w_dicttype, *args_w, **kwds_w): from pypy.objspace.std.dictobject import W_DictObject - return W_DictObject(space, []) + w_obj = W_DictObject(space, []) + return space.w_dict.check_user_subclass(w_dicttype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py Fri Jun 4 18:55:43 2004 @@ -4,12 +4,13 @@ def descr__new__(space, w_floattype, w_value=0): if space.is_true(space.isinstance(w_value, space.w_str)): try: - return space.newfloat(float(space.unwrap(w_value))) + w_obj = space.newfloat(float(space.unwrap(w_value))) except ValueError, e: raise OperationError(space.w_ValueError, space.wrap(str(e))) else: - return space.float(w_value) + w_obj = space.float(w_value) + return space.w_float.check_user_subclass(w_floattype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py Fri Jun 4 18:55:43 2004 @@ -5,7 +5,7 @@ def descr__new__(space, w_inttype, w_value=0, w_base=None): from intobject import W_IntObject if w_base == space.w_None: - return space.int(w_value) + w_obj = space.int(w_value) else: # XXX write the logic for int("str", base) s = space.unwrap(w_value) @@ -21,7 +21,8 @@ except OverflowError, e: raise OperationError(space.w_OverflowError, space.wrap(str(e))) - return W_IntObject(value) + w_obj = W_IntObject(value) + return space.w_int.check_user_subclass(w_inttype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/listtype.py Fri Jun 4 18:55:43 2004 @@ -15,7 +15,8 @@ # ____________________________________________________________ def descr__new__(space, w_listtype, *args_w, **kwds_w): - return space.newlist([]) + w_obj = space.newlist([]) + return space.w_list.check_user_subclass(w_listtype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py Fri Jun 4 18:55:43 2004 @@ -26,7 +26,8 @@ def descr__new__(space, w_type, *args_w, **kwds_w): # XXX 2.2 behavior: ignoring all arguments from objectobject import W_ObjectObject - return W_ObjectObject(space) + w_obj = W_ObjectObject(space) + return space.w_object.check_user_subclass(w_type, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Fri Jun 4 18:55:43 2004 @@ -84,7 +84,8 @@ 'Exception', [self.w_object], {'__init__': w_init, - '__str__': w_str}) + '__str__': w_str}, + ) done = {'Exception': self.w_Exception} # some of the complexity of the following is due to the fact @@ -111,7 +112,8 @@ self, next, [base], - {}) + {}, + ) setattr(self, 'w_' + next, newtype) @@ -141,6 +143,8 @@ } # types + from pypy.objspace.std.objecttype import object_typedef + self.object_typedef = object_typedef self.types_w = {} for typedef in self.standard_types(): w_type = self.gettypeobject(typedef) @@ -243,8 +247,11 @@ return stringobject.W_StringObject(self, ''.join(chars)) def type(self, w_obj): - assert w_obj.typedef, w_obj - return self.gettypeobject(w_obj.typedef) + if hasattr(w_obj, 'w__class__'): + return w_obj.w__class__ # user-defined classes + else: + assert w_obj.typedef, w_obj + return self.gettypeobject(w_obj.typedef) def lookup(self, w_obj, name): from pypy.objspace.std.cpythonobject import W_CPythonObject Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py Fri Jun 4 18:55:43 2004 @@ -96,7 +96,8 @@ else: raise OperationError(space.w_TypeError, space.wrap("slice() takes at least 1 argument")) - return space.newslice(w_start, w_stop, w_step) + w_obj = space.newslice(w_start, w_stop, w_step) + return space.w_slice.check_user_subclass(w_slicetype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Fri Jun 4 18:55:43 2004 @@ -46,7 +46,6 @@ # get all the sliced multimethods multimethods = slicemultimethods(space.__class__, typedef) for name, code in multimethods.items(): - #print typedef.name, ':', name fn = function.Function(space, code, defs_w=code.getdefaults(space)) assert name not in rawdict, 'name clash: %s in %s_typedef' % ( name, typedef.name) @@ -61,7 +60,7 @@ for descrname, descrvalue in rawdict.items(): dict_w[descrname] = w(descrvalue) - return W_TypeObject(space, typedef.name, bases_w, dict_w) + return W_TypeObject(space, typedef.name, bases_w, dict_w, typedef) def hack_out_multimethods(ns): result = [] Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py Fri Jun 4 18:55:43 2004 @@ -37,7 +37,8 @@ # ____________________________________________________________ def descr__new__(space, w_stringtype, w_obj=''): - return space.str(w_obj) + w_obj = space.str(w_obj) + return space.w_str.check_user_subclass(w_stringtype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py Fri Jun 4 18:55:43 2004 @@ -4,7 +4,8 @@ def descr__new__(space, w_tupletype, w_items=()): tuple_w = space.unpackiterable(w_items) - return space.newtuple(tuple_w) + w_obj = space.newtuple(tuple_w) + return space.w_tuple.check_user_subclass(w_tupletype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Fri Jun 4 18:55:43 2004 @@ -4,11 +4,28 @@ class W_TypeObject(W_Object): from pypy.objspace.std.typetype import type_typedef as typedef - def __init__(w_self, space, name, bases_w, dict_w): + def __init__(w_self, space, name, bases_w, dict_w, overridetypedef=None): W_Object.__init__(w_self, space) w_self.name = name w_self.bases_w = bases_w w_self.dict_w = dict_w + w_self.needs_new_dict = False + if overridetypedef is not None: + w_self.instancetypedef = overridetypedef + else: + # find the most specific typedef + longest_mro = [space.object_typedef] + for w_base in bases_w: + mro = w_base.instancetypedef.mro(space) + if len(mro) > len(longest_mro): + longest_mro = mro + # check that it is a sub-typedef of all other ones + for w_base in bases_w: + if w_base.instancetypedef not in longest_mro: + raise OperationError(space.w_TypeError, + space.wrap("instance layout conflicts in " + "multiple inheritance")) + w_self.instancetypedef = longest_mro[0] def getmro(w_self): # XXX this is something that works not too bad right now @@ -30,6 +47,30 @@ pass return None + def check_user_subclass(w_self, w_subtype, w_obj): + """This morphs an object newly created by the w_self's __new__ + function into an instance of a subclass of w_self if needed.""" + space = w_self.space + if space.is_true(space.is_(w_self, w_subtype)): + return w_obj + if not space.is_true(space.issubtype(w_subtype, w_self)): + raise OperationError(space.w_TypeError, + "%s.__new__(%s): %s is not a subtype of %s" % ( + w_self.name, w_subtype.name, w_subtype.name, w_self.name)) + if w_self.instancetypedef is not w_subtype.instancetypedef: + raise OperationError(space.w_TypeError, + "%s.__new__(%s) is not safe, use %s.__new__()" % ( + w_self.name, w_subtype.name, w_subtype.name)) + if w_self.instancetypedef is not w_obj.typedef: + raise OperationError(space.w_TypeError, + "%s.__new__(): got an object of type %s instead of %s" % ( + w_self.name, space.type(w_obj).name, w_self.name)) + # stuff extra attributes into w_obj + w_obj.w__class__ = w_subtype + if w_subtype.needs_new_dict: + w_obj.w__dict__ = space.newdict([]) + return w_obj + ## def lookup_exactly_here(w_self, w_key): ## space = w_self.space ## multimethods = getmultimethods(space.__class__, w_self.__class__) @@ -186,7 +227,7 @@ return space.newbool(w_type2 in w_type1.getmro()) def repr__Type(space, w_obj): - return space.wrap("" % w_obj.typename) # XXX remove 'pypy' + return space.wrap("" % w_obj.name) # XXX remove 'pypy' def getattr__Type_ANY(space, w_type, w_name): name = space.unwrap(w_name) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Fri Jun 4 18:55:43 2004 @@ -3,7 +3,7 @@ def descr__new__(space, w_typetype, w_name, w_bases, w_dict): - # XXX staticmethod-ify w_dict['__new__'] + "This is used to create user-defined classes only." from pypy.objspace.std.typeobject import W_TypeObject # XXX check types name = space.unwrap(w_name) @@ -15,7 +15,13 @@ key = space.unwrap(w_key) assert isinstance(key, str) dict_w[key] = space.getitem(w_dict, w_key) - return W_TypeObject(space, name, bases_w or [space.w_object], dict_w) + # XXX classmethod-ify w_dict['__new__'] + w_type = W_TypeObject(space, name, bases_w or [space.w_object], dict_w, None) + # provide a __dict__ for the instances if there isn't any yet + if w_type.lookup('__dict__') is None: + w_type.needs_new_dict = True + w_type.dict_w['__dict__'] = space.wrap(attrproperty_w('w__dict__')) + return space.w_type.check_user_subclass(w_typetype, w_type) def descr_get__mro__(space, w_type): # XXX this should be inside typeobject.py From mwh at codespeak.net Fri Jun 4 21:15:38 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 21:15:38 +0200 (MEST) Subject: [pypy-svn] r4927 - in pypy/branch/src-newobjectmodel/pypy/objspace: . std Message-ID: <20040604191538.9A6ED5BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 21:15:37 2004 New Revision: 4927 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Log: fixity fix Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Fri Jun 4 21:15:37 2004 @@ -201,7 +201,7 @@ w_right_impl = None else: w_right_impl = space.lookup(w_obj2,'__rpow__') - if space.issubtype(w_typ1,w_typ2): + 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 if w_left_impl is not None: @@ -255,7 +255,7 @@ w_right_impl = None else: w_right_impl = space.lookup(w_obj2,'__cmp__') - if space.issubtype(w_typ1,w_typ2): + 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 do_neg1,do_neg2 = do_neg2,do_neg1 @@ -296,7 +296,7 @@ w_right_impl = None else: w_right_impl = space.lookup(w_obj2,right) - if space.issubtype(w_typ1,w_typ2): + 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 @@ -324,7 +324,7 @@ w_right_impl = None else: w_right_impl = space.lookup(w_obj2,right) - if space.issubtype(w_typ1,w_typ2): + 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 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Fri Jun 4 21:15:37 2004 @@ -45,15 +45,15 @@ "Import here the types you want to have appear in __builtin__." from objecttype import object_typedef - #from booltype import W_BoolType + from booltype import bool_typedef from inttype import int_typedef - #from floattype import W_FloatType - #from tupletype import W_TupleType - #from listtype import W_ListType - #from dicttype import W_DictType - #from stringtype import W_StringType + from floattype import float_typedef + from tupletype import tuple_typedef + from listtype import list_typedef + from dicttype import dict_typedef + from stringtype import str_typedef from typetype import type_typedef - #from slicetype import W_SliceType + from slicetype import slice_typedef return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look @@ -266,17 +266,15 @@ return self.wrap(cls.__dict__[name]) return None - def unpacktuple(self, w_tuple): + def unpacktuple(self, w_tuple, expected_length=None): import tupleobject assert isinstance(w_tuple, tupleobject.W_TupleObject) - return w_tuple.wrappeditems + t = w_tuple.wrappeditems + if expected_length is not None and expected_length != len(t): + raise ValueError, "got a tuple of length %d instead of %d" % ( + len(t), expected_length) + return t - # special visible multimethods - delegate = DelegateMultiMethod() # delegators - unwrap = MultiMethod('unwrap', 1, []) # returns an unwrapped object - is_true = MultiMethod('nonzero', 1, []) # returns an unwrapped bool - issubtype = MultiMethod('issubtype', 2, []) - id = MultiMethod('id', 1, []) class MM: "Container for multimethods." @@ -285,6 +283,16 @@ next = MultiMethod('next', 1, ['next']) # iterator interface call = MultiMethod('call', 1, ['__call__'], varargs=True, keywords=True) #getattribute = MultiMethod('getattr', 2, ['__getattribute__']) # XXX hack + # special visible multimethods + delegate = DelegateMultiMethod() # delegators + unwrap = MultiMethod('unwrap', 1, []) # returns an unwrapped object + is_true = MultiMethod('nonzero', 1, []) # returns an unwrapped bool + issubtype = MultiMethod('issubtype', 2, []) + id = MultiMethod('id', 1, []) + + unwrap = MM.unwrap + delegate = MM.delegate + is_true = MM.is_true def is_(self, w_one, w_two): # XXX a bit of hacking to gain more speed @@ -302,12 +310,13 @@ # add all regular multimethods to StdObjSpace for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: if not hasattr(StdObjSpace.MM, _name): - if isinstance(getattr(StdObjSpace, _name, None), MultiMethod): - mm = getattr(StdObjSpace, _name) - else: - mm = MultiMethod(_symbol, _arity, _specialnames) +## if isinstance(getattr(StdObjSpace, _name, None), MultiMethod): +## mm = getattr(StdObjSpace, _name) +## else: + mm = MultiMethod(_symbol, _arity, _specialnames) setattr(StdObjSpace.MM, _name, mm) - + if not hasattr(StdObjSpace, _name): + setattr(StdObjSpace, _name, getattr(StdObjSpace.MM, _name)) # import the common base W_ObjectObject as well as # default implementations of some multimethods for all objects Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Fri Jun 4 21:15:37 2004 @@ -1,7 +1,7 @@ from pypy.interpreter import eval, function, gateway from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import attrproperty, attrproperty_w -from pypy.objspace.std.multimethod import MultiMethod +from pypy.objspace.std.multimethod import MultiMethod, FailedToImplement __all__ = ['StdTypeDef', 'newmethod', 'gateway', 'GetSetProperty', 'attrproperty', 'attrproperty_w', Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py Fri Jun 4 21:15:37 2004 @@ -75,7 +75,7 @@ from pypy.interpreter import gateway from intobject import W_IntObject from sliceobject import W_SliceObject -#import slicetype +import slicetype from listobject import W_ListObject from noneobject import W_NoneObject from tupleobject import W_TupleObject Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Fri Jun 4 21:15:37 2004 @@ -1,5 +1,5 @@ from pypy.objspace.std.objspace import * - +from pypy.interpreter.typedef import attrproperty_w class W_TypeObject(W_Object): from pypy.objspace.std.typetype import type_typedef as typedef @@ -26,6 +26,11 @@ space.wrap("instance layout conflicts in " "multiple inheritance")) w_self.instancetypedef = longest_mro[0] + # provide a __dict__ for the instances if there isn't any yet + if w_self.lookup('__dict__') is None: + w_self.needs_new_dict = True + w_self.dict_w['__dict__'] = space.wrap(attrproperty_w('w__dict__')) + def getmro(w_self): # XXX this is something that works not too bad right now Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Fri Jun 4 21:15:37 2004 @@ -17,10 +17,6 @@ dict_w[key] = space.getitem(w_dict, w_key) # XXX classmethod-ify w_dict['__new__'] w_type = W_TypeObject(space, name, bases_w or [space.w_object], dict_w, None) - # provide a __dict__ for the instances if there isn't any yet - if w_type.lookup('__dict__') is None: - w_type.needs_new_dict = True - w_type.dict_w['__dict__'] = space.wrap(attrproperty_w('w__dict__')) return space.w_type.check_user_subclass(w_typetype, w_type) def descr_get__mro__(space, w_type): From mwh at codespeak.net Fri Jun 4 21:22:47 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 21:22:47 +0200 (MEST) Subject: [pypy-svn] r4928 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040604192247.C76835BE07@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 21:22:47 2004 New Revision: 4928 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py Log: fix bool() <- no arguments! Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/booltype.py Fri Jun 4 21:22:47 2004 @@ -3,7 +3,7 @@ def descr__new__(space, w_booltype, w_obj=None): - if space.is_true(w_obj): + if w_obj is not None and space.is_true(w_obj): return space.w_True else: return space.w_False From hpk at codespeak.net Fri Jun 4 22:31:46 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 22:31:46 +0200 (MEST) Subject: [pypy-svn] r4929 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace/std Message-ID: <20040604203146.27C2C5BE07@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 22:31:45 2004 New Revision: 4929 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: - introduced special wrappers for cpython- and cpython-builtin functions which inherit from the interpreter Function objects - print stuff as it gets cpython-wrapped - some cleanups here and there Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/gateway.py Fri Jun 4 22:31:45 2004 @@ -184,8 +184,9 @@ self.code.func) space = obj.space fn = self.get_function(space) + w_obj = space.wrap(obj) return Method(space, space.wrap(fn), - space.wrap(obj), space.wrap(obj.__class__)) + w_obj, space.type(w_obj)) class app2interp(Gateway): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py Fri Jun 4 22:31:45 2004 @@ -1,19 +1,35 @@ """ -Reviewed 03-06-21 -This is an extremely general object, so the tests are -a carefully choosen sample, rather than a complete coverage. -Exception wrapping is tested and ok. -Inplace operators are untested, but quite obvious by inspection. -Some operators and functions (both unary and binary) are tested. -Inspection of table MethodImplementations is necessary and -sufficient to ensure completeness and correctness of this module. """ from pypy.objspace.std.objspace import * +from pypy.interpreter.function import Function from stringobject import W_StringObject from intobject import W_IntObject 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(self, w_args, w_kwds): + space = self.space + args = space.unwrap(w_args) + kwds = {} + keys_w = space.unpackiterable(w_kwds) + for w_key in keys_w: + kwds[space.unwrap(w_key)] = space.unwrap(space.getitem(w_kwds, w_key)) + try: + result = apply(self.cpyfunc, args, kwds) + except: + wrap_exception(space) + return space.wrap(result) + class W_CPythonObject(W_Object): "This class wraps an arbitrary CPython object." @@ -173,23 +189,18 @@ f = MethodImplementation.get(_name) if f: if _arity == 1: - def cpython_f(space, w_1, f=f, pypymethod='pypy_'+_name): + def cpython_f(space, w_1, f=f): x1 = w_1.cpyobj type_x1 = type(x1) - if hasattr(type_x1, pypymethod): - return getattr(type_x1, pypymethod)(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, pypymethod='pypy_'+_name): + def cpython_f(space, w_1, w_2, f=f): x1 = w_1.cpyobj type_x1 = type(x1) - if hasattr(type_x1, pypymethod): - return getattr(type_x1, pypymethod)(x1, w_2) - # XXX do we really want to unwrap unknown objects here? x2 = space.unwrap(w_2) try: @@ -198,12 +209,9 @@ wrap_exception(space) return space.wrap(y) elif _arity == 3: - def cpython_f(space, w_1, w_2, w_3, f=f, pypymethod='pypy_'+_name): + def cpython_f(space, w_1, w_2, w_3, f=f): x1 = w_1.cpyobj type_x1 = type(x1) - if hasattr(type_x1, pypymethod): - return getattr(type_x1, pypymethod)(x1, w_2, w_3) - x2 = space.unwrap(w_2) x3 = space.unwrap(w_3) try: @@ -231,7 +239,6 @@ return space.wrap(y) multimethod.register(cpython_f_rev, W_ANY, W_CPythonObject) - def is_true__CPython(space, w_obj): obj = space.unwrap(w_obj) try: @@ -293,8 +300,6 @@ def next__CPython(space, w_obj): obj = space.unwrap(w_obj) - if hasattr(obj, 'pypy_next'): - return obj.pypy_next() try: result = obj.next() except: @@ -304,8 +309,6 @@ def call__CPython(space, w_obj, w_arguments, w_keywords): # XXX temporary hack similar to objspace.trivial.call() callable = space.unwrap(w_obj) - if hasattr(callable, 'pypy_call'): - return callable.pypy_call(w_arguments, w_keywords) args = space.unwrap(w_arguments) keywords = space.unwrap(w_keywords) try: Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py Fri Jun 4 22:31:45 2004 @@ -252,14 +252,8 @@ items[start+i*step] = sequence2[i] return space.w_None -def repr__List(space, w_list): - w = space.wrap - a = space.add - reprs_w = map(space.repr, space.unpackiterable(w_list)) - from pypy.objspace.std.stringtype import W_StringType - w_bm = space.getattr(space.wrap(', '), space.wrap('join')) - return a(a(w('['), space.call_function(w_bm, space.newlist(reprs_w))), w(']')) - return space.newstring([]) +def app_repr__List(l): + return "[" + ", ".join([repr(x) for x in l]) + ']' def hash__List(space,w_list): raise OperationError(space.w_TypeError,space.wrap("list objects are unhashable")) @@ -534,5 +528,7 @@ }; """ +from pypy.interpreter import gateway +gateway.importall(globals()) from pypy.objspace.std import listtype register_all(vars(), listtype) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Fri Jun 4 22:31:45 2004 @@ -2,6 +2,7 @@ from pypy.interpreter.baseobjspace import * from pypy.objspace.std.multimethod import * from pypy.objspace.descroperation import DescrOperation +import types class W_Object: @@ -139,7 +140,7 @@ "None" : self.w_None, "NotImplemented": self.w_NotImplemented, "Ellipsis": self.w_Ellipsis, - "long": self.wrap(long), # XXX temporary +# "long": self.wrap(long), # XXX temporary } # types @@ -204,8 +205,14 @@ return listobject.W_ListObject(self, wrappeditems) if isinstance(x, Wrappable): return x.__spacebind__(self) - #print "wrapping %r (%s)" % (x, type(x)) import cpythonobject + SlotWrapperType = type(type(None).__repr__) + if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): + return cpythonobject.W_BuiltinFunctionObject(self, x) + print "cpython wrapping %r (%s)" % (x, type(x)) + #if hasattr(x, '__bases__'): + # print "cpython wrapping a class %r (%s)" % (x, type(x)) + #raise TypeError, "cannot wrap classes" return cpythonobject.W_CPythonObject(self, x) def newint(self, int_w): @@ -247,7 +254,11 @@ return stringobject.W_StringObject(self, ''.join(chars)) def type(self, w_obj): - if hasattr(w_obj, 'w__class__'): + from pypy.objspace.std.cpythonobject import W_CPythonObject + if isinstance(w_obj, W_CPythonObject): + #raise TypeError, str(w_obj.cpyobj) + return self.wrap(type(w_obj.cpyobj)) + elif hasattr(w_obj, 'w__class__'): return w_obj.w__class__ # user-defined classes else: assert w_obj.typedef, w_obj From hpk at codespeak.net Fri Jun 4 22:35:25 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 4 Jun 2004 22:35:25 +0200 (MEST) Subject: [pypy-svn] r4930 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040604203525.B4F665BE09@thoth.codespeak.net> Author: hpk Date: Fri Jun 4 22:35:25 2004 New Revision: 4930 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: uncommment print statement ... Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Fri Jun 4 22:35:25 2004 @@ -209,7 +209,7 @@ SlotWrapperType = type(type(None).__repr__) if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): return cpythonobject.W_BuiltinFunctionObject(self, x) - print "cpython wrapping %r (%s)" % (x, type(x)) + #print "cpython wrapping %r (%s)" % (x, type(x)) #if hasattr(x, '__bases__'): # print "cpython wrapping a class %r (%s)" % (x, type(x)) #raise TypeError, "cannot wrap classes" From mwh at codespeak.net Fri Jun 4 22:43:39 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 22:43:39 +0200 (MEST) Subject: [pypy-svn] r4931 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace/std tool/tb_server Message-ID: <20040604204339.E6FC25BE09@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 22:43:39 2004 New Revision: 4931 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Log: fixes to None.__class__ and instantiating subtypes. $ python2.3 pypy/test_all.py -S interpreter ... Ran 109 tests in 165.046s FAILED (failures=3, errors=10) ... not too bad! Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Fri Jun 4 22:43:39 2004 @@ -27,7 +27,9 @@ self.doc = doc def descr_property_get(space, w_property, w_obj, w_ignored): - if w_obj == space.w_None: + # XXX HAAAAAAAAAAAACK (but possibly a good one) + if w_obj == space.w_None and not space.is_true(space.is_(w_ignored, space.type(space.w_None))): + print w_property, w_obj, w_ignored return w_property else: return space.unwrap(w_property).fget(space, w_obj) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Fri Jun 4 22:43:39 2004 @@ -26,10 +26,19 @@ space.wrap("instance layout conflicts in " "multiple inheritance")) w_self.instancetypedef = longest_mro[0] + nd = False + for w_base in bases_w: + if w_base.needs_new_dict: + nd = True + break + # provide a __dict__ for the instances if there isn't any yet if w_self.lookup('__dict__') is None: w_self.needs_new_dict = True w_self.dict_w['__dict__'] = space.wrap(attrproperty_w('w__dict__')) + elif nd: + w_self.needs_new_dict = True + def getmro(w_self): Modified: pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/tb_server/render.py Fri Jun 4 22:43:39 2004 @@ -94,7 +94,7 @@ for k, v in tb.tb_frame.f_locals.items(): if k[0] == '_': continue - lines.append(xml.escape('%s=%s\n'%(k, repr(v)[:50]))) + lines.append(xml.escape('%s=%s\n'%(k, repr(v)[:1000]))) return lines From mwh at codespeak.net Fri Jun 4 23:29:42 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 23:29:42 +0200 (MEST) Subject: [pypy-svn] r4932 - pypy/branch/src-newobjectmodel/pypy/interpreter/test Message-ID: <20040604212942.A34365C16B@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 23:29:40 2004 New Revision: 4932 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py Log: fix test Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_interpreter.py Fri Jun 4 23:29:40 2004 @@ -23,7 +23,7 @@ code = space.unwrap(w_code) code.exec_code(space, w_glob, w_glob) - wrappedargs = space.newtuple(args) + wrappedargs = space.newtuple([w(a) for a in args]) wrappedfunc = space.getitem(w_glob, w(functionname)) wrappedkwds = space.newdict([]) try: From mwh at codespeak.net Fri Jun 4 23:36:08 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 4 Jun 2004 23:36:08 +0200 (MEST) Subject: [pypy-svn] r4933 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040604213608.66DEA5C16B@thoth.codespeak.net> Author: mwh Date: Fri Jun 4 23:36:07 2004 New Revision: 4933 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Log: fix recursive mro() call Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Fri Jun 4 23:36:07 2004 @@ -21,7 +21,7 @@ def mro(self, space): assert len(self.bases) <= 1 if self.bases: - return [self] + self.bases[0].mro() + return [self] + self.bases[0].mro(space) else: return [self] From arigo at codespeak.net Sat Jun 5 10:56:34 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 10:56:34 +0200 (MEST) Subject: [pypy-svn] r4934 - in pypy/branch/src-newobjectmodel/pypy: objspace/flow translator/tool Message-ID: <20040605085634.52A4C5BE07@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 10:56:32 2004 New Revision: 4934 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/flow/objspace.py pypy/branch/src-newobjectmodel/pypy/translator/tool/make_dot.py Log: - fixed an importerror in the flow objspace - updated an XXLocalPath to the new std.path interface Modified: pypy/branch/src-newobjectmodel/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/flow/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/flow/objspace.py Sat Jun 5 10:56:32 2004 @@ -1,7 +1,7 @@ # ______________________________________________________________________ import sys, operator, types import pypy -from pypy.interpreter.baseobjspace import ObjSpace, NoValue +from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError from pypy.objspace.flow.model import * @@ -22,7 +22,7 @@ self.w_None = Constant(None) self.w_False = Constant(False) self.w_True = Constant(True) - for exc in [KeyError, ValueError]: + for exc in [KeyError, ValueError, StopIteration]: clsname = exc.__name__ setattr(self, 'w_'+clsname, Constant(exc)) #self.make_builtins() @@ -106,7 +106,7 @@ context = self.getexecutioncontext() outcome = context.guessbool(w_curexc, [None, StopIteration]) if outcome is StopIteration: - raise NoValue + raise OperationError(self.w_StopIteration, self.w_None) else: return w_item Modified: pypy/branch/src-newobjectmodel/pypy/translator/tool/make_dot.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/translator/tool/make_dot.py (original) +++ pypy/branch/src-newobjectmodel/pypy/translator/tool/make_dot.py Sat Jun 5 10:56:32 2004 @@ -158,7 +158,7 @@ source = dotgen.getgraph(basefilename, subgraphs) #print source dest.write(source) - psdest = dest.newext(target) + psdest = dest.new(ext=target) out = cmdexec('dot -T%s %s' % (target, str(dest))) psdest.write(out) #print "wrote", psdest From mwh at codespeak.net Sat Jun 5 11:40:45 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 11:40:45 +0200 (MEST) Subject: [pypy-svn] r4937 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605094045.7D59F5C16B@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 11:40:44 2004 New Revision: 4937 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py Log: Careful with those default args! Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/tupletype.py Sat Jun 5 11:40:44 2004 @@ -2,8 +2,11 @@ from pypy.objspace.std.objecttype import object_typedef -def descr__new__(space, w_tupletype, w_items=()): - tuple_w = space.unpackiterable(w_items) +def descr__new__(space, w_tupletype, w_items=None): + if w_items is None: + tuple_w = [] + else: + tuple_w = space.unpackiterable(w_items) w_obj = space.newtuple(tuple_w) return space.w_tuple.check_user_subclass(w_tupletype, w_obj) From arigo at codespeak.net Sat Jun 5 11:57:10 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 11:57:10 +0200 (MEST) Subject: [pypy-svn] r4938 - in pypy/branch/src-newobjectmodel/pypy/objspace: . std Message-ID: <20040605095710.BCC735C16D@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 11:57:10 2004 New Revision: 4938 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Log: - Cleaned up default operation behavior. - Fix to show all methods on built-in types. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Sat Jun 5 11:57:10 2004 @@ -143,6 +143,23 @@ space.wrap("object does not support attribute removal")) return space.get_and_call_function(w_descr,w_obj,w_name) + def is_true(space,w_obj): + if w_obj == space.w_False: + return False + if w_obj == space.w_True: + return True + if w_obj == space.w_None: + return False + w_descr = space.lookup(w_obj, '__nonzero__') + if w_descr is not None: + w_res = space.get_and_call_function(w_descr,w_obj) + return space.is_true(w_res) + w_descr = space.lookup(w_obj, '__len__') + if w_descr is not None: + w_res = space.get_and_call_function(w_descr,w_obj) + return space.is_true(w_res) + return True + def str(space,w_obj): w_descr = space.lookup(w_obj,'__str__') return space.get_and_call_function(w_descr,w_obj) @@ -217,9 +234,23 @@ raise OperationError(space.w_TypeError, space.wrap("operands do not support **")) - + + def contains(space,w_container,w_item): + w_descr = space.lookup(w_container,'__contains__') + if w_descr is not None: + return space.get_and_call_function(w_descr,w_container,w_item) + w_iter = space.iter(w_container) + while 1: + try: + w_next = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + return space.w_False + if space.is_true(space.eq(w_next, w_lookfor)): + return space.w_True - # not_ has a default implementation + # XXX not_ has a default implementation # xxx round, ord Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py Sat Jun 5 11:57:10 2004 @@ -6,34 +6,35 @@ # The following default implementations are used before delegation is tried. # 'id' is normally the address of the wrapper. -def id__Object(space, w_obj): +def id__ANY(space, w_obj): + #print 'id:', w_obj import intobject return intobject.W_IntObject(space, id(w_obj)) # this 'not' implementation should be fine for most cases -def not__Object(space, w_obj): +def not__ANY(space, w_obj): return space.newbool(not space.is_true(w_obj)) # __nonzero__ falls back to __len__ -def is_true__Object(space, w_obj): - w_descr = space.lookup(w_obj, '__len__') - if w_descr is None: - return True - else: - w_len = space.get_and_call_function(w_descr, w_obj) - return space.is_true(w_len) +##def is_true__ANY(space, w_obj): +## w_descr = space.lookup(w_obj, '__len__') +## if w_descr is None: +## return True +## else: +## w_len = space.get_and_call_function(w_descr, w_obj) +## return space.is_true(w_len) -# in-place operators fall back to their non-in-place counterpart +### in-place operators fall back to their non-in-place counterpart -for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if _name.startswith('inplace_'): - def default_inplace(space, w_1, w_2, baseop=_name[8:]): - op = getattr(space, baseop) - return op(w_1, w_2) - getattr(StdObjSpace.MM, _name).register(default_inplace, - W_Object, W_ANY) +##for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: +## if _name.startswith('inplace_'): +## def default_inplace(space, w_1, w_2, baseop=_name[8:]): +## op = getattr(space, baseop) +## return op(w_1, w_2) +## getattr(StdObjSpace.MM, _name).register(default_inplace, +## W_Object, W_ANY) # '__get__(descr, inst, cls)' returns 'descr' by default @@ -187,30 +188,30 @@ ##def str__Object(space, w_obj): ## return space.repr(w_obj) -def hash__Object(space, w_obj): - return space.id(w_obj) +##def hash__ANY(space, w_obj): +## return space.id(w_obj) # The following operations are fall-backs if we really cannot find # anything else even with delegation. # 'eq' falls back to 'is' -def eq__ANY_ANY(space, w_a, w_b): - return space.is_(w_a, w_b) +##def eq__ANY_ANY(space, w_a, w_b): +## return space.is_(w_a, w_b) # 'contains' falls back to iteration. -def contains__ANY_ANY(space, w_iterable, w_lookfor): - w_iter = space.iter(w_iterable) - while 1: - try: - w_next = space.next(w_iter) - except OperationError, e: - if not e.match(space, space.w_StopIteration): - raise - return space.w_False - if space.is_true(space.eq(w_next, w_lookfor)): - return space.w_True +##def contains__ANY_ANY(space, w_iterable, w_lookfor): +## w_iter = space.iter(w_iterable) +## while 1: +## try: +## w_next = space.next(w_iter) +## except OperationError, e: +## if not e.match(space, space.w_StopIteration): +## raise +## return space.w_False +## if space.is_true(space.eq(w_next, w_lookfor)): +## return space.w_True # ugh Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py Sat Jun 5 11:57:10 2004 @@ -1,6 +1,7 @@ from pypy.objspace.descroperation import Object from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.objspace import StdObjSpace object_init = MultiMethod('__init__', 1, varargs=True, keywords=True) @@ -20,6 +21,10 @@ def descr__str__(space, w_obj): return space.repr(w_obj) +def descr__hash__(space, w_obj): + # XXX detect non-hashable instances (the ones overriding comparison only) + return space.id(w_obj) + def descr__class__(space, w_obj): return space.type(w_obj) @@ -37,6 +42,7 @@ __delattr__ = gateway.interp2app(Object.descr__delattr__.im_func), __str__ = gateway.interp2app(descr__str__), __repr__ = gateway.interp2app(descr__repr__), + __hash__ = gateway.interp2app(descr__hash__), __class__ = GetSetProperty(descr__class__), __new__ = newmethod(descr__new__), ) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 11:57:10 2004 @@ -13,7 +13,7 @@ w_self.space = space # XXX not sure this is ever used any more def __repr__(self): - return '' % ( + return '%s(%s)' % ( self.__class__.__name__, #', '.join(['%s=%r' % keyvalue for keyvalue in self.__dict__.items()]) getattr(self, 'name', '') @@ -204,7 +204,9 @@ import listobject return listobject.W_ListObject(self, wrappeditems) if isinstance(x, Wrappable): - return x.__spacebind__(self) + w_result = x.__spacebind__(self) + #print 'wrapping', x, '->', w_result + return w_result import cpythonobject SlotWrapperType = type(type(None).__repr__) if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Sat Jun 5 11:57:10 2004 @@ -69,28 +69,35 @@ result.append(value) return result +def slicemultimethod(multimethod, typeclass): + result = {} + for i in range(len(multimethod.specialnames)): + # each MultimethodCode embeds a multimethod + name = multimethod.specialnames[i] + if name in result: + # conflict between e.g. __lt__ and + # __lt__-as-reversed-version-of-__gt__ + code = result[name] + if code.bound_position < i: + continue + mmframeclass = multimethod.extras.get('mmframeclass') + if mmframeclass is None: + if len(multimethod.specialnames) > 1: + mmframeclass = SpecialMmFrame + else: + mmframeclass = MmFrame + code = MultimethodCode(multimethod, mmframeclass, typeclass, i) + result[name] = code + return result + def slicemultimethods(spaceclass, typeclass): result = {} # import and slice all multimethods of the space.MM container - for multimethod in (hack_out_multimethods(spaceclass.MM.__dict__) + - typeclass.local_multimethods): - for i in range(len(multimethod.specialnames)): - # each MultimethodCode embeds a multimethod - name = multimethod.specialnames[i] - if name in result: - # conflict between e.g. __lt__ and - # __lt__-as-reversed-version-of-__gt__ - code = result[name] - if code.bound_position < i: - continue - mmframeclass = multimethod.extras.get('mmframeclass') - if mmframeclass is None: - if len(multimethod.specialnames) > 1: - mmframeclass = SpecialMmFrame - else: - mmframeclass = MmFrame - code = MultimethodCode(multimethod, mmframeclass, typeclass, i) - result[name] = code + for multimethod in hack_out_multimethods(spaceclass.MM.__dict__): + result.update(slicemultimethod(multimethod, typeclass)) + # import all multimethods defined directly on the type without slicing + for multimethod in typeclass.local_multimethods: + result.update(slicemultimethod(multimethod, None)) # add some more multimethods with a special interface code = MultimethodCode(spaceclass.MM.next, MmFrame, typeclass) result['next'] = code @@ -128,7 +135,11 @@ for x in self.basemultimethod.extras.get('defaults', ())] def slice(self): - return self.basemultimethod.slice(self.typeclass, self.bound_position) + if self.typeclass is None: + return self.basemultimethod + else: + return self.basemultimethod.slice(self.typeclass, + self.bound_position) def create_frame(self, space, w_globals, closure=None): return self.framecls(space, self) From arigo at codespeak.net Sat Jun 5 12:06:37 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 12:06:37 +0200 (MEST) Subject: [pypy-svn] r4939 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040605100637.B506C5C16B@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 12:06:37 2004 New Revision: 4939 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: Typo. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Sat Jun 5 12:06:37 2004 @@ -247,7 +247,7 @@ if not e.match(space, space.w_StopIteration): raise return space.w_False - if space.is_true(space.eq(w_next, w_lookfor)): + if space.is_true(space.eq(w_next, w_item)): return space.w_True # XXX not_ has a default implementation From mwh at codespeak.net Sat Jun 5 12:20:49 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 12:20:49 +0200 (MEST) Subject: [pypy-svn] r4940 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605102049.0589A5C16B@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 12:20:49 2004 New Revision: 4940 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py Log: be careful with defaults in __new__ implementations nudges for string -> int conversion import all object implementations *before* building type objects! Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/floattype.py Sat Jun 5 12:20:49 2004 @@ -1,15 +1,18 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.objecttype import object_typedef -def descr__new__(space, w_floattype, w_value=0): - if space.is_true(space.isinstance(w_value, space.w_str)): - try: - w_obj = space.newfloat(float(space.unwrap(w_value))) - except ValueError, e: - raise OperationError(space.w_ValueError, - space.wrap(str(e))) +def descr__new__(space, w_floattype, w_value=None): + if w_value is None: + w_obj = space.newfloat(0.0) else: - w_obj = space.float(w_value) + if space.is_true(space.isinstance(w_value, space.w_str)): + try: + w_obj = space.newfloat(float(space.unwrap(w_value))) + except ValueError, e: + raise OperationError(space.w_ValueError, + space.wrap(str(e))) + else: + w_obj = space.float(w_value) return space.w_float.check_user_subclass(w_floattype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py Sat Jun 5 12:20:49 2004 @@ -1,15 +1,22 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.objecttype import object_typedef +from pypy.interpreter.error import OperationError - -def descr__new__(space, w_inttype, w_value=0, w_base=None): +def descr__new__(space, w_inttype, w_value=None, w_base=None): from intobject import W_IntObject - if w_base == space.w_None: - w_obj = space.int(w_value) + if w_base is None: + w_base = space.w_None + if w_value is None: + space.newint(0) + if w_base == space.w_None and not space.is_true(space.isinstance(w_value, space.w_str)): + w_obj = space.int(w_value) else: + if w_base == space.w_None: + base = 0 + else: + base = space.unwrap(w_base) # XXX write the logic for int("str", base) s = space.unwrap(w_value) - base = space.unwrap(w_base) try: value = int(s, base) except TypeError, e: @@ -21,7 +28,7 @@ except OverflowError, e: raise OperationError(space.w_OverflowError, space.wrap(str(e))) - w_obj = W_IntObject(value) + w_obj = W_IntObject(space, value) return space.w_int.check_user_subclass(w_inttype, w_obj) # ____________________________________________________________ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 12:20:49 2004 @@ -55,6 +55,14 @@ from stringtype import str_typedef from typetype import type_typedef from slicetype import slice_typedef + import floatobject + import objectobject + import boolobject + import tupleobject + import listobject + import stringobject + import typeobject + import sliceobject return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stringtype.py Sat Jun 5 12:20:49 2004 @@ -36,8 +36,11 @@ # ____________________________________________________________ -def descr__new__(space, w_stringtype, w_obj=''): - w_obj = space.str(w_obj) +def descr__new__(space, w_stringtype, w_obj=None): + if w_obj is None: + w_obj = space.newstring('') + else: + w_obj = space.str(w_obj) return space.w_str.check_user_subclass(w_stringtype, w_obj) # ____________________________________________________________ From arigo at codespeak.net Sat Jun 5 12:23:51 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 12:23:51 +0200 (MEST) Subject: [pypy-svn] r4941 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605102351.EB9165C16B@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 12:23:51 2004 New Revision: 4941 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: 2nd round at importing object implementations before they are used. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 12:23:51 2004 @@ -55,11 +55,16 @@ from stringtype import str_typedef from typetype import type_typedef from slicetype import slice_typedef - import floatobject + # 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. import objectobject import boolobject + import intobject + import floatobject import tupleobject import listobject + import dictobject import stringobject import typeobject import sliceobject From hpk at codespeak.net Sat Jun 5 12:24:18 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 12:24:18 +0200 (MEST) Subject: [pypy-svn] r4942 - pypy/trunk/src/pypy/tool Message-ID: <20040605102418.C14295C16B@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 12:24:18 2004 New Revision: 4942 Modified: pypy/trunk/src/pypy/tool/testit.py Log: get rid of wrong "using objspace ...." messages Modified: pypy/trunk/src/pypy/tool/testit.py ============================================================================== --- pypy/trunk/src/pypy/tool/testit.py (original) +++ pypy/trunk/src/pypy/tool/testit.py Sat Jun 5 12:24:18 2004 @@ -357,7 +357,7 @@ Options.spacename = spacename warnings.defaultaction = Options.showwarning and 'default' or 'ignore' - print >> sys.stderr, "running tests via", repr(objspace()) + #print >> sys.stderr, "running tests via", repr(objspace()) runner.run(suite) def main(root=None): From hpk at codespeak.net Sat Jun 5 12:36:07 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 12:36:07 +0200 (MEST) Subject: [pypy-svn] r4943 - pypy/trunk/src/pypy/translator/test Message-ID: <20040605103607.593715C16B@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 12:36:06 2004 New Revision: 4943 Modified: pypy/trunk/src/pypy/translator/test/test_translator.py Log: inplace-ops don't currently work correctly, commented out test-five Modified: pypy/trunk/src/pypy/translator/test/test_translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_translator.py (original) +++ pypy/trunk/src/pypy/translator/test/test_translator.py Sat Jun 5 12:36:06 2004 @@ -57,7 +57,7 @@ nested_whiles = t.compile() self.assertEquals(nested_whiles(5,3), '!!!!!') - def test_call_five(self): + def xxxtest_call_five(self): t = Translator(snippet.call_five) t.simplify() t.annotate([]) From arigo at codespeak.net Sat Jun 5 12:43:42 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 12:43:42 +0200 (MEST) Subject: [pypy-svn] r4944 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605104342.985E85C16B@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 12:43:42 2004 New Revision: 4944 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Log: A previous code reorganization broke the algorithm to check for __lt__ vs. __gt__. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Sat Jun 5 12:43:42 2004 @@ -69,8 +69,7 @@ result.append(value) return result -def slicemultimethod(multimethod, typeclass): - result = {} +def slicemultimethod(multimethod, typeclass, result): for i in range(len(multimethod.specialnames)): # each MultimethodCode embeds a multimethod name = multimethod.specialnames[i] @@ -88,16 +87,15 @@ mmframeclass = MmFrame code = MultimethodCode(multimethod, mmframeclass, typeclass, i) result[name] = code - return result def slicemultimethods(spaceclass, typeclass): result = {} # import and slice all multimethods of the space.MM container for multimethod in hack_out_multimethods(spaceclass.MM.__dict__): - result.update(slicemultimethod(multimethod, typeclass)) + slicemultimethod(multimethod, typeclass, result) # import all multimethods defined directly on the type without slicing for multimethod in typeclass.local_multimethods: - result.update(slicemultimethod(multimethod, None)) + slicemultimethod(multimethod, None, result) # add some more multimethods with a special interface code = MultimethodCode(spaceclass.MM.next, MmFrame, typeclass) result['next'] = code From mwh at codespeak.net Sat Jun 5 12:54:41 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 12:54:41 +0200 (MEST) Subject: [pypy-svn] r4945 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040605105441.2FCBC5C16B@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 12:54:40 2004 New Revision: 4945 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Log: when a descriptor is not a descriptor, return *it*, not the object being queried!!! Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Sat Jun 5 12:54:40 2004 @@ -100,7 +100,7 @@ def get(space,w_descr,w_obj,w_type): w_get = space.lookup(w_descr,'__get__') if w_get is None: - return w_obj + return w_descr return space.get_and_call_function(w_get,w_descr,w_obj,w_type) def set(space,w_descr,w_obj,w_val): From arigo at codespeak.net Sat Jun 5 12:58:18 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 12:58:18 +0200 (MEST) Subject: [pypy-svn] r4946 - pypy/branch/src-newobjectmodel/pypy/interpreter/test Message-ID: <20040605105818.744545C16E@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 12:58:17 2004 New Revision: 4946 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py Log: Test case for the bug just fixed. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_class.py Sat Jun 5 12:58:17 2004 @@ -62,7 +62,22 @@ raise RuntimeError c = C() self.assertRaises(RuntimeError, c.meth) - - + + def test_class_attr(self): + class C: + a = 42 + c = C() + self.assertEquals(c.a, 42) + self.assertEquals(C.a, 42) + + def test_class_attr_inherited(self): + class C: + a = 42 + class D(C): + pass + d = D() + self.assertEquals(d.a, 42) + self.assertEquals(D.a, 42) + if __name__ == '__main__': testit.main() From mwh at codespeak.net Sat Jun 5 12:59:47 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 12:59:47 +0200 (MEST) Subject: [pypy-svn] r4947 - pypy/branch/src-newobjectmodel/pypy/interpreter/test Message-ID: <20040605105947.659E75C16F@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 12:59:46 2004 New Revision: 4947 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py Log: don't compare immutable values using 'is' function's have __class__ attributes now. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py Sat Jun 5 12:59:46 2004 @@ -25,10 +25,10 @@ def f(): pass self.assertEquals(f.__name__, 'f') self.assertEquals(f.__doc__, None) - self.assert_(f.__name__ is f.func_name) - self.assert_(f.__doc__ is f.func_doc) + self.assert_(f.__name__ == f.func_name) + self.assert_(f.__doc__ == f.func_doc) self.assert_(f.__dict__ is f.func_dict) - #XXX self.assert_(hasattr(f, '__class__')) + self.assert_(hasattr(f, '__class__')) class AppTestFunction(testit.AppTestCase): def test_simple_call(self): From hpk at codespeak.net Sat Jun 5 13:04:10 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 13:04:10 +0200 (MEST) Subject: [pypy-svn] r4948 - pypy/trunk/src/pypy/translator/test Message-ID: <20040605110410.C50BD5C16E@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 13:04:10 2004 New Revision: 4948 Modified: pypy/trunk/src/pypy/translator/test/snippet.py pypy/trunk/src/pypy/translator/test/test_annrpython.py pypy/trunk/src/pypy/translator/test/test_pyrextrans.py pypy/trunk/src/pypy/translator/test/test_translator.py Log: simplified the specification of translator/genpyrex tests a bit. The snippets have default-values for arguments specifying starting-types for the annotation ... Modified: pypy/trunk/src/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/snippet.py Sat Jun 5 13:04:10 2004 @@ -19,99 +19,23 @@ But for now, none of the above applies. """ -function_info={ - 'append_five':{'arg_names': ['lst'],'arg_types':[list], - 'name': 'append_five'}, - 'branch_id': {'arg_names': ['cond', 'a', 'b'],'arg_types':[int,int,int], - 'name': 'branch_id'}, - 'break_continue': {'arg_names': ['x'],'arg_types':[int], - 'name': 'break_continue'}, - 'build_instance': {'arg_names': [],'arg_types':[], - 'name': 'build_instance'}, - 'builtinusage': {'arg_names': [],'arg_types':[], - 'name': 'builtinusage'}, - 'call_five': {'arg_names': [],'arg_types':[], - 'name': 'call_five'}, - 'choose_last': {'arg_names': [],'arg_types':[], - 'name': 'choose_last'}, - 'factorial': {'arg_names': ['n'],'arg_types':[int], - 'name': 'factorial'}, - 'factorial2': {'arg_names': ['n'],'arg_types':[int], - 'name': 'factorial2'}, - 'finallys': {'arg_names': ['lst'],'arg_types':[list], - 'name': 'finallys'}, - 'greet': {'arg_names': ['target'],'arg_types':[str], - 'name': 'greet'}, - 'half_of_n': {'arg_names': ['n'],'arg_types':[int], - 'name': 'half_of_n'}, - 'if_then_else': {'arg_names': ['cond', 'x', 'y'], - 'arg_types':[object,object,object], - 'name': 'if_then_else'}, - 'inheritance1': {'arg_names': [],'arg_types':[], - 'name': 'inheritance1'}, - 'inheritance2': {'arg_names': [],'arg_types':[], - 'name': 'inheritance2'}, - #'inheritance_nonrunnable': {'arg_names': [],'arg_types':[], - # 'name': 'inheritance_nonrunnable'}, - 'int_id': {'arg_names': ['x'],'arg_types':[int], - 'name': 'int_id'}, - 'is_perfect_number': {'arg_names': ['i'],'arg_types':[int], - 'name': 'is_perfect_number'}, - 'knownkeysdict': {'arg_names': ['b'],'arg_types':[object], - 'name': 'knownkeysdict'}, - 'merge_setattr': {'arg_names': ['x'],'arg_types':[object], - 'name': 'merge_setattr'}, -# 'methodcall1': {'arg_names': ['cond'],'arg_types':[int], -# 'name': 'methodcall1'}, - 'my_bool': {'arg_names': ['x'],'arg_types':[object], - 'name': 'my_bool'}, - 'my_gcd': {'arg_names': ['a', 'b'],'arg_types':[int,int], - 'name': 'my_gcd'}, - 'nested_whiles': {'arg_names': ['i', 'j'],'arg_types':[int,int], - 'name': 'nested_whiles'}, - 'poly_branch': {'arg_names': ['x'],'arg_types':[object], - 'name': 'poly_branch'}, - 'poor_man_range': {'arg_names': ['i'],'arg_types':[int], - 'name': 'poor_man_range'}, - 'poor_man_rev_range': {'arg_names': ['i'],'arg_types':[int], - 'name': 'poor_man__rev_range'}, - 'powerset': {'arg_names': ['x'],'arg_types':[int], - 'name': 'powerset'}, - 'prime': {'arg_names': ['n'],'arg_types':[int], - 'name': 'prime'}, - 'reverse_3': {'arg_names': ['lst'],'arg_types':[list], - 'name': 'reverse_3'}, - 's_and': {'arg_names': ['x', 'y'],'arg_types':[object,object], - 'name': 's_and'}, - 'set_attr': {'arg_names': [],'arg_types':[], - 'name': 'set_attr'}, - 'sieve_of_eratosthenes': {'arg_names': [],'arg_types':[], - 'name': 'sieve_of_eratosthenes'}, - 'simple_func': {'arg_names': ['i'],'arg_types':[int], - 'name': 'simple_func'}, - 'simple_id': {'arg_names': ['x'],'arg_types':[object], - 'name': 'simple_id'}, - 'simple_method': {'arg_names': ['v'],'arg_types':[object], - 'name': 'simple_method'}, -# 'somebug1': {'arg_names': ['n'],'arg_types':[int], -# 'name': 'somebug1'}, - 'time_waster': {'arg_names': ['n'],'arg_types':[int], - 'name': 'time_waster'}, - 'two_plus_two': {'arg_names': [],'arg_types':[], - 'name': 'two_plus_two'}, - 'while_func': {'arg_names': ['i'],'arg_types':[int], - 'name': 'while_func'}, - 'yast': {'arg_names': ['lst'],'arg_types':[list], - 'name': 'yast'} - } -def if_then_else(cond, x, y): +# we define the starting types in the snippet +# function's default arguments. the following +# definitions denote to the "test-generator" +# the possible types that can be passed to +# the specific snippet. +numtype = (int, float, ) +anytype = (int, float, str, ) +seqtype = (list, tuple) + +def if_then_else(cond=anytype, x=anytype, y=anytype): if cond: return x else: return y -def my_gcd(a, b): +def my_gcd(a=numtype, b=numtype): r = a % b while r: a = b @@ -119,7 +43,7 @@ r = a % b return b -def is_perfect_number(n): +def is_perfect_number(n=int): div = 1 sum = 0 while div < n: @@ -128,7 +52,7 @@ div += 1 return n == sum -def my_bool(x): +def my_bool(x=int): return not not x def two_plus_two(): @@ -160,17 +84,17 @@ i = i + 1 return count -def simple_func(i): +def simple_func(i=numtype): return i + 1 -def while_func(i): +def while_func(i=numtype): total = 0 while i > 0: total = total + i i = i - 1 return total -def nested_whiles(i, j): +def nested_whiles(i=int, j=int): s = '' z = 5 while z > 0: @@ -182,7 +106,7 @@ s = s + '!' return s -def poor_man_range(i): +def poor_man_range(i=int): lst = [] while i > 0: i = i - 1 @@ -190,17 +114,17 @@ lst.reverse() return lst -def poor_man_rev_range(i): +def poor_man_rev_range(i=int): lst = [] while i > 0: i = i - 1 lst += [i] return lst -def simple_id(x): +def simple_id(x=anytype): return x -def branch_id(cond, a, b): +def branch_id(cond=anytype, a=anytype, b=anytype): while 1: if cond: return a @@ -210,13 +134,13 @@ def builtinusage(): return pow(2, 2) -def yast(lst): +def yast(lst=seqtype): total = 0 for z in lst: total = total + z return total -def time_waster(n): +def time_waster(n=int): """Arbitrary test function""" i = 0 x = 1 @@ -228,7 +152,7 @@ i = i + 1 return x -def half_of_n(n): +def half_of_n(n=int): """Slice test""" i = 0 lst = range(n) @@ -237,13 +161,13 @@ i = i + 1 return i -def int_id(x): +def int_id(x=int): i = 0 while i < x: i = i + 1 return i -def greet(target): +def greet(target=str): """String test""" hello = "hello" return hello + target @@ -255,7 +179,7 @@ pass return choice -def poly_branch(x): +def poly_branch(x=int): if x: y = [1,2,3] else: @@ -264,13 +188,13 @@ z = y return z*2 -def s_and(x, y): +def s_and(x=anytype, y=anytype): if x and y: return 'yes' else: return 'no' -def break_continue(x): +def break_continue(x=numtype): result = [] i = 0 while 1: @@ -285,14 +209,14 @@ i = i + 1 return result -def reverse_3(lst): +def reverse_3(lst=seqtype): try: a, b, c = lst except: return 0, 0, 0 return c, b, a -def finallys(lst): +def finallys(lst=seqtype): x = 1 try: x = 2 @@ -310,28 +234,27 @@ x = 8 return x -def factorial(n): +def factorial(n=int): if n <= 1: return 1 else: return n * factorial(n-1) -def factorial2(n): # analysed in a different order +def factorial2(n=int): # analysed in a different order if n > 1: return n * factorial(n-1) else: return 1 -def append_five(lst): +def _append_five(lst): lst += [5] - def call_five(): a = [] - append_five(a) + _append_five(a) return a - +# INHERITANCE / CLASS TESTS class C(object): pass def build_instance(): @@ -370,7 +293,7 @@ d.stuff = (-12, -12) e = E() e.stuff = (3, "world") - return getstuff(d), getstuff(e) + return _getstuff(d), _getstuff(e) class F: pass @@ -384,7 +307,7 @@ self.attr = 1 return E(), y -def knownkeysdict(b): +def knownkeysdict(b=anytype): if b: d = {'a': 0} d['b'] = b @@ -393,7 +316,7 @@ d = {'b': -123} return d['b'] -def prime(n): +def prime(n=int): return len([i for i in range(1,n+1) if n%i==0]) == 2 @@ -401,13 +324,13 @@ def my_method(self): return self.my_attribute -def simple_method(v): +def simple_method(v=anytype): z = Z() z.my_attribute = v return z.my_method() -def powerset(setsize): +def powerset(setsize=int): """Powerset This one is from a Philippine Pythonista Hangout, an modified @@ -439,14 +362,15 @@ # --------------------(Currently) Non runnable Functions --------------------- -def somebug1(n): +def _somebug1(n=int): l = [] v = l.append while n: - l[7] = 5 + l[7] = 5 # raises an exception + break return v -def inheritance_nonrunnable(): +def _inheritance_nonrunnable(): d = D() d.stuff = (-12, -12) e = E() @@ -455,16 +379,16 @@ # --------------------(Currently) Non compillable Functions --------------------- -def attrs(): +def _attrs(): def b(): pass b.f = 4 b.g = 5 return b.f + b.g -def getstuff(x): +def _getstuff(x): return x.stuff -def methodcall1(cond): +def _methodcall1(cond): if cond: x = G() else: Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_annrpython.py (original) +++ pypy/trunk/src/pypy/translator/test/test_annrpython.py Sat Jun 5 13:04:10 2004 @@ -165,7 +165,7 @@ def test_inheritance2(self): a = RPythonAnnotator() - s = a.build_types(snippet.inheritance_nonrunnable, []) + s = a.build_types(snippet._inheritance_nonrunnable, []) # result should be exactly: self.assertEquals(s, annmodel.SomeTuple([ annmodel.SomeInteger(), @@ -181,7 +181,7 @@ def test_methodcall1(self): a = RPythonAnnotator() - s = a.build_types(snippet.methodcall1, [int]) + s = a.build_types(snippet._methodcall1, [int]) # result should be a tuple of (C, positive_int) self.assertEquals(s.knowntype, tuple) self.assertEquals(len(s.items), 2) @@ -191,7 +191,7 @@ def test_classes_methodcall1(self): a = RPythonAnnotator() - a.build_types(snippet.methodcall1, [int]) + a.build_types(snippet._methodcall1, [int]) # the user classes should have the following attributes: classes = a.bookkeeper.userclasses self.assertEquals(classes[snippet.F].attrs.keys(), ['m']) @@ -207,7 +207,7 @@ def test_somebug1(self): a = RPythonAnnotator() - s = a.build_types(snippet.somebug1, [int]) + s = a.build_types(snippet._somebug1, [int]) # result should be a built-in method self.assert_(isinstance(s, annmodel.SomeBuiltin)) Modified: pypy/trunk/src/pypy/translator/test/test_pyrextrans.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_pyrextrans.py (original) +++ pypy/trunk/src/pypy/translator/test/test_pyrextrans.py Sat Jun 5 13:04:10 2004 @@ -4,8 +4,9 @@ from pypy.translator.genpyrex import GenPyrex from pypy.objspace.flow.model import * from pypy.translator.tool.buildpyxmodule import build_cfunc +from pypy.translator.translator import Translator -from pypy.translator.test import snippet as t +from pypy.translator.test import snippet class NoTypePyrexGenTestCase(testit.IntTestCase): @@ -24,64 +25,111 @@ return build_cfunc(func, **options) def test_simple_func(self): - cfunc = self.build_cfunc(t.simple_func) + cfunc = self.build_cfunc(snippet.simple_func) self.assertEquals(cfunc(1), 2) def test_while_func(self): - while_func = self.build_cfunc(t.while_func) + while_func = self.build_cfunc(snippet.while_func) self.assertEquals(while_func(10), 55) def test_nested_whiles(self): - nested_whiles = self.build_cfunc(t.nested_whiles) + nested_whiles = self.build_cfunc(snippet.nested_whiles) self.assertEquals(nested_whiles(111, 114), '...!...!...!...!...!') def test_poor_man_range(self): - poor_man_range = self.build_cfunc(t.poor_man_range) + poor_man_range = self.build_cfunc(snippet.poor_man_range) self.assertEquals(poor_man_range(10), range(10)) def test_simple_id(self): #we just want to see, if renaming of parameter works correctly #if the first branch is the end branch - simple_id = self.build_cfunc(t.simple_id) + simple_id = self.build_cfunc(snippet.simple_id) self.assertEquals(simple_id(9), 9) def test_branch_id(self): - branch_id = self.build_cfunc(t.branch_id) + branch_id = self.build_cfunc(snippet.branch_id) self.assertEquals(branch_id(1, 2, 3), 2) self.assertEquals(branch_id(0, 2, 3), 3) def test_int_id(self): - int_id = self.build_cfunc(t.int_id) + int_id = self.build_cfunc(snippet.int_id) self.assertEquals(int_id(3), 3) def dont_test_attrs(self): - attrs = self.build_cfunc(t.attrs) + attrs = self.build_cfunc(snippet.attrs) self.assertEquals(attrs(), 9) def test_builtinusage(self): - fun = self.build_cfunc(t.builtinusage) + fun = self.build_cfunc(snippet.builtinusage) self.assertEquals(fun(), 4) def test_sieve(self): - sieve = self.build_cfunc(t.sieve_of_eratosthenes) + sieve = self.build_cfunc(snippet.sieve_of_eratosthenes) self.assertEquals(sieve(), 1028) def test_slice(self): - half = self.build_cfunc(t.half_of_n) + half = self.build_cfunc(snippet.half_of_n) self.assertEquals(half(10), 5) def test_poly_branch(self): - poly_branch = self.build_cfunc(t.poly_branch) + poly_branch = self.build_cfunc(snippet.poly_branch) self.assertEquals(poly_branch(10), [1,2,3]*2) self.assertEquals(poly_branch(0), ['a','b','c']*2) def test_and(self): - sand = self.build_cfunc(t.s_and) + sand = self.build_cfunc(snippet.s_and) self.assertEquals(sand(5, 6), "yes") self.assertEquals(sand(5, 0), "no") self.assertEquals(sand(0, 6), "no") self.assertEquals(sand(0, 0), "no") +class TypedTestCase(testit.IntTestCase): + + def getcompiled(self, func): + t = Translator(func) + t.simplify() + # builds starting-types from func_defs + argstypelist = [] + if func.func_defaults: + for spec in func.func_defaults: + if isinstance(spec, tuple): + spec = spec[0] # use the first type only for the tests + argstypelist.append(spec) + t.annotate(argstypelist) + return t.compile() + + def test_set_attr(self): + set_attr = self.getcompiled(snippet.set_attr) + self.assertEquals(set_attr(), 2) + + def test_inheritance2(self): + inheritance2 = self.getcompiled(snippet.inheritance2) + self.assertEquals(inheritance2(), ((-12, -12), (3, "world"))) + + def test_factorial2(self): + factorial2 = self.getcompiled(snippet.factorial2) + self.assertEquals(factorial2(5), 120) + + def test_factorial(self): + factorial = self.getcompiled(snippet.factorial) + self.assertEquals(factorial(5), 120) + + def test_simple_method(self): + simple_method = self.getcompiled(snippet.simple_method) + self.assertEquals(simple_method(55), 55) + + def test_sieve_of_eratosthenes(self): + sieve_of_eratosthenes = self.getcompiled(snippet.sieve_of_eratosthenes) + self.assertEquals(sieve_of_eratosthenes(), 1028) + + def test_nested_whiles(self): + nested_whiles = self.getcompiled(snippet.nested_whiles) + self.assertEquals(nested_whiles(5,3), '!!!!!') + + def xxxtest_call_five(self): + call_five = self.getcompiled(snippet.call_five) + self.assertEquals(call_five(), [5]) + if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/translator/test/test_translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_translator.py (original) +++ pypy/trunk/src/pypy/translator/test/test_translator.py Sat Jun 5 13:04:10 2004 @@ -5,64 +5,6 @@ from pypy.translator.test import snippet -class TranslatorTestCase(testit.IntTestCase): - - def test_set_attr(self): - t = Translator(snippet.set_attr) - t.simplify() - t.annotate([]) - set_attr = t.compile() - self.assertEquals(set_attr(), 2) - - def test_inheritance2(self): - t = Translator(snippet.inheritance2) - t.simplify() - t.annotate([]) - inheritance2 = t.compile() - self.assertEquals(inheritance2(), ((-12, -12), (3, "world"))) - - def test_factorial2(self): - t = Translator(snippet.factorial2) - t.simplify() - t.annotate([int]) - factorial2 = t.compile() - self.assertEquals(factorial2(5), 120) - - def test_factorial(self): - t = Translator(snippet.factorial) - t.simplify() - t.annotate([int]) - factorial = t.compile() - self.assertEquals(factorial(5), 120) - - def test_simple_method(self): - t = Translator(snippet.simple_method) - t.simplify() - t.annotate([int]).simplify() - simple_method = t.compile() - self.assertEquals(simple_method(55), 55) - - def test_sieve_of_eratosthenes(self): - t = Translator(snippet.sieve_of_eratosthenes) - t.simplify() - t.annotate([])#.simplify() - #t.view() - sieve_of_eratosthenes = t.compile() - self.assertEquals(sieve_of_eratosthenes(), 1028) - - def test_nested_whiles(self): - t = Translator(snippet.nested_whiles) - t.simplify() - t.annotate([int,int]) - nested_whiles = t.compile() - self.assertEquals(nested_whiles(5,3), '!!!!!') - - def xxxtest_call_five(self): - t = Translator(snippet.call_five) - t.simplify() - t.annotate([]) - call_five = t.compile() - self.assertEquals(call_five(), [5]) if __name__ == '__main__': testit.main() From arigo at codespeak.net Sat Jun 5 13:44:17 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 13:44:17 +0200 (MEST) Subject: [pypy-svn] r4949 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605114417.053155BE07@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 13:44:17 2004 New Revision: 4949 Removed: pypy/branch/src-newobjectmodel/pypy/objspace/std/userobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/usertype.py Log: No longer used. Deleted: /pypy/branch/src-newobjectmodel/pypy/objspace/std/userobject.py ============================================================================== --- /pypy/branch/src-newobjectmodel/pypy/objspace/std/userobject.py Sat Jun 5 13:44:17 2004 +++ (empty file) @@ -1,190 +0,0 @@ -""" -Reviewed 03-06-22 -This object implements "instances of custom types" completely and -accurately. We have selectively tested (in the testfile) a key -selection of features: setting and getting attributes and the -correct working of inheritance from both builtin and user types -as well as of normal and special attributes. -""" -from pypy.objspace.std.objspace import * -from usertype import W_UserType -import typeobject - - -class W_UserObject(W_Object): - """Instances of this class are what the user sees as instances of custom - types. All such instances are implemented by the present W_UserObject - class.""" - statictype = W_UserType - -def make_user_object(space, w_type, w_args, w_kwds): - # the restriction that a single built-in type is allowed among the - # bases is specific to our W_UserObject implementation of user - # objects, and should thus not be enforced in W_UserType. - # Note: w_type may be any object, not necessarily a W_UserType - # (in case 'type' is subclassed). - - # create an instance of the parent built-in type - w_builtintype = getsinglebuiltintype(space, w_type) - newobj = space.call(w_builtintype, w_args, w_kwds) - - morph_into_user_object(space,w_type,newobj) - - return newobj - - -registerimplementation(W_UserObject) - -_bltin_subclass_cache = {} - -def _make_bltin_subclass(cls): - global _bltin_subclass_cache - try: - return _bltin_subclass_cache[cls] - except: - subcls = type(W_Object)("%s_sub" % cls.__name__, (W_UserObject, cls), - {'statictype': W_UserType}) - - # W_UserObject-to-the-parent-builtin-type delegation - def delegate_to_parent_builtin(space, w_userobj): - return w_userobj - delegate_to_parent_builtin.trivial_delegation = True - delegate_to_parent_builtin.result_class = cls - delegate_to_parent_builtin.priority = PRIORITY_PARENT_TYPE - StdObjSpace.delegate.register(delegate_to_parent_builtin, subcls) - - _bltin_subclass_cache[cls] = subcls - return subcls - -def morph_into_user_object(space,w_type,newobj): - newobj.__class__ = _make_bltin_subclass(newobj.__class__) - newobj.w_type = w_type - if not hasattr(newobj,'w_dict'): - newobj.w_dict = space.newdict([]) - return newobj - - -def getsinglebuiltintype(space, w_type): - "Return the (asserted unique) built-in type that w_type inherits from." - mostspecialized = space.w_object - mro = space.getattr(w_type, space.wrap('__mro__')) - mro = space.unpacktuple(mro) - mro.reverse() - for w_base in mro: - if not isinstance(w_base, W_UserType): - if not space.is_true(space.issubtype(w_base, mostspecialized)): - raise OperationError(space.w_TypeError, - space.wrap("instance layout conflicts in " - "multiple inheritance")) - mostspecialized = w_base - return mostspecialized - - -def type__User(space, w_userobj): - return w_userobj.w_type - -def getdict__User(space, w_userobj): - # XXX check getdict() of the base built-in implementation - return w_userobj.w_dict - -def is_data_descr__User(space, w_userobj): - try: - space.type(w_userobj).lookup(space.wrap("__set__")) - except: - try: - space.type(w_userobj).lookup(space.wrap("__delete__")) - except: - return 0 - else: - return 1 - else: - return 1 - - -class SpecialMethod: - """An implementation for a multimethod that looks for a user-defined - special __xxx__ method.""" - - def __init__(self, method_name, bound_position=0): - self.method_name = method_name - self.bound_position = bound_position - - def internal_do_call(self, space, w_userobj, w_args, w_kwds): - w_key = space.wrap(self.method_name) - w_mro = space.getattr(w_userobj.w_type, space.wrap('__mro__')) - mro = space.unpacktuple(w_mro) - for w_base in mro: - if not isinstance(w_base, W_UserType): - continue - try: - w_function = w_base.lookup_exactly_here(w_key) - except KeyError: - continue - w_method = space.get(w_function, w_userobj, w_base) - return space.call(w_method, w_args, w_kwds) - raise FailedToImplement - - def do_call(self, space, args_w): - # args_w is in the standard multimethod order - # we need it in the Python-friendly order (i.e. swapped for __rxxx__) - args_w = list(args_w) - w_userobj = args_w.pop(self.bound_position) - w_args = space.newtuple(args_w) - return self.internal_do_call(space, w_userobj, w_args, space.newdict([])) - - def normal_call(self, space, *args_w): - "Call a user-defined __xxx__ method and convert the result back." - w_result = self.do_call(space, args_w) - # interpret 'NotImplemented' as meaning not implemented (duh). - if space.is_true(space.is_(w_result, space.w_NotImplemented)): - raise FailedToImplement - return w_result - - def next_call(self, space, *args_w): - "For .next()." - # don't accept NotImplemented nor a real None, but catch StopIteration - return self.do_call(space, args_w) - - def nonzero_call(self, space, *args_w): - "For __nonzero__()." - # accept any object and return its truth value - # XXX if the user returns another custom object he can - # force the interpreter into an infinite loop - w_result = self.do_call(space, args_w) - return space.is_true(w_result) - - def argskwds_call(self, space, w_userobj, w_args, w_kwds): - "For __init__()." - return self.internal_do_call(space, w_userobj, w_args, w_kwds) - - def iter_call(self, space, *args_w): - try: - return self.do_call(space, args_w) - except FailedToImplement: - w_userobj = args_w[0] - try: - space.type(w_userobj).lookup(space.wrap('__getitem__')) - except KeyError: - raise FailedToImplement - else: - from iterobject import W_SeqIterObject - return W_SeqIterObject(space, args_w[0]) - - -import new -for multimethod in typeobject.hack_out_multimethods(StdObjSpace): - if multimethod in (StdObjSpace.iter, StdObjSpace.call): - continue - for i in range(len(multimethod.specialnames)): - f = SpecialMethod(multimethod.specialnames[i], i).normal_call - signature = [W_ANY] * multimethod.arity - signature[i] = W_UserObject - multimethod.register(f, *signature) - -next__User = SpecialMethod('next').next_call -is_true__User = SpecialMethod('nonzero').nonzero_call -object_init__User = SpecialMethod('__init__').argskwds_call -call__User_ANY_ANY = SpecialMethod('__call__').argskwds_call -iter__User = SpecialMethod('__iter__').iter_call - -register_all(vars()) Deleted: /pypy/branch/src-newobjectmodel/pypy/objspace/std/usertype.py ============================================================================== --- /pypy/branch/src-newobjectmodel/pypy/objspace/std/usertype.py Sat Jun 5 13:44:17 2004 +++ (empty file) @@ -1,93 +0,0 @@ -""" -Reviewed 03-06-22 -""" -from __future__ import nested_scopes -from pypy.objspace.std.objspace import * -import typeobject, objecttype -from typeobject import W_TypeObject - -class W_UserType(W_TypeObject): - """Instances of this class are user-defined Python type objects. - All user-defined types are instances of the present class. - Builtin-in types, on the other hand, each have their own W_XxxType - class.""" - - # 'typename' is an instance property here - - def __init__(w_self, space, w_name, w_bases, w_dict): - w_self.typename = space.unwrap(w_name) - W_TypeObject.__init__(w_self, space) - w_self.w_name = w_name - w_self.w_bases = w_bases - w_self.w_dict = w_dict - - def __repr__(self): - return ''%(self.space.unwrap(self.w_name),) - - def getbases(w_self): - bases = w_self.space.unpackiterable(w_self.w_bases) - if bases: - return bases - else: - return W_TypeObject.getbases(w_self) # defaults to (w_object,) - - def lookup_exactly_here(w_self, w_key): - space = w_self.space - try: - w_value = space.getitem(w_self.w_dict, w_key) - except OperationError, e: - # catch KeyErrors and turn them into KeyErrors (real ones!) - if not e.match(space, space.w_KeyError): - raise - raise KeyError - return w_value - -registerimplementation(W_UserType) - -# XXX we'll worry about the __new__/__init__ distinction later -# XXX NOTE: currently (03-06-21) user-object can only sublass -# types which register an implementation for 'new' -- currently -# this means that e.g. subclassing list or str works, subclassing -# int or float does not -- this is not a bug fixable in userobject -# (perhaps in the object-space, perhaps in each builtin type...?) -# but we're documenting it here as there seems no better place!!! -# The problem is actually that, currently, several types such as -# int and float just cannot be CALLED -- this needs to be fixed soon. -# Note: currently (03-12-21) this appears to be fully & correctly fixed. -def type_new__UserType_UserType(space, w_basetype, w_usertype, w_args, w_kwds): - import typetype - # XXX this uses the following algorithm: - # walk the __mro__ of the user type - # for each *user* type t in there, just look for a __new__ in t.__dict__ - # if we get to a *built-in* type t, we use t.__new__, which is a - # bound method from the type 'type'. - for w_looktype in w_basetype.getmro(): - if not isinstance(w_looktype, W_UserType): - # no user-defined __new__ found - type_new = typetype.W_TypeType.type_new.get(space) - return type_new(w_looktype, w_usertype, w_args, w_kwds) - try: - w_new = w_looktype.lookup_exactly_here(space.wrap('__new__')) - except KeyError: - pass - else: - w_newobj = space.call_function(w_new, [w_usertype, w_args, w_kwds]) - return w_newobj, True - raise AssertionError, "execution should not get here" - -def type_new__ANY_UserType(space, w_basetype, w_usertype, w_args, w_kwds): - import typetype - from userobject import morph_into_user_object, getsinglebuiltintype - assert w_basetype is getsinglebuiltintype(space, w_usertype) - type_new = typetype.W_TypeType.type_new.get(space) - w_newobject, callinit = type_new(w_basetype, w_basetype, w_args, w_kwds) - morph_into_user_object(space, w_usertype, w_newobject) - return w_newobject, True - -def getdict__UserType(space, w_usertype): - return w_usertype.w_dict - -def repr__UserType(space, w_usertype): - return space.wrap("" % w_usertype.typename) - -register_all(vars()) From arigo at codespeak.net Sat Jun 5 13:44:37 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 13:44:37 +0200 (MEST) Subject: [pypy-svn] r4950 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605114437.436905C16B@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 13:44:36 2004 New Revision: 4950 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: __init__() was not present for built-in types. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py Sat Jun 5 13:44:36 2004 @@ -16,6 +16,12 @@ def not__ANY(space, w_obj): return space.newbool(not space.is_true(w_obj)) +# __init__ should succeed if called internally as a multimethod + +def init__ANY(space, w_obj, w_args, w_kwds): + pass + + # __nonzero__ falls back to __len__ ##def is_true__ANY(space, w_obj): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py Sat Jun 5 13:44:36 2004 @@ -85,7 +85,7 @@ result[space.unwrap(w_key)] = space.unwrap(cell.get()) return result -def object_init__Dict(space, w_dict, w_args, w_kwds): +def init__Dict(space, w_dict, w_args, w_kwds): dict_clear__Dict(space, w_dict) args = space.unpackiterable(w_args) if len(args) == 0: Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/listobject.py Sat Jun 5 13:44:36 2004 @@ -37,7 +37,7 @@ items = [space.unwrap(w_item) for w_item in w_list.ob_item[:w_list.ob_size]] return list(items) -def object_init__List(space, w_list, w_args, w_kwds): +def init__List(space, w_list, w_args, w_kwds): if space.is_true(w_kwds): raise OperationError(space.w_TypeError, space.wrap("no keyword arguments expected")) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objectobject.py Sat Jun 5 13:44:36 2004 @@ -13,8 +13,7 @@ delegate__ANY.result_class = W_ObjectObject delegate__ANY.priority = PRIORITY_PARENT_TYPE -#def object_init__Object(space, w_object, w_args, w_kwds): -# pass +# ____________________________________________________________ register_all(vars()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objecttype.py Sat Jun 5 13:44:36 2004 @@ -3,14 +3,6 @@ from pypy.objspace.std.register_all import register_all from pypy.objspace.std.objspace import StdObjSpace -object_init = MultiMethod('__init__', 1, varargs=True, keywords=True) - -def object_init__ANY(space, w_obj, w_args, w_kwds): - pass - -register_all(vars(), globals()) - -# ____________________________________________________________ def descr__repr__(space, w_obj): w = space.wrap Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 13:44:36 2004 @@ -315,6 +315,7 @@ is_true = MultiMethod('nonzero', 1, []) # returns an unwrapped bool issubtype = MultiMethod('issubtype', 2, []) id = MultiMethod('id', 1, []) + init = MultiMethod('__init__', 1, varargs=True, keywords=True) unwrap = MM.unwrap delegate = MM.delegate From mwh at codespeak.net Sat Jun 5 14:19:50 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 14:19:50 +0200 (MEST) Subject: [pypy-svn] r4953 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace objspace/std Message-ID: <20040605121950.617675BE07@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 14:19:47 2004 New Revision: 4953 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Log: remove not_ multimethod make next() non-special multimethod rename is_true() -> nonzero(), make non-special space.is_true() now descroperation method that unwraps result of nonzero() (and participates in ugly hacks to avoid infinte recursion) Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Sat Jun 5 14:19:47 2004 @@ -93,6 +93,9 @@ w_id_y = self.id(w_y) return self.eq(w_id_x, w_id_y) + def not_(self, w_obj): + return self.wrap(not self.is_true(w_obj)) + def unwrapdefault(self, w_value, default): if w_value is None or w_value == self.w_None: return default @@ -195,7 +198,7 @@ ('delitem', 'delitem', 2, ['__delitem__']), ('pos', 'pos', 1, ['__pos__']), ('neg', 'neg', 1, ['__neg__']), - ('not_', 'not', 1, []), + ('nonzero', 'truth', 1, ['__nonzero__']), ('abs' , 'abs', 1, ['__abs__']), ('hex', 'hex', 1, ['__hex__']), ('oct', 'oct', 1, ['__oct__']), @@ -239,6 +242,7 @@ ('ge', '>=', 2, ['__ge__', '__le__']), ('contains', 'contains', 2, ['__contains__']), ('iter', 'iter', 1, ['__iter__']), + ('next', 'next', 1, ['next']), ('call', 'call', 3, ['__call__']), ('get', 'get', 3, ['__get__']), ('set', 'set', 3, ['__set__']), @@ -303,5 +307,4 @@ # newstring([w_1, w_2,...]) -> w_string from ascii numbers (bytes) # newdict([(w_key,w_value),...]) -> w_dict #newslice(w_start,w_stop,w_step) -> w_slice (any argument may be a real None) -# next(w_iter) -> w_value or raise StopIteration # Modified: pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/descroperation.py Sat Jun 5 14:19:47 2004 @@ -250,7 +250,6 @@ if space.is_true(space.eq(w_next, w_item)): return space.w_True - # XXX not_ has a default implementation # xxx round, ord @@ -419,7 +418,7 @@ setattr(DescrOperation,_name,_impl_maker(_symbol,_specialnames)) elif _name not in ['id','type','issubtype', # not really to be defined in DescrOperation - 'ord','not_','round']: + 'ord','round']: raise Exception,"missing def for operation%s" % _name Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/boolobject.py Sat Jun 5 14:19:47 2004 @@ -22,8 +22,8 @@ delegate__Bool.priority = PRIORITY_PARENT_TYPE -def is_true__Bool(space, w_bool): - return w_bool.boolval +def nonzero__Bool(space, w_bool): + return w_bool def unwrap__Bool(space, w_bool): return w_bool.boolval Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py Sat Jun 5 14:19:47 2004 @@ -137,7 +137,6 @@ # 'delitem': see below, 'pos': operator.pos, 'neg': operator.neg, - 'not_': operator.not_, 'abs': operator.abs, 'hex': hex, 'oct': oct, @@ -239,10 +238,10 @@ return space.wrap(y) multimethod.register(cpython_f_rev, W_ANY, W_CPythonObject) -def is_true__CPython(space, w_obj): +def nonzero__CPython(space, w_obj): obj = space.unwrap(w_obj) try: - return operator.truth(obj) + return space.newbool(operator.truth(obj)) except: wrap_exception(space) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/default.py Sat Jun 5 14:19:47 2004 @@ -11,11 +11,6 @@ import intobject return intobject.W_IntObject(space, id(w_obj)) -# this 'not' implementation should be fine for most cases - -def not__ANY(space, w_obj): - return space.newbool(not space.is_true(w_obj)) - # __init__ should succeed if called internally as a multimethod def init__ANY(space, w_obj, w_args, w_kwds): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py Sat Jun 5 14:19:47 2004 @@ -125,11 +125,11 @@ return raise OperationError(space.w_KeyError, w_lookup) -def is_true__Dict(space, w_dict): +def nonzero__Dict(space, w_dict): # this must be implemented in addition to len() for dictionaries # for infinite recursion reasons (is_true -> len -> call to len -> # checking for keywords -> is_true etc.) - return not not w_dict.non_empties() + return space.newbool(not not w_dict.non_empties()) def len__Dict(space, w_dict): return space.wrap(len(w_dict.non_empties())) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/floatobject.py Sat Jun 5 14:19:47 2004 @@ -239,8 +239,8 @@ def abs__Float(space, w_float): return W_FloatObject(space, abs(w_float.floatval)) -def is_true__Float(space, w_float): - return w_float.floatval != 0.0 +def nonzero__Float(space, w_float): + return space.newbool(w_float.floatval != 0.0) ######## coersion must be done later later = """ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/intobject.py Sat Jun 5 14:19:47 2004 @@ -289,9 +289,8 @@ else: return neg__Int(space, w_int1) -def is_true__Int(space, w_int1): - ''' note: this must return an UNWRAPPED bool!!! ''' - return w_int1.intval != 0 +def nonzero__Int(space, w_int1): + return space.newbool(w_int1.intval != 0) def invert__Int(space, w_int1): x = w_int1.intval Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/noneobject.py Sat Jun 5 14:19:47 2004 @@ -13,8 +13,8 @@ def unwrap__None(space, w_none): return None -def is_true__None(space, w_none): - return False +def nonzero__None(space, w_none): + return space.w_False def repr__None(space, w_none): return space.wrap('None') Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 14:19:47 2004 @@ -312,14 +312,13 @@ # special visible multimethods delegate = DelegateMultiMethod() # delegators unwrap = MultiMethod('unwrap', 1, []) # returns an unwrapped object - is_true = MultiMethod('nonzero', 1, []) # returns an unwrapped bool issubtype = MultiMethod('issubtype', 2, []) id = MultiMethod('id', 1, []) init = MultiMethod('__init__', 1, varargs=True, keywords=True) unwrap = MM.unwrap delegate = MM.delegate - is_true = MM.is_true + #is_true = MM.is_true def is_(self, w_one, w_two): # XXX a bit of hacking to gain more speed @@ -334,6 +333,14 @@ return self.newbool(self.unwrap(w_one) is self.unwrap(w_two)) return self.newbool(0) + def is_true(self, w_obj): + # XXX don't look! + from dictobject import W_DictObject + if isinstance(w_obj, W_DictObject): + return not not w_obj.non_empties() + else: + return DescrOperation.is_true(self, w_obj) + # add all regular multimethods to StdObjSpace for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: if not hasattr(StdObjSpace.MM, _name): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/register_all.py Sat Jun 5 14:19:47 2004 @@ -2,7 +2,6 @@ _name_mappings = { 'and': 'and_', 'or': 'or_', - 'not': 'not_', } def register_all(module_dict, alt_ns=None): Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Sat Jun 5 14:19:47 2004 @@ -96,11 +96,6 @@ # import all multimethods defined directly on the type without slicing for multimethod in typeclass.local_multimethods: slicemultimethod(multimethod, None, result) - # add some more multimethods with a special interface - code = MultimethodCode(spaceclass.MM.next, MmFrame, typeclass) - result['next'] = code - code = MultimethodCode(spaceclass.is_true, NonZeroMmFrame, typeclass) - result['__nonzero__'] = code # remove the empty slices for name, code in result.items(): if code.slice().is_empty(): @@ -168,21 +163,3 @@ else: return self.space.w_NotImplemented -##class NextMmFrame(eval.Frame): -## def run(self): -## "Call the next() multimethod." -## mm = self.code.slice().get(self.space) -## args = self.fastlocals_w -## try: -## return mm(*args) -## except NoValue: -## raise OperationError(self.space.w_StopIteration, -## self.space.w_None) - -class NonZeroMmFrame(eval.Frame): - def run(self): - "Call the is_true() multimethods." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w - result = mm(*args) - return self.space.newbool(result) From mwh at codespeak.net Sat Jun 5 14:29:28 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 14:29:28 +0200 (MEST) Subject: [pypy-svn] r4954 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605122928.82A1F5BE07@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 14:29:27 2004 New Revision: 4954 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Log: kill mounds of commented out code Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Sat Jun 5 14:29:27 2004 @@ -85,141 +85,6 @@ w_obj.w__dict__ = space.newdict([]) return w_obj -## def lookup_exactly_here(w_self, w_key): -## space = w_self.space -## multimethods = getmultimethods(space.__class__, w_self.__class__) -## key = space.unwrap(w_key) -## if not isinstance(key, str): -## raise OperationError(space.w_TypeError, -## space.wrap('attribute name must be string')) -## try: -## code = multimethods[key] -## except KeyError: -## raise KeyError # pass on the KeyError -## if code.slice().is_empty(): -## raise KeyError -## fn = function.Function(space, code, defs_w=code.getdefaults(space)) -## return space.wrap(fn) - - -##def hack_out_multimethods(cls): -## result = [] -## for base in cls.__bases__: -## result += hack_out_multimethods(base) -## for value in cls.__dict__.itervalues(): -## if isinstance(value, MultiMethod): -## result.append(value) -## return result - -##AllSlicedMultimethods = {} - -##def getmultimethods(spaceclass, typeclass): -## try: -## multimethods = AllSlicedMultimethods[spaceclass, typeclass] -## except KeyError: -## multimethods = AllSlicedMultimethods[spaceclass, typeclass] = {} -## # import all multimethods of the type class and of the objspace -## for multimethod in (hack_out_multimethods(typeclass) + -## hack_out_multimethods(spaceclass)): -## for i in range(len(multimethod.specialnames)): -## # each MultimethodCode embeds a multimethod -## name = multimethod.specialnames[i] -## if name in multimethods: -## # conflict between e.g. __lt__ and -## # __lt__-as-reversed-version-of-__gt__ -## code = multimethods[name] -## if code.bound_position < i: -## continue -## mmframeclass = multimethod.extras.get('mmframeclass') -## if mmframeclass is None: -## if len(multimethod.specialnames) > 1: -## mmframeclass = SpecialMmFrame -## else: -## mmframeclass = MmFrame -## code = MultimethodCode(multimethod, mmframeclass, typeclass, i) -## multimethods[name] = code -## # add some more multimethods with a special interface -## code = MultimethodCode(spaceclass.next, NextMmFrame, typeclass) -## multimethods['next'] = code -## code = MultimethodCode(spaceclass.is_true, NonZeroMmFrame, typeclass) -## multimethods['__nonzero__'] = code -## return multimethods - -##class MultimethodCode(eval.Code): -## """A code object that invokes a multimethod.""" - -## def __init__(self, multimethod, framecls, typeclass, bound_position=0): -## eval.Code.__init__(self, multimethod.operatorsymbol) -## self.basemultimethod = multimethod -## self.typeclass = typeclass -## self.bound_position = bound_position -## self.framecls = framecls -## argnames = ['x%d'%(i+1) for i in range(multimethod.arity)] -## argnames.insert(0, argnames.pop(self.bound_position)) -## varargname = kwargname = None -## if multimethod.extras.get('varargs', False): -## varargname = 'args' -## if multimethod.extras.get('keywords', False): -## kwargname = 'keywords' -## self.sig = argnames, varargname, kwargname - -## def signature(self): -## return self.sig - -## def getdefaults(self, space): -## return [space.wrap(x) -## for x in self.basemultimethod.extras.get('defaults', ())] - -## def slice(self): -## return self.basemultimethod.slice(self.typeclass, self.bound_position) - -## def create_frame(self, space, w_globals, closure=None): -## return self.framecls(space, self) - -##class MmFrame(eval.Frame): -## def run(self): -## "Call the multimethod, raising a TypeError if not implemented." -## mm = self.code.slice().get(self.space) -## args = self.fastlocals_w -## w_result = mm(*args) -## # we accept a real None from operations with no return value -## if w_result is None: -## w_result = self.space.w_None -## return w_result - -##class SpecialMmFrame(eval.Frame): -## def run(self): -## "Call the multimethods, possibly returning a NotImplemented." -## mm = self.code.slice().get(self.space) -## args = self.fastlocals_w -## try: -## return mm.perform_call(args) -## except FailedToImplement, e: -## if e.args: -## raise OperationError(*e.args) -## else: -## return self.space.w_NotImplemented - -##class NextMmFrame(eval.Frame): -## def run(self): -## "Call the next() multimethod." -## mm = self.code.slice().get(self.space) -## args = self.fastlocals_w -## try: -## return mm(*args) -## except NoValue: -## raise OperationError(self.space.w_StopIteration, -## self.space.w_None) - -##class NonZeroMmFrame(eval.Frame): -## def run(self): -## "Call the is_true() multimethods." -## mm = self.code.slice().get(self.space) -## args = self.fastlocals_w -## result = mm(*args) -## return self.space.newbool(result) - - def call__Type(space, w_type, w_args, w_kwds): args_w = space.unpacktuple(w_args) # special case for type(x) From arigo at codespeak.net Sat Jun 5 14:32:15 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 14:32:15 +0200 (MEST) Subject: [pypy-svn] r4955 - pypy/branch/src-newobjectmodel/pypy/module Message-ID: <20040605123215.12B665BE07@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 14:32:14 2004 New Revision: 4955 Modified: pypy/branch/src-newobjectmodel/pypy/module/sysinterp.py Log: Just wrap the whole CPython module in a CPythonObject instead of emulating it as a Module instance. Modified: pypy/branch/src-newobjectmodel/pypy/module/sysinterp.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/module/sysinterp.py (original) +++ pypy/branch/src-newobjectmodel/pypy/module/sysinterp.py Sat Jun 5 14:32:14 2004 @@ -12,16 +12,17 @@ def hack_cpython_module(modname): "Steal a module from CPython." cpy_module = __import__(modname, globals(), locals(), None) - # to build the dictionary of the module, we get all the objects - # accessible as 'self.xxx'. Methods are bound. - contents = [] - for name in cpy_module.__dict__: - # ignore names in '_xyz' - if not name.startswith('_') or name.endswith('_'): - value = cpy_module.__dict__[name] - contents.append((space.wrap(name), space.wrap(value))) - w_contents = space.newdict(contents) - return Module(space, space.wrap(modname), w_contents) + return cpy_module +## # to build the dictionary of the module, we get all the objects +## # accessible as 'self.xxx'. Methods are bound. +## contents = [] +## for name in cpy_module.__dict__: +## # ignore names in '_xyz' +## if not name.startswith('_') or name.endswith('_'): +## value = cpy_module.__dict__[name] +## contents.append((space.wrap(name), space.wrap(value))) +## w_contents = space.newdict(contents) +## return Module(space, space.wrap(modname), w_contents) # ____________________________________________________________ # From arigo at codespeak.net Sat Jun 5 14:32:24 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 14:32:24 +0200 (MEST) Subject: [pypy-svn] r4956 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605123224.CDD6A5C16E@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 14:32:24 2004 New Revision: 4956 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: Minor fix for CPythonObject. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 14:32:24 2004 @@ -223,7 +223,7 @@ import cpythonobject SlotWrapperType = type(type(None).__repr__) if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): - return cpythonobject.W_BuiltinFunctionObject(self, x) + return cpythonobject.W_BuiltinFunctionObject(self, x) #print "cpython wrapping %r (%s)" % (x, type(x)) #if hasattr(x, '__bases__'): # print "cpython wrapping a class %r (%s)" % (x, type(x)) @@ -287,7 +287,7 @@ return w_type.lookup(name) else: # hack - for cls in w_obj.cpyobj.__class__.__mro__: + for cls in type(w_obj.cpyobj).__mro__: if name in cls.__dict__: return self.wrap(cls.__dict__[name]) return None From mwh at codespeak.net Sat Jun 5 14:34:29 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 14:34:29 +0200 (MEST) Subject: [pypy-svn] r4957 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605123429.7F75D5BE07@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 14:34:28 2004 New Revision: 4957 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Log: setattr for types Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Sat Jun 5 14:34:28 2004 @@ -122,7 +122,14 @@ return space.get(w_descr,w_type,space.type(w_type)) raise OperationError(space.w_AttributeError,w_name) -# XXX __setattr__ +def setattr__Type_ANY_ANY(space, w_type, w_name, w_value): + 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): + return space.set(w_descr,w_type,space.type(w_type)) + w_type.dict_w[name] = w_value + # XXX __delattr__ # XXX __hash__ ?? From hpk at codespeak.net Sat Jun 5 14:34:41 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 14:34:41 +0200 (MEST) Subject: [pypy-svn] r4958 - pypy/trunk/src/pypy/translator/test Message-ID: <20040605123441.A0B245C16B@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 14:34:41 2004 New Revision: 4958 Added: pypy/trunk/src/pypy/translator/test/run_snippet.py - copied, changed from r4942, pypy/trunk/src/pypy/translator/test/some_snippets_test.py Removed: pypy/trunk/src/pypy/translator/test/some_snippets_test.py Log: a new run_snippet tests which scans through all snippet functions and tries to flow/annotate and compile them, printing a nice report and taking the starting types out of the func_defaults of the snippets. Copied: pypy/trunk/src/pypy/translator/test/run_snippet.py (from r4942, pypy/trunk/src/pypy/translator/test/some_snippets_test.py) ============================================================================== --- pypy/trunk/src/pypy/translator/test/some_snippets_test.py (original) +++ pypy/trunk/src/pypy/translator/test/run_snippet.py Sat Jun 5 14:34:41 2004 @@ -5,96 +5,84 @@ """ import autopath import traceback +import sys from pypy.tool import testit from pypy.translator.translator import Translator from pypy.translator.test import snippet -import inspect - -def compile(func,argtypes=[]): - - t = Translator(func) - t.simplify() - t.annotate(argtypes)#.simplify() - #t.view() - compiled_function = t.compile() - return compiled_function - -def compile_by_inspecting(module): - bad=0 - good=0 - funcs={} - all=module.__dict__.items() - for fu in all: - if isinstance(fu[1],type(compile)): - func_info={} - func_versions={} +class Result: + def __init__(self, func, argtypes): + self.func = func + self.argtypes = argtypes + self.r_flow = self.r_annotate = self.r_compile = None + for name in 'flow', 'annotate', 'compile': + method = getattr(self, name) + resname = 'r_' + name try: - args=inspect.getargspec(fu[1]) - func_info['arg_names']=args[0] - func_info['name']=fu[0] - func_versions['python']=fu[1] - func_versions['pyrex']=compile(fu[1],[int]*len(args[0])) + method() + except (KeyboardInterrupt, SystemExit): + raise except: - print fu[0] - bad+=1 + self.excinfo = sys.exc_info() + setattr(self, resname, False) else: - good+=1 - funcs[fu[0]]=(func_info,func_versions) - print "Good: %i, Bad : %i, All: %i"%(good,bad,good+bad) - return funcs -def random_arg(arg): - if arg is int: - return 5 - if arg is list: - return [1,2,3,4,5,6] # [1,'ere','fggf']Doesn't work for snippet.yast - if arg is str: - return 'python' - else: - return 'object' - -def compile_by_function_info(module,info): - result={} - for func_name in info.keys(): - func=module.__dict__[func_name] - arg_types=info[func_name]['arg_types'] - try: - pyrex_func=compile(func,arg_types) - except: - traceback.print_exc() - print "Pyrex Compilation exception",func_name - args=tuple([random_arg(atype) for atype in arg_types]) - try: - pyresult=func(*args) - try: - pyrexresult=pyrex_func(*args) - except: - print "pyrex function not runnable",func_name - raise - except: - print "Python Function not runnable",func_name - print traceback.print_exc() - else: - result[func_name]=(pyresult, pyrexresult) #or (pyresult,pyrexresult) - - return result - -def get_funcs_from_module(module): - info=module.__dict__.get('function_info',None) - if info: - funcs=compile_by_function_info(module,info) - else: - funcs=compile_by_inspecting(module) - return funcs + setattr(self, resname, True) + + def flow(self): + self.translator = Translator(func) + self.translator.simplify() + + def annotate(self): + self.translator.annotate(self.argtypes) + + def compile(self): + compiled_function = self.translator.compile() + return compiled_function +def collect_functions(module): + l = [] + for name, value in vars(module).items(): + if name[0] != '_' and hasattr(value, 'func_code'): + l.append(value) + return l + +def get_arg_types(func): + # func_defaults e.g.: ([int, float], [str, int], int) + if func.func_defaults: + argstypelist = [] + for spec in func.func_defaults: + if isinstance(spec, tuple): + spec = spec[0] # use the first type only for the tests + argstypelist.append(spec) + yield argstypelist + else: + yield [] + +# format string for result-lines +format_str = "%-30s %10s %10s %10s" + +def repr_result(res): + name = res.func.func_name + argtypes = res.argtypes + funccall = "%s(%s)" % (name, ", ".join([x.__name__ for x in argtypes])) + flow = res.r_flow and 'ok' or 'fail' + ann = res.r_annotate and 'ok' or 'fail' + comp = res.r_compile and 'ok' or 'fail' + return format_str %(funccall, flow, ann, comp) + if __name__=='__main__': - funcs=get_funcs_from_module(snippet) - import pprint - print len(funcs) - for f in funcs.keys(): - assert funcs[f][0]==funcs[f][1],"%s!=%s"%(funcs[f][0],funcs[f][1]) - print f, - pprint.pprint(funcs[f]) - + funcs = collect_functions(snippet) + funcs.insert(0, snippet._attrs) + results = [] + print format_str %("functioncall", "flowed", "annotated", "compiled") + for func in funcs: + for argtypeslist in get_arg_types(func): + result = Result(func, argtypeslist) + results.append(result) + print repr_result(result) + for res in results: + print repr_result(res) + + Deleted: /pypy/trunk/src/pypy/translator/test/some_snippets_test.py ============================================================================== --- /pypy/trunk/src/pypy/translator/test/some_snippets_test.py Sat Jun 5 14:34:41 2004 +++ (empty file) @@ -1,100 +0,0 @@ -""" - - Use all functions in snippet to test translation to pyrex - -""" -import autopath -import traceback -from pypy.tool import testit -from pypy.translator.translator import Translator - -from pypy.translator.test import snippet - -import inspect - -def compile(func,argtypes=[]): - - t = Translator(func) - t.simplify() - t.annotate(argtypes)#.simplify() - #t.view() - compiled_function = t.compile() - return compiled_function - -def compile_by_inspecting(module): - bad=0 - good=0 - funcs={} - all=module.__dict__.items() - for fu in all: - if isinstance(fu[1],type(compile)): - func_info={} - func_versions={} - try: - args=inspect.getargspec(fu[1]) - func_info['arg_names']=args[0] - func_info['name']=fu[0] - func_versions['python']=fu[1] - func_versions['pyrex']=compile(fu[1],[int]*len(args[0])) - except: - print fu[0] - bad+=1 - else: - good+=1 - funcs[fu[0]]=(func_info,func_versions) - print "Good: %i, Bad : %i, All: %i"%(good,bad,good+bad) - return funcs -def random_arg(arg): - if arg is int: - return 5 - if arg is list: - return [1,2,3,4,5,6] # [1,'ere','fggf']Doesn't work for snippet.yast - if arg is str: - return 'python' - else: - return 'object' - -def compile_by_function_info(module,info): - result={} - for func_name in info.keys(): - func=module.__dict__[func_name] - arg_types=info[func_name]['arg_types'] - try: - pyrex_func=compile(func,arg_types) - except: - traceback.print_exc() - print "Pyrex Compilation exception",func_name - args=tuple([random_arg(atype) for atype in arg_types]) - try: - pyresult=func(*args) - try: - pyrexresult=pyrex_func(*args) - except: - print "pyrex function not runnable",func_name - raise - except: - print "Python Function not runnable",func_name - print traceback.print_exc() - else: - result[func_name]=(pyresult, pyrexresult) #or (pyresult,pyrexresult) - - return result - -def get_funcs_from_module(module): - info=module.__dict__.get('function_info',None) - if info: - funcs=compile_by_function_info(module,info) - else: - funcs=compile_by_inspecting(module) - return funcs - -if __name__=='__main__': - funcs=get_funcs_from_module(snippet) - import pprint - print len(funcs) - for f in funcs.keys(): - assert funcs[f][0]==funcs[f][1],"%s!=%s"%(funcs[f][0],funcs[f][1]) - print f, - pprint.pprint(funcs[f]) - - From mwh at codespeak.net Sat Jun 5 14:39:24 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 14:39:24 +0200 (MEST) Subject: [pypy-svn] r4959 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605123924.23A0C5BE07@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 14:39:23 2004 New Revision: 4959 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py Log: bug in int.__new__ Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py Sat Jun 5 14:39:23 2004 @@ -7,8 +7,8 @@ if w_base is None: w_base = space.w_None if w_value is None: - space.newint(0) - if w_base == space.w_None and not space.is_true(space.isinstance(w_value, space.w_str)): + w_obj = space.newint(0) + elif w_base == space.w_None and not space.is_true(space.isinstance(w_value, space.w_str)): w_obj = space.int(w_value) else: if w_base == space.w_None: From arigo at codespeak.net Sat Jun 5 14:46:46 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 14:46:46 +0200 (MEST) Subject: [pypy-svn] r4960 - in pypy/branch/src-newobjectmodel/pypy: interpreter objspace/std/test Message-ID: <20040605124646.D02655BE07@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 14:46:46 2004 New Revision: 4960 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py Log: Small fixes for test_dictobject... Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Sat Jun 5 14:46:46 2004 @@ -4,6 +4,7 @@ """ from pypy.interpreter.gateway import interp2app from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.error import OperationError class TypeDef: def __init__(self, __name, **rawdict): @@ -29,7 +30,7 @@ def descr_property_get(space, w_property, w_obj, w_ignored): # XXX HAAAAAAAAAAAACK (but possibly a good one) if w_obj == space.w_None and not space.is_true(space.is_(w_ignored, space.type(space.w_None))): - print w_property, w_obj, w_ignored + #print w_property, w_obj, w_ignored return w_property else: return space.unwrap(w_property).fget(space, w_obj) @@ -37,16 +38,16 @@ def descr_property_set(space, w_property, w_obj, w_value): fset = space.unwrap(w_property).fset if fset is None: - complains - else: - do_it + raise OperationError(space.w_AttributeError, + space.wrap("read-only attribute")) + fset(space, w_obj, w_value) def descr_property_del(space, w_property, w_obj): - fset = space.unwrap(w_property).fset - if fset is None: - complains - else: - do_it + fdel = space.unwrap(w_property).fdel + if fdel is None: + raise OperationError(space.w_AttributeError, + space.wrap("cannot delete attribute")) + fdel(space, w_obj) typedef = TypeDef("GetSetProperty", __get__ = interp2app(descr_property_get), Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py Sat Jun 5 14:46:46 2004 @@ -118,15 +118,15 @@ return [[w(a),w(b)] for a,b in lp] d = mydict() self.assertEqual_w(d, w({})) - args = w([[['a',2],[23,45]]]) + args = w(([['a',2],[23,45]],)) d = mydict(args) self.assertEqual_w(d, wd(deepwrap([['a',2],[23,45]]))) d = mydict(args, w({'a':33, 'b':44})) self.assertEqual_w(d, wd(deepwrap([['a',33],['b',44],[23,45]]))) d = mydict(w_kwds=w({'a':33, 'b':44})) self.assertEqual_w(d, wd(deepwrap([['a',33],['b',44]]))) - self.assertRaises_w(space.w_TypeError, mydict, w([23])) - self.assertRaises_w(space.w_ValueError, mydict, w([[[1,2,3]]])) + self.assertRaises_w(space.w_TypeError, mydict, w((23,))) + self.assertRaises_w(space.w_ValueError, mydict, w(([[1,2,3]],))) def test_dict_pop(self): space = self.space From mwh at codespeak.net Sat Jun 5 14:51:18 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 14:51:18 +0200 (MEST) Subject: [pypy-svn] r4961 - pypy/branch/src-newobjectmodel/pypy/objspace/std/test Message-ID: <20040605125118.838155C16B@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 14:51:17 2004 New Revision: 4961 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py Log: fix some screwy tests Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py Sat Jun 5 14:51:17 2004 @@ -134,21 +134,19 @@ wd = space.newdict def mydict(w_args=w(()), w_kwds=w({})): return space.call(space.w_dict, w_args, w_kwds) - def deepwrap(lp): - return [[w(a),w(b)] for a,b in lp] - d = mydict(w_kwds=w({1:2, 3:4})) - dd = mydict(w_kwds=w({1:2, 3:4})) # means d.copy() + d = mydict(w_kwds=w({"1":2, "3":4})) + dd = mydict(w_kwds=w({"1":2, "3":4})) # means d.copy() pop = space.getattr(dd, w("pop")) - result = space.call_function(pop, w(1)) + result = space.call_function(pop, w("1")) self.assertEqual_w(result, w(2)) self.assertEqual_w(space.len(dd), w(1)) - dd = mydict(w_kwds=w({1:2, 3:4})) # means d.copy() + dd = mydict(w_kwds=w({"1":2, "3":4})) # means d.copy() pop = space.getattr(dd, w("pop")) - result = space.call_function(pop, w(1), w(44)) + result = space.call_function(pop, w("1"), w(44)) self.assertEqual_w(result, w(2)) self.assertEqual_w(space.len(dd), w(1)) - result = space.call_function(pop, w(1), w(44)) + result = space.call_function(pop, w("1"), w(44)) self.assertEqual_w(result, w(44)) self.assertEqual_w(space.len(dd), w(1)) @@ -159,12 +157,12 @@ w = space.wrap def mydict(w_args=w(()), w_kwds=w({})): return space.call(space.w_dict, w_args, w_kwds) - d = mydict(w_kwds=w({1:2, 3:4})) + d = mydict(w_kwds=w({"1":2, "3":4})) get = space.getattr(d, w("get")) - self.assertEqual_w(space.call_function(get, w(1)), w(2)) - self.assertEqual_w(space.call_function(get, w(1), w(44)), w(2)) - self.assertEqual_w(space.call_function(get, w(33)), w(None)) - self.assertEqual_w(space.call_function(get, w(33), w(44)), w(44)) + self.assertEqual_w(space.call_function(get, w("1")), w(2)) + self.assertEqual_w(space.call_function(get, w("1"), w(44)), w(2)) + self.assertEqual_w(space.call_function(get, w("33")), w(None)) + self.assertEqual_w(space.call_function(get, w("33"), w(44)), w(44)) From arigo at codespeak.net Sat Jun 5 14:55:37 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 14:55:37 +0200 (MEST) Subject: [pypy-svn] r4962 - in pypy/branch/src-newobjectmodel/pypy/interpreter: . test Message-ID: <20040605125537.D62555C16D@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 14:55:37 2004 New Revision: 4962 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Log: Writable func_doc. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/function.py Sat Jun 5 14:55:37 2004 @@ -17,7 +17,7 @@ def __init__(self, space, code, w_globals=None, defs_w=[], closure=None, forcename=None): self.space = space self.name = forcename or code.co_name - self.doc = getattr(code, 'co_consts', (None,))[0] + self.w_doc = None # lazily read and wrapped from code.co_consts[0] self.code = code # Code instance self.w_func_globals = w_globals # the globals dictionary self.closure = closure # normally, list of Cell instances or None @@ -185,7 +185,22 @@ values_w = self.defs_w if not values_w: return space.w_None - return space.newtuple(values_w) + return space.newtuple(values_w) + + def fget_func_doc(space, w_self): + self = space.unwrap(w_self) + if self.w_doc is None: + doc = getattr(self.code, 'co_consts', (None,))[0] + self.w_doc = space.wrap(doc) + return self.w_doc + + def fset_func_doc(space, w_self, w_doc): + self = space.unwrap(w_self) + self.w_doc = w_doc + + def fdel_func_doc(space, w_self): + self = space.unwrap(w_self) + self.w_doc = space.w_None class Method(Wrappable): """A method is a function bound to a specific instance or class.""" Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/test/test_function.py Sat Jun 5 14:55:37 2004 @@ -30,6 +30,22 @@ self.assert_(f.__dict__ is f.func_dict) self.assert_(hasattr(f, '__class__')) + def test_write_doc(self): + def f(): "hello" + self.assertEquals(f.__doc__, 'hello') + f.__doc__ = 'good bye' + self.assertEquals(f.__doc__, 'good bye') + del f.__doc__ + self.assertEquals(f.__doc__, None) + + def test_write_func_doc(self): + def f(): "hello" + self.assertEquals(f.func_doc, 'hello') + f.func_doc = 'good bye' + self.assertEquals(f.func_doc, 'good bye') + del f.func_doc + self.assertEquals(f.func_doc, None) + class AppTestFunction(testit.AppTestCase): def test_simple_call(self): def func(arg1, arg2): Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/typedef.py Sat Jun 5 14:55:37 2004 @@ -121,16 +121,20 @@ __dict__ = attrproperty_w('w_dict'), ) +getset_func_doc = GetSetProperty(Function.fget_func_doc, + Function.fset_func_doc, + Function.fdel_func_doc) + Function.typedef = TypeDef("function", __call__ = interp2app(Function.descr_function_call.im_func), __get__ = interp2app(Function.descr_function_get.im_func), func_code = attrproperty('code'), - func_doc = attrproperty('doc'), + func_doc = getset_func_doc, func_name = attrproperty('name'), func_dict = attrproperty_w('w_func_dict'), func_defaults = GetSetProperty(Function.fget_func_defaults), func_globals = attrproperty_w('w_func_globals'), - __doc__ = attrproperty('doc'), + __doc__ = getset_func_doc, __name__ = attrproperty('name'), __dict__ = attrproperty_w('w_func_dict'), # XXX func_closure, etc.pp From hpk at codespeak.net Sat Jun 5 14:58:05 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 14:58:05 +0200 (MEST) Subject: [pypy-svn] r4963 - pypy/trunk/src/pypy/translator/test Message-ID: <20040605125805.BD9635C16D@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 14:58:05 2004 New Revision: 4963 Modified: pypy/trunk/src/pypy/translator/test/run_snippet.py Log: - default run mode (no arguments) is to run all snippets and only report - with cmdline args it will only run functions starting with the given prefixes Modified: pypy/trunk/src/pypy/translator/test/run_snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/run_snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/run_snippet.py Sat Jun 5 14:58:05 2004 @@ -40,10 +40,16 @@ compiled_function = self.translator.compile() return compiled_function -def collect_functions(module): +def collect_functions(module, specnamelist): l = [] - for name, value in vars(module).items(): - if name[0] != '_' and hasattr(value, 'func_code'): + for funcname, value in vars(module).items(): + if not hasattr(value, 'func_code'): + continue + for specname in specnamelist: + if funcname.startswith(specname): + l.append(value) + break + if not specnamelist: l.append(value) return l @@ -72,8 +78,8 @@ return format_str %(funccall, flow, ann, comp) if __name__=='__main__': - funcs = collect_functions(snippet) - funcs.insert(0, snippet._attrs) + specnamelist = sys.argv[1:] + funcs = collect_functions(snippet, specnamelist) results = [] print format_str %("functioncall", "flowed", "annotated", "compiled") for func in funcs: @@ -81,6 +87,9 @@ result = Result(func, argtypeslist) results.append(result) print repr_result(result) + if specnamelist and getattr(result, 'excinfo', None): + traceback.print_exception(*result.excinfo) + raise SystemExit, 1 for res in results: print repr_result(res) From mwh at codespeak.net Sat Jun 5 15:03:24 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 15:03:24 +0200 (MEST) Subject: [pypy-svn] r4964 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605130324.BB9F75C16D@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 15:03:24 2004 New Revision: 4964 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py Log: modernize slices Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/sliceobject.py Sat Jun 5 15:03:24 2004 @@ -19,24 +19,4 @@ registerimplementation(W_SliceObject) - -def getattr__Slice_ANY(space, w_slice, w_attr): - # XXX later - if space.is_true(space.eq(w_attr, space.wrap('start'))): - if w_slice.w_start is None: - return space.w_None - else: - return w_slice.w_start - if space.is_true(space.eq(w_attr, space.wrap('stop'))): - if w_slice.w_stop is None: - return space.w_None - else: - return w_slice.w_stop - if space.is_true(space.eq(w_attr, space.wrap('step'))): - if w_slice.w_step is None: - return space.w_None - else: - return w_slice.w_step - raise FailedToImplement(space.w_AttributeError) - register_all(vars()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/slicetype.py Sat Jun 5 15:03:24 2004 @@ -1,6 +1,7 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.objecttype import object_typedef from pypy.objspace.std.register_all import register_all +from pypy.interpreter.error import OperationError slice_indices = MultiMethod('indices', 2) @@ -90,7 +91,7 @@ w_start, w_stop = args_w elif len(args_w) == 3: w_start, w_stop, w_step = args_w - elif len(args) > 3: + elif len(args_w) > 3: raise OperationError(space.w_TypeError, space.wrap("slice() takes at most 3 arguments")) else: @@ -103,5 +104,8 @@ slice_typedef = StdTypeDef("slice", [object_typedef], __new__ = newmethod(descr__new__), + start = attrproperty_w('w_start'), + stop = attrproperty_w('w_stop'), + step = attrproperty_w('w_step'), ) slice_typedef.registermethods(globals()) From mwh at codespeak.net Sat Jun 5 15:11:11 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 15:11:11 +0200 (MEST) Subject: [pypy-svn] r4965 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605131111.152935C16D@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 15:11:10 2004 New Revision: 4965 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Log: support __bases__ better repr for tuples Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/tupleobject.py Sat Jun 5 15:11:10 2004 @@ -103,12 +103,16 @@ # No more items to compare -- compare sizes return space.newbool(len(items1) > len(items2)) -def repr__Tuple(space, w_tuple): - # XXX slimy! --mwh - return space.wrap(repr(space.unwrap(w_tuple))) +def app_repr__Tuple(t): + if len(t) == 1: + return "(" + repr(t[0]) + ",)" + else: + return "(" + ", ".join([repr(x) for x in t]) + ')' def hash__Tuple(space, w_tuple): # silly-ish, but _correct_, while lacking it would be WRONG return space.len(w_tuple) +from pypy.interpreter import gateway +gateway.importall(globals()) register_all(vars()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Sat Jun 5 15:11:10 2004 @@ -30,12 +30,15 @@ dictspec.append((space.wrap(key), w_value)) return space.newdict(dictspec) +def descr__bases(space, w_type): + return space.newtuple(w_type.bases_w) + # ____________________________________________________________ type_typedef = StdTypeDef("type", [object_typedef], __new__ = newmethod(descr__new__), __name__ = attrproperty('name'), - #__bases__ = XXX use newtuple + __bases__ = GetSetProperty(descr__bases), __dict__ = GetSetProperty(descr__dict__), __mro__ = GetSetProperty(descr_get__mro__), ) From mwh at codespeak.net Sat Jun 5 15:14:56 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 15:14:56 +0200 (MEST) Subject: [pypy-svn] r4966 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605131456.D02C25C16D@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 15:14:56 2004 New Revision: 4966 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py Log: grotty failure for int('0x2a') Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/inttype.py Sat Jun 5 15:14:56 2004 @@ -12,7 +12,7 @@ w_obj = space.int(w_value) else: if w_base == space.w_None: - base = 0 + base = -909 # don't blame us!! else: base = space.unwrap(w_base) # XXX write the logic for int("str", base) From anna at codespeak.net Sat Jun 5 15:22:53 2004 From: anna at codespeak.net (anna at codespeak.net) Date: Sat, 5 Jun 2004 15:22:53 +0200 (MEST) Subject: [pypy-svn] r4968 - pypy/trunk/doc Message-ID: <20040605132253.D435F5BE07@thoth.codespeak.net> Author: anna Date: Sat Jun 5 15:22:53 2004 New Revision: 4968 Modified: pypy/trunk/doc/index.txt Log: added project comparison links to doc index txtfile. note: this is the same file as in www/rawdoc/doc.txt, which needs to be turned into a useful form. I'm uploading it here so it can be viewed until rawdoc gets changed. Modified: pypy/trunk/doc/index.txt ============================================================================== --- pypy/trunk/doc/index.txt (original) +++ pypy/trunk/doc/index.txt Sat Jun 5 15:22:53 2004 @@ -52,7 +52,32 @@ * testdesign_: pypy is a test-driven development project.read here to find out more about how we're doing testing. + +Further reading +--------------- + +* An interesting thread on an HP tech report that may be proof the pypy is feasible_ . (We already knew that...) + +* An interesting thread on why VHLL rock_ . (We already knew that too.) +* A thread on Python in Scheme_ . + +* An intriguting project, FlashMob_ - creating an adhoc supercomputer. + +* A discussion on Python and lisp_ support + +* An interesting repository_ of papers by Xerox Parc members, with quite a few issues more or less relevant to PyPy. + +* A thread on the gnu lightning_ project."GNU lightning is a library that generates assembly language code at run-time; it is very fast, making it ideal for Just-In-Time compilers, +and it abstracts over the target CPU, as it exposes to the clients a standardized RISC instruction set inspired by the MIPS and SPARC chips." + +* A project to create a Low Level Virtual Machine (LLVM_) and a PyPy-LLVM_ discussion, and conversation_ between PyPy and LLVM. + +* A thread discussing the xhelix_ python C extension implementing Helix encryption and authentication, which may be interesting to use as a pypy performance test at some point. + +* A thread discussing comparison of PyPy-IronPython_ , and a paper for PyCon 2004: "IronPython_ is a new implementation of the Python language targeting the Common Language Runtime (CLR). It compiles python programs into bytecode (IL) that will run on either Microsoft's .NET or the Open Source Mono platform. IronPython includes an interactive interpreter and transparent on-the-fly compilation of source files just like standard Python. In addition, IronPython supports static compilation of Python code to produce static executables (.exe's) that can be run directly or static libraries (.dll's) that can be called from other CLR languages." + +* A comparison of Python and Pliant_ , an OS written in a python-like language. .. _architecture: http://codespeak.net/pypy/index.cgi?doc/architecture.html @@ -63,4 +88,18 @@ .. _coding-style: http://codespeak.net/pypy/index.cgi?doc/devel/coding-style.html .. _howtosvn: http://codespeak.net/pypy/index.cgi?doc/devel/howtosvn.html .. _optionaltool: http://codespeak.net/pypy/index.cgi?doc/devel/optionaltool.html -.. _testdesign: http://codespeak.net/pypy/index.cgi?doc/devel/testdesign.html \ No newline at end of file +.. _testdesign: http://codespeak.net/pypy/index.cgi?doc/devel/testdesign.html +.. _feasible: http://codespeak.net/pipermail/pypy-dev/2004q2/002619.html +.. _rock: http://codespeak.net/pipermail/pypy-dev/2004q1/002585.html +.. _Scheme: http://codespeak.net/pipermail/pypy-dev/2004q1/002586.html +.. _FlashMob: http://www.flashmobcomputing.org/ +.. _lisp: http://codespeak.net/pipermail/pypy-dev/2003q4/002318.html +.. _repository: http://www2.parc.com/csl/groups/sda/publications.shtml +.. _lightning: http://codespeak.net/pipermail/pypy-dev/2003q4/002321.html +.. _LLVM: http://llvm.cs.uiuc.edu/ +.. _PyPy-LLVM: http://codespeak.net/pipermail/pypy-dev/2003q4/002398.html +.. _conversation: http://codespeak.net/pipermail/pypy-dev/2003q4/002411.html +.. _xhelix: http://codespeak.net/pipermail/pypy-dev/2003q4/002437.html +.. _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 From anna at codespeak.net Sat Jun 5 15:31:28 2004 From: anna at codespeak.net (anna at codespeak.net) Date: Sat, 5 Jun 2004 15:31:28 +0200 (MEST) Subject: [pypy-svn] r4969 - pypy/trunk/doc Message-ID: <20040605133128.D26525BE07@thoth.codespeak.net> Author: anna Date: Sat Jun 5 15:31:28 2004 New Revision: 4969 Modified: pypy/trunk/doc/index.txt Log: corrected the index.txt file so docutils and ReST wouldn't complain Modified: pypy/trunk/doc/index.txt ============================================================================== --- pypy/trunk/doc/index.txt (original) +++ pypy/trunk/doc/index.txt Sat Jun 5 15:31:28 2004 @@ -68,8 +68,7 @@ * An interesting repository_ of papers by Xerox Parc members, with quite a few issues more or less relevant to PyPy. -* A thread on the gnu lightning_ project."GNU lightning is a library that generates assembly language code at run-time; it is very fast, making it ideal for Just-In-Time compilers, -and it abstracts over the target CPU, as it exposes to the clients a standardized RISC instruction set inspired by the MIPS and SPARC chips." +* A thread on the gnu lightning_ project."GNU lightning is a library that generates assembly language code at run-time; it is very fast, making it ideal for Just-In-Time compilers, and it abstracts over the target CPU, as it exposes to the clients a standardized RISC instruction set inspired by the MIPS and SPARC chips." * A project to create a Low Level Virtual Machine (LLVM_) and a PyPy-LLVM_ discussion, and conversation_ between PyPy and LLVM. From mwh at codespeak.net Sat Jun 5 15:32:29 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 15:32:29 +0200 (MEST) Subject: [pypy-svn] r4970 - pypy/branch/src-newobjectmodel/pypy/module Message-ID: <20040605133229.5040A5C16D@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 15:32:28 2004 New Revision: 4970 Modified: pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py Log: fixes for super(), callable() Modified: pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py (original) +++ pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py Sat Jun 5 15:32:28 2004 @@ -295,10 +295,11 @@ return False def callable(ob): - # XXX remove 't is type' when we have proper types - # that make this check no longer needed - t = type(ob) - return t is type or hasattr(t, '__call__') + for c in type(ob).__mro__: + if '__call__' in c.__dict__: + return True + else: + return False def dir(*args): """dir([object]) -> list of strings @@ -561,14 +562,12 @@ # Note: mro is an iterator, so the second loop # picks up where the first one left off! for cls in mro: - try: - # XXX - # XXX build-in classes have no __dict__ currently! - # XXX - x = getattr(cls, attr) - except AttributeError: + try: + x = cls.__dict__[attr] + except KeyError: continue - x = _pypy_get(x, self.__self__) # XXX replace with x.__get__ + if hasattr(x, '__get__'): + x = x.__get__(self.__self__, type(self.__self__)) return x raise AttributeError, attr From mwh at codespeak.net Sat Jun 5 15:44:00 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 15:44:00 +0200 (MEST) Subject: [pypy-svn] r4971 - pypy/branch/src-newobjectmodel/pypy/translator/test Message-ID: <20040605134400.65E025BE07@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 15:43:59 2004 New Revision: 4971 Modified: pypy/branch/src-newobjectmodel/pypy/translator/test/test_cltrans.py Log: require flowobjspace for test_cltrans Modified: pypy/branch/src-newobjectmodel/pypy/translator/test/test_cltrans.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/translator/test/test_cltrans.py (original) +++ pypy/branch/src-newobjectmodel/pypy/translator/test/test_cltrans.py Sat Jun 5 15:43:59 2004 @@ -42,6 +42,7 @@ class GenCLTestCase(testit.IntTestCase): def setUp(self): + self.space = testit.objspace('flow') if not global_cl: raise (testit.TestSkip, "Common Lisp neither configured nor detected.") From mwh at codespeak.net Sat Jun 5 15:45:40 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 15:45:40 +0200 (MEST) Subject: [pypy-svn] r4972 - in pypy/branch/src-newobjectmodel/pypy: interpreter module objspace/std Message-ID: <20040605134540.DDBB85C16E@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 15:45:40 2004 New Revision: 4972 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: add fromkeys() this requires jiggering with how the builtins are built... Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/baseobjspace.py Sat Jun 5 15:45:40 2004 @@ -23,11 +23,15 @@ # sets all the internal descriptors self.initialize() - def make_builtins(self): + def make_builtins(self, for_builtins): # initializing builtins may require creating a frame which in # turn already accesses space.w_builtins, provide a dummy one ... self.w_builtins = self.newdict([]) + # insert stuff into the newly-made builtins + for key, w_value in for_builtins.items(): + self.setitem(self.w_builtins, self.wrap(key), w_value) + assert not hasattr(self, 'builtin') if not hasattr(self, 'sys'): self.make_sys() Modified: pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py (original) +++ pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py Sat Jun 5 15:45:40 2004 @@ -537,6 +537,15 @@ return self.f(klass, *args) return newfunc +def _fromkeys(cls, seq, value=None): + r = cls() + for s in seq: + r[s] = value + return r + +dict.fromkeys = classmethod(_fromkeys) +del _fromkeys + # super is a modified version from Guido's tutorial # http://www.python.org/2.2.3/descrintro.html Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 15:45:40 2004 @@ -168,11 +168,7 @@ # exceptions for_builtins.update(self.clone_exception_hierarchy()) - self.make_builtins() - - # insert stuff into the newly-made builtins - for key, w_value in for_builtins.items(): - self.setitem(self.w_builtins, self.wrap(key), w_value) + self.make_builtins(for_builtins) def gettypeobject(self, typedef): # types_w maps each StdTypeDef instance to its From mwh at codespeak.net Sat Jun 5 15:55:43 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 15:55:43 +0200 (MEST) Subject: [pypy-svn] r4973 - in pypy/branch/src-newobjectmodel/pypy: module objspace objspace/test Message-ID: <20040605135543.9D3F05C16D@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 15:55:43 2004 New Revision: 4973 Modified: pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py pypy/branch/src-newobjectmodel/pypy/objspace/test/test_traceobjspace.py pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: minor fixes to/for trivial object space (no promises!) fix test_traceobjspace Modified: pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py (original) +++ pypy/branch/src-newobjectmodel/pypy/module/__builtin__module.py Sat Jun 5 15:55:43 2004 @@ -537,14 +537,16 @@ return self.f(klass, *args) return newfunc -def _fromkeys(cls, seq, value=None): - r = cls() - for s in seq: - r[s] = value - return r +if not hasattr(dict, 'fromkeys'): + def _fromkeys(cls, seq, value=None): + r = cls() + for s in seq: + r[s] = value + return r -dict.fromkeys = classmethod(_fromkeys) -del _fromkeys + dict.fromkeys = classmethod(_fromkeys) + + del _fromkeys # super is a modified version from Guido's tutorial Modified: pypy/branch/src-newobjectmodel/pypy/objspace/test/test_traceobjspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/test/test_traceobjspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/test/test_traceobjspace.py Sat Jun 5 15:55:43 2004 @@ -17,7 +17,7 @@ func_gw = app2interp(app_func) func = func_gw.get_function(tspace) tspace.settrace() - func() + self.space.call_function(self.space.wrap(func)) res = tspace.getresult() return res Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Sat Jun 5 15:55:43 2004 @@ -114,11 +114,7 @@ setattr(self, 'w_' + c.__name__, c) newstuff[c.__name__] = c newstuff.update(self.clone_exception_hierarchy()) - self.make_builtins() - # insert these into the newly-made builtins - for key, w_value in newstuff.items(): - self.w_builtins.setdefault(key, w_value) - # I'm tired of wrapping correctly here -- armin + self.make_builtins(newstuff) # general stuff def wrap(self, x): From hpk at codespeak.net Sat Jun 5 16:08:33 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 16:08:33 +0200 (MEST) Subject: [pypy-svn] r4974 - pypy/trunk/src/pypy/translator/test Message-ID: <20040605140833.02FF15C16D@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 16:08:33 2004 New Revision: 4974 Modified: pypy/trunk/src/pypy/translator/test/run_snippet.py pypy/trunk/src/pypy/translator/test/snippet.py Log: - run all combinations of argument types - small fixes Modified: pypy/trunk/src/pypy/translator/test/run_snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/run_snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/run_snippet.py Sat Jun 5 16:08:33 2004 @@ -52,16 +52,25 @@ if not specnamelist: l.append(value) return l - + + +def combine(lists): + if not lists: + yield [] + else: + head = lists[0] + if not isinstance(head, tuple): + head = (head,) + tail = lists[1:] + for item in head: + for com in combine(tail): + yield [item] + com + def get_arg_types(func): # func_defaults e.g.: ([int, float], [str, int], int) if func.func_defaults: - argstypelist = [] - for spec in func.func_defaults: - if isinstance(spec, tuple): - spec = spec[0] # use the first type only for the tests - argstypelist.append(spec) - yield argstypelist + for argtypeslist in combine(func.func_defaults): + yield argtypeslist else: yield [] @@ -84,6 +93,7 @@ print format_str %("functioncall", "flowed", "annotated", "compiled") for func in funcs: for argtypeslist in get_arg_types(func): + #print "trying %s %s" %(func, argtypeslist) result = Result(func, argtypeslist) results.append(result) print repr_result(result) @@ -91,7 +101,7 @@ traceback.print_exception(*result.excinfo) raise SystemExit, 1 - for res in results: - print repr_result(res) + #for res in results: + # print repr_result(res) Modified: pypy/trunk/src/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/snippet.py Sat Jun 5 16:08:33 2004 @@ -26,7 +26,7 @@ # the possible types that can be passed to # the specific snippet. numtype = (int, float, ) -anytype = (int, float, str, ) +anytype = (int, float, str) seqtype = (list, tuple) def if_then_else(cond=anytype, x=anytype, y=anytype): From hpk at codespeak.net Sat Jun 5 16:09:01 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 16:09:01 +0200 (MEST) Subject: [pypy-svn] r4975 - pypy/trunk/src/pypy/translator/tool Message-ID: <20040605140901.D666D5C170@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 16:09:01 2004 New Revision: 4975 Modified: pypy/trunk/src/pypy/translator/tool/buildpyxmodule.py Log: fix the loop that looks for a free filename ... Modified: pypy/trunk/src/pypy/translator/tool/buildpyxmodule.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/buildpyxmodule.py (original) +++ pypy/trunk/src/pypy/translator/tool/buildpyxmodule.py Sat Jun 5 16:09:01 2004 @@ -17,6 +17,7 @@ i = 0 while pyxfile.check(): pyxfile = pyxfile.new(basename='%s%d.pyx' % (name, i)) + i+=1 pyxfile.write(string) if debug: print "made pyxfile", pyxfile make_c_from_pyxfile(pyxfile) From anna at codespeak.net Sat Jun 5 16:35:45 2004 From: anna at codespeak.net (anna at codespeak.net) Date: Sat, 5 Jun 2004 16:35:45 +0200 (MEST) Subject: [pypy-svn] r4977 - pypy/trunk/doc Message-ID: <20040605143545.65F165BE07@thoth.codespeak.net> Author: anna Date: Sat Jun 5 16:35:44 2004 New Revision: 4977 Modified: pypy/trunk/doc/index.txt Log: added the recently modified page to the doc index page Modified: pypy/trunk/doc/index.txt ============================================================================== --- pypy/trunk/doc/index.txt (original) +++ pypy/trunk/doc/index.txt Sat Jun 5 16:35:44 2004 @@ -14,6 +14,9 @@ * oscon2003-paper_: presentation to OSCON on what pypy is about and why you should care + * recent_ commitments: + to see recently modified files + Getting Started --------------- @@ -102,3 +105,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 +.. _recent: http://codespeak.net/pypy/index.cgi?doc/recent \ No newline at end of file From arigo at codespeak.net Sat Jun 5 16:41:33 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 16:41:33 +0200 (MEST) Subject: [pypy-svn] r4978 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605144133.1A9315BE07@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 16:41:32 2004 New Revision: 4978 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/mro.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Log: The C3 algorithm to compute the Method Resolution Order now integrated. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/mro.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/mro.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/mro.py Sat Jun 5 16:41:32 2004 @@ -3,68 +3,55 @@ """ -def MRO(cls): - - def register(cls): - try: - blocklist = blocking[cls] - except KeyError: - blocklist = blocking[cls] = [0] - prevlist = blocklist - for base in cls.__bases__: - prevlist.append(base) - prevlist = register(base) - blocklist[0] += 1 - return blocklist +def mro(cls): order = [] - blocking = {} - register(cls) - - unblock = [cls] - while unblock: - cls = unblock.pop() - blocklist = blocking[cls] - assert blocklist[0] > 0 - blocklist[0] -= 1 - if blocklist[0] == 0: - order.append(cls) - unblock += blocklist[:0:-1] - - if len(order) < len(blocking): - mro_error(blocking) + orderlists = [mro(base) for base in cls.__bases__] + orderlists.append([cls] + list(cls.__bases__)) + while orderlists: + for candidatelist in orderlists: + candidate = candidatelist[0] + if blockinglist(candidate, orderlists) is None: + break # good candidate + else: + mro_error(orderlists) # no candidate found + assert candidate not in order + order.append(candidate) + for i in range(len(orderlists)-1, -1, -1): + if orderlists[i][0] == candidate: + del orderlists[i][0] + if len(orderlists[i]) == 0: + del orderlists[i] return order - -def mro_error(blocking): - # look for a cycle - - def find_cycle(cls): - path.append(cls) - blocklist = blocking[cls] # raise KeyError when we complete the path - if blocklist[0] > 0: - del blocking[cls] - for cls2 in blocklist[1:]: - find_cycle(cls2) - blocking[cls] = blocklist - del path[-1] - - #import pprint; pprint.pprint(blocking) - path = [] - try: - for cls in blocking.keys(): - find_cycle(cls) - except KeyError: - i = path.index(path[-1]) - names = [cls.__name__ for cls in path[i:]] - raise TypeError, "Cycle among base classes: " + ' < '.join(names) - else: - # should not occur - raise TypeError, "Cannot create a consistent method resolution order (MRO)" +def blockinglist(candidate, orderlists): + for lst in orderlists: + if candidate in lst[1:]: + return lst + return None # good candidate + +def mro_error(orderlists): + cycle = [] + candidate = orderlists[0][0] + while candidate not in cycle: + cycle.append(candidate) + nextblockinglist = blockinglist(candidate, orderlists) + candidate = nextblockinglist[0] + del cycle[:cycle.index(candidate)] + cycle.append(candidate) + cycle.reverse() + names = [cls.__name__ for cls in cycle] + raise TypeError, "Cycle among base classes: " + ' < '.join(names) + + +def mronames(cls): + names = [cls.__name__ for cls in mro(cls)] + return names if __name__ == '__main__': class ex_9: + #O = object class O: pass class A(O): pass class B(O): pass @@ -76,5 +63,11 @@ class K2(D,F,B,E): pass class K3(D,A): pass class Z(K1,K2,F,K3): pass + class ZM(K1,K2,K3): pass + #print ZM.__mro__ - print MRO(ex_9.Z) + print 'K1:', mronames(ex_9.K1) + print 'K2:', mronames(ex_9.K2) + print 'K3:', mronames(ex_9.K3) + print mronames(ex_9.ZM) + print mronames(ex_9.Z) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typeobject.py Sat Jun 5 16:41:32 2004 @@ -10,6 +10,7 @@ w_self.bases_w = bases_w w_self.dict_w = dict_w w_self.needs_new_dict = False + w_self.mro_w = compute_C3_mro(w_self) # XXX call type(w_self).mro() if overridetypedef is not None: w_self.instancetypedef = overridetypedef else: @@ -38,23 +39,13 @@ w_self.dict_w['__dict__'] = space.wrap(attrproperty_w('w__dict__')) elif nd: w_self.needs_new_dict = True - - - - def getmro(w_self): - # XXX this is something that works not too bad right now - # XXX do the complete mro thing later (see mro.py) - mro = [w_self] - for w_parent in w_self.bases_w: - mro += w_parent.getmro() - return mro def lookup(w_self, key): # note that this doesn't call __get__ on the result at all # XXX this should probably also return the (parent) class in which # the attribute was found space = w_self.space - for w_class in w_self.getmro(): + for w_class in w_self.mro_w: try: return w_class.dict_w[key] except KeyError: @@ -103,7 +94,7 @@ return w_newobject def issubtype__Type_Type(space, w_type1, w_type2): - return space.newbool(w_type2 in w_type1.getmro()) + return space.newbool(w_type2 in w_type1.mro_w) def repr__Type(space, w_obj): return space.wrap("" % w_obj.name) # XXX remove 'pypy' @@ -133,5 +124,53 @@ # XXX __delattr__ # XXX __hash__ ?? +# ____________________________________________________________ + +def compute_C3_mro(cls): + order = [] + orderlists = [list(base.mro_w) for base in cls.bases_w] + orderlists.append([cls] + cls.bases_w) + while orderlists: + for candidatelist in orderlists: + candidate = candidatelist[0] + if mro_blockinglist(candidate, orderlists) is None: + break # good candidate + else: + mro_error(orderlists) # no candidate found + assert candidate not in order + order.append(candidate) + for i in range(len(orderlists)-1, -1, -1): + if orderlists[i][0] == candidate: + del orderlists[i][0] + if len(orderlists[i]) == 0: + del orderlists[i] + return order + +def mro_blockinglist(candidate, orderlists): + for lst in orderlists: + if candidate in lst[1:]: + return lst + return None # good candidate + +def mro_error(orderlists): + cycle = [] + candidate = orderlists[-1][0] + space = candidate.space + if candidate in orderlists[-1][1:]: + # explicit error message for this specific case + raise OperationError(space.w_TypeError, + space.wrap("duplicate base class " + candidate.name)) + while candidate not in cycle: + cycle.append(candidate) + nextblockinglist = mro_blockinglist(candidate, orderlists) + candidate = nextblockinglist[0] + del cycle[:cycle.index(candidate)] + cycle.append(candidate) + cycle.reverse() + names = [cls.name for cls in cycle] + raise OperationError(space.w_TypeError, + space.wrap("cycle among base classes: " + ' < '.join(names))) + +# ____________________________________________________________ register_all(vars()) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/typetype.py Sat Jun 5 16:41:32 2004 @@ -21,7 +21,7 @@ def descr_get__mro__(space, w_type): # XXX this should be inside typeobject.py - return space.newtuple(w_type.getmro()) + return space.newtuple(w_type.mro_w) def descr__dict__(space, w_type): # XXX should return a From anna at codespeak.net Sat Jun 5 16:43:31 2004 From: anna at codespeak.net (anna at codespeak.net) Date: Sat, 5 Jun 2004 16:43:31 +0200 (MEST) Subject: [pypy-svn] r4979 - pypy/trunk/doc Message-ID: <20040605144331.3962B5BE15@thoth.codespeak.net> Author: anna Date: Sat Jun 5 16:43:30 2004 New Revision: 4979 Modified: pypy/trunk/doc/index.txt Log: minor change to doc index page Modified: pypy/trunk/doc/index.txt ============================================================================== --- pypy/trunk/doc/index.txt (original) +++ pypy/trunk/doc/index.txt Sat Jun 5 16:43:30 2004 @@ -1,7 +1,7 @@ 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. +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. Overview -------- @@ -14,8 +14,6 @@ * oscon2003-paper_: presentation to OSCON on what pypy is about and why you should care - * recent_ commitments: - to see recently modified files Getting Started --------------- @@ -105,4 +103,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 -.. _recent: http://codespeak.net/pypy/index.cgi?doc/recent \ No newline at end of file +.. _recently-modified: http://codespeak.net/pypy/index.cgi?doc/recent \ No newline at end of file From hpk at codespeak.net Sat Jun 5 17:18:26 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 17:18:26 +0200 (MEST) Subject: [pypy-svn] r4980 - pypy/branch/src-newobjectmodel/pypy Message-ID: <20040605151826.B72485BE07@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 17:18:26 2004 New Revision: 4980 Modified: pypy/branch/src-newobjectmodel/pypy/TODO Log: just discovered that traceobjspace does not really catch all operations ... added a TODO item ... Modified: pypy/branch/src-newobjectmodel/pypy/TODO ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/TODO (original) +++ pypy/branch/src-newobjectmodel/pypy/TODO Sat Jun 5 17:18:26 2004 @@ -46,3 +46,7 @@ * add web server thread (!) that allows inspection of e.g. app-level tracebacks (and stop clogging the user's terminal with them). + +* improve traceobjectspace! currently it only catches + calls from outside the space into the space but not + the ones where the space calls operations on itself! From arigo at codespeak.net Sat Jun 5 17:46:05 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 17:46:05 +0200 (MEST) Subject: [pypy-svn] r4981 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040605154605.639065BE15@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 17:46:04 2004 New Revision: 4981 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py Log: Interactive console improvements. Ctrl-C gives you a CPython prompt to play with PyPy at interpreter-level. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py Sat Jun 5 17:46:04 2004 @@ -18,15 +18,26 @@ def interact(self, banner=None): if banner is None: - banner = "Python %s in pypy\n%s / %s" % ( - sys.version, self.__class__.__name__, - self.space.__class__.__name__) + #banner = "Python %s in pypy\n%s / %s" % ( + # sys.version, self.__class__.__name__, + # self.space.__class__.__name__) + banner = "PyPy in %s on top of Python %s" % ( + self.space.__class__.__name__, sys.version.split()[0]) 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) + try: + return code.InteractiveConsole.raw_input(self, prompt[0] + prompt) + except KeyboardInterrupt: + # fires into an interpreter-level console + print + banner = ("Python %s on %s\n" % (sys.version, sys.platform) + + "*** Entering interpreter-level console ***") + code.interact(banner=banner, local=self.__dict__) + print '*** Leaving interpreter-level console ***' + raise def runcode(self, code): # 'code' is a CPython code object From arigo at codespeak.net Sat Jun 5 17:49:47 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 17:49:47 +0200 (MEST) Subject: [pypy-svn] r4982 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040605154947.852855BE16@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 17:49:46 2004 New Revision: 4982 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py Log: Safer this way. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py Sat Jun 5 17:49:46 2004 @@ -35,7 +35,7 @@ print banner = ("Python %s on %s\n" % (sys.version, sys.platform) + "*** Entering interpreter-level console ***") - code.interact(banner=banner, local=self.__dict__) + code.interact(banner=banner, local=self.__dict__.copy()) print '*** Leaving interpreter-level console ***' raise From mwh at codespeak.net Sat Jun 5 17:51:08 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 5 Jun 2004 17:51:08 +0200 (MEST) Subject: [pypy-svn] r4983 - in pypy/branch/src-newobjectmodel/pypy/objspace/std: . test Message-ID: <20040605155108.74E405BE17@thoth.codespeak.net> Author: mwh Date: Sat Jun 5 17:51:07 2004 New Revision: 4983 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_cpythonobject.py Log: fixes to hash() -- probably makes things even slower, sorry (but as a bonus, actually correct!) also, comment out hopelessly optimistic test in test_cpythonobject Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 17:51:07 2004 @@ -336,6 +336,28 @@ return not not w_obj.non_empties() else: return DescrOperation.is_true(self, w_obj) + + def hash(space, w_obj): + import cpythonobject + if isinstance(w_obj, cpythonobject.W_CPythonObject): + try: + return space.newint(hash(w_obj.cpyobj)) + except: + 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) # add all regular multimethods to StdObjSpace for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_cpythonobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_cpythonobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_cpythonobject.py Sat Jun 5 17:51:07 2004 @@ -30,7 +30,7 @@ def test_binary(self): w1 = self.space.wrap(self.stuff) for op, w_arg, expected in [ - ('getattr', self.space.wrap('count'), self.stuff.count), +# ('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])), ]: From pedronis at codespeak.net Sat Jun 5 17:58:52 2004 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 5 Jun 2004 17:58:52 +0200 (MEST) Subject: [pypy-svn] r4984 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605155852.E4AA85BE16@thoth.codespeak.net> Author: pedronis Date: Sat Jun 5 17:58:52 2004 New Revision: 4984 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py Log: comment about the code in cpython that is obsolete and should be carefully removed. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/cpythonobject.py Sat Jun 5 17:58:52 2004 @@ -60,6 +60,23 @@ 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() From arigo at codespeak.net Sat Jun 5 18:06:34 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 18:06:34 +0200 (MEST) Subject: [pypy-svn] r4985 - pypy/branch/src-newobjectmodel/pypy/interpreter Message-ID: <20040605160634.621665BE16@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 18:06:33 2004 New Revision: 4985 Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py Log: Provide the app-level variables with a 'w_' prefix in the interp-level console. Modified: pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py (original) +++ pypy/branch/src-newobjectmodel/pypy/interpreter/interactive.py Sat Jun 5 18:06:33 2004 @@ -35,7 +35,11 @@ print banner = ("Python %s on %s\n" % (sys.version, sys.platform) + "*** Entering interpreter-level console ***") - code.interact(banner=banner, local=self.__dict__.copy()) + local = self.__dict__.copy() + for w_name in self.space.unpackiterable(self.w_globals): + local['w_' + self.space.unwrap(w_name)] = ( + self.space.getitem(self.w_globals, w_name)) + code.interact(banner=banner, local=local) print '*** Leaving interpreter-level console ***' raise From hpk at codespeak.net Sat Jun 5 20:01:35 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 5 Jun 2004 20:01:35 +0200 (MEST) Subject: [pypy-svn] r4986 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040605180135.265445BE07@thoth.codespeak.net> Author: hpk Date: Sat Jun 5 20:01:34 2004 New Revision: 4986 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Log: Forgot to import OperationError there. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Sat Jun 5 20:01:34 2004 @@ -1,4 +1,5 @@ from pypy.interpreter import eval, function, gateway +from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import attrproperty, attrproperty_w from pypy.objspace.std.multimethod import MultiMethod, FailedToImplement From arigo at codespeak.net Sat Jun 5 20:54:04 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 20:54:04 +0200 (MEST) Subject: [pypy-svn] r4987 - in pypy/branch/src-newobjectmodel/pypy: objspace/std tool Message-ID: <20040605185404.0E8CE5BE07@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 20:54:04 2004 New Revision: 4987 Added: pypy/branch/src-newobjectmodel/pypy/tool/stdprofile.py Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Log: Performance tricks. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sat Jun 5 20:54:04 2004 @@ -55,20 +55,7 @@ from stringtype import str_typedef from typetype import type_typedef from slicetype import slice_typedef - # 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. - import objectobject - import boolobject - import intobject - import floatobject - import tupleobject - import listobject - import dictobject - import stringobject - import typeobject - import sliceobject - return [value for key, value in result.__dict__.items() + return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look def clone_exception_hierarchy(self): @@ -138,6 +125,39 @@ return done def initialize(self): + # 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. + import objectobject + import boolobject + import intobject + import floatobject + import tupleobject + import listobject + import dictobject + import stringobject + import typeobject + import sliceobject + 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 + global W_CPythonObject, W_BuiltinFunctionObject + W_ObjectObject = objectobject.W_ObjectObject + W_BoolObject = boolobject.W_BoolObject + W_IntObject = intobject.W_IntObject + W_FloatObject = floatobject.W_FloatObject + W_TupleObject = tupleobject.W_TupleObject + W_ListObject = listobject.W_ListObject + W_DictObject = dictobject.W_DictObject + W_StringObject = stringobject.W_StringObject + W_TypeObject = typeobject.W_TypeObject + W_SliceObject = sliceobject.W_SliceObject + W_CPythonObject = cpythonobject.W_CPythonObject + W_BuiltinFunctionObject = cpythonobject.W_BuiltinFunctionObject + # end of hacks + from noneobject import W_NoneObject from boolobject import W_BoolObject @@ -192,65 +212,52 @@ if isinstance(x, int): if isinstance(bool, type) and isinstance(x, bool): return self.newbool(x) - import intobject - return intobject.W_IntObject(self, x) + return W_IntObject(self, x) if isinstance(x, str): - import stringobject - return stringobject.W_StringObject(self, x) + return W_StringObject(self, x) if isinstance(x, dict): items_w = [(self.wrap(k), self.wrap(v)) for (k, v) in x.iteritems()] - import dictobject - return dictobject.W_DictObject(self, items_w) + return W_DictObject(self, items_w) if isinstance(x, float): - import floatobject - return floatobject.W_FloatObject(self, x) + return W_FloatObject(self, x) if isinstance(x, tuple): wrappeditems = [self.wrap(item) for item in x] - import tupleobject - return tupleobject.W_TupleObject(self, wrappeditems) + return W_TupleObject(self, wrappeditems) if isinstance(x, list): wrappeditems = [self.wrap(item) for item in x] - import listobject - return listobject.W_ListObject(self, wrappeditems) + return W_ListObject(self, wrappeditems) if isinstance(x, Wrappable): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result - import cpythonobject SlotWrapperType = type(type(None).__repr__) if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): - return cpythonobject.W_BuiltinFunctionObject(self, x) + return W_BuiltinFunctionObject(self, x) #print "cpython wrapping %r (%s)" % (x, type(x)) #if hasattr(x, '__bases__'): # print "cpython wrapping a class %r (%s)" % (x, type(x)) #raise TypeError, "cannot wrap classes" - return cpythonobject.W_CPythonObject(self, x) + return W_CPythonObject(self, x) def newint(self, int_w): - import intobject - return intobject.W_IntObject(self, int_w) + return W_IntObject(self, int_w) def newfloat(self, int_w): - import floatobject - return floatobject.W_FloatObject(self, int_w) + return W_FloatObject(self, int_w) def newtuple(self, list_w): assert isinstance(list_w, list) - import tupleobject - return tupleobject.W_TupleObject(self, list_w) + return W_TupleObject(self, list_w) def newlist(self, list_w): - import listobject - return listobject.W_ListObject(self, list_w) + return W_ListObject(self, list_w) def newdict(self, list_pairs_w): - import dictobject - return dictobject.W_DictObject(self, list_pairs_w) + return W_DictObject(self, list_pairs_w) def newslice(self, w_start, w_end, w_step): # w_step may be a real None - import sliceobject - return sliceobject.W_SliceObject(self, w_start, w_end, w_step) + return W_SliceObject(self, w_start, w_end, w_step) def newstring(self, chars_w): try: @@ -261,11 +268,9 @@ except ValueError: # chr(out-of-range) raise OperationError(self.w_ValueError, self.wrap("character code not in range(256)")) - import stringobject - return stringobject.W_StringObject(self, ''.join(chars)) + return W_StringObject(self, ''.join(chars)) def type(self, w_obj): - from pypy.objspace.std.cpythonobject import W_CPythonObject if isinstance(w_obj, W_CPythonObject): #raise TypeError, str(w_obj.cpyobj) return self.wrap(type(w_obj.cpyobj)) @@ -276,7 +281,6 @@ return self.gettypeobject(w_obj.typedef) def lookup(self, w_obj, name): - from pypy.objspace.std.cpythonobject import W_CPythonObject if not isinstance(w_obj, W_CPythonObject): # usual case w_type = self.type(w_obj) @@ -289,8 +293,7 @@ return None def unpacktuple(self, w_tuple, expected_length=None): - import tupleobject - assert isinstance(w_tuple, tupleobject.W_TupleObject) + assert isinstance(w_tuple, W_TupleObject) t = w_tuple.wrappeditems if expected_length is not None and expected_length != len(t): raise ValueError, "got a tuple of length %d instead of %d" % ( @@ -321,7 +324,6 @@ # if w_one is w_two: return self.newbool(1) - from cpythonobject import W_CPythonObject if isinstance(w_one, W_CPythonObject): if isinstance(w_two, W_CPythonObject): if w_one.cpyobj is w_two.cpyobj: @@ -331,18 +333,17 @@ def is_true(self, w_obj): # XXX don't look! - from dictobject import W_DictObject if isinstance(w_obj, W_DictObject): return not not w_obj.non_empties() else: return DescrOperation.is_true(self, w_obj) def hash(space, w_obj): - import cpythonobject - if isinstance(w_obj, cpythonobject.W_CPythonObject): + 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 Added: pypy/branch/src-newobjectmodel/pypy/tool/stdprofile.py ============================================================================== --- (empty file) +++ pypy/branch/src-newobjectmodel/pypy/tool/stdprofile.py Sat Jun 5 20:54:04 2004 @@ -0,0 +1,22 @@ +#! /usr/bin/env python + +import hotshot, os +from pypy.objspace.std import StdObjSpace + +try: + os.unlink('profile.log') +except: + pass + +p = hotshot.Profile('profile.log') +p.run('StdObjSpace()') +p.close() + +print 'loading...' + +import hotshot.stats +p = hotshot.stats.load('profile.log') +p.strip_dirs() +p.sort_stats('time', 'calls') +p.print_stats(20) + From arigo at codespeak.net Sat Jun 5 21:03:42 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 5 Jun 2004 21:03:42 +0200 (MEST) Subject: [pypy-svn] r4988 - in pypy/branch/src-newobjectmodel/pypy: objspace/std tool Message-ID: <20040605190342.ADF8B5BE15@thoth.codespeak.net> Author: arigo Date: Sat Jun 5 21:03:42 2004 New Revision: 4988 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py pypy/branch/src-newobjectmodel/pypy/tool/stdprofile.py Log: More performance hacks. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py Sat Jun 5 21:03:42 2004 @@ -752,88 +752,117 @@ return W_IntObject(space, hash(space.unwrap(w_str))) -EQ = 1 -LE = 2 -GE = 3 -GT = 4 -LT = 5 -NE = 6 - - -def string_richcompare(space, w_str1, w_str2, op): - u = space.unwrap - str1 = u(w_str1) - str2 = u(w_str2) - - if space.is_true(space.is_(w_str1, w_str2)): - if op == EQ or op == LE or op == GE: - return space.w_True - elif op == GT or op == LT or op == NE: - return space.w_False - if 0: - pass - else: - if op == EQ: - if len(str1) == len(str2): - for i in range(len(str1)): - if ord(str1[i]) != ord(str2[i]): - return space.w_False - return space.w_True - else: - return space.w_False - else: - if len(str1) > len(str2): - min_len = len(str2) - else: - min_len = len(str1) - - c = 0 - idx = 0 - if (min_len > 0): - while (c == 0) and (idx < min_len): - c = ord(str1[idx]) - ord(str2[idx]) - idx = idx + 1 - else: - c = 0 - - if (c == 0): - if len(str1) < len(str2): - c = -1 - elif len(str1) > len(str2): - c = 1 - else: - c = 0 - - if op == LT: - return space.newbool(c < 0) - elif op == LE: - return space.newbool(c <= 0) - elif op == NE: - return space.newbool(c != 0) - elif op == GT: - return space.newbool(c > 0) - elif op == GE: - return space.newbool(c >= 0) - else: - return NotImplemented +##EQ = 1 +##LE = 2 +##GE = 3 +##GT = 4 +##LT = 5 +##NE = 6 + + +##def string_richcompare(space, w_str1, w_str2, op): +## str1 = w_str1._value +## str2 = w_str2._value + +## if space.is_true(space.is_(w_str1, w_str2)): +## if op == EQ or op == LE or op == GE: +## return space.w_True +## elif op == GT or op == LT or op == NE: +## return space.w_False +## if 0: +## pass +## else: +## if op == EQ: +## if len(str1) == len(str2): +## for i in range(len(str1)): +## if ord(str1[i]) != ord(str2[i]): +## return space.w_False +## return space.w_True +## else: +## return space.w_False +## else: +## if len(str1) > len(str2): +## min_len = len(str2) +## else: +## min_len = len(str1) + +## c = 0 +## idx = 0 +## if (min_len > 0): +## while (c == 0) and (idx < min_len): +## c = ord(str1[idx]) - ord(str2[idx]) +## idx = idx + 1 +## else: +## c = 0 + +## if (c == 0): +## if len(str1) < len(str2): +## c = -1 +## elif len(str1) > len(str2): +## c = 1 +## else: +## c = 0 + +## if op == LT: +## return space.newbool(c < 0) +## elif op == LE: +## return space.newbool(c <= 0) +## elif op == NE: +## return space.newbool(c != 0) +## elif op == GT: +## return space.newbool(c > 0) +## elif op == GE: +## return space.newbool(c >= 0) +## else: +## return NotImplemented def lt__String_String(space, w_str1, w_str2): - return string_richcompare(space, w_str1, w_str2, LT) + s1 = w_str1._value + s2 = w_str2._value + if s1 < s2: + return space.w_True + else: + return space.w_False def le__String_String(space, w_str1, w_str2): - return string_richcompare(space, w_str1, w_str2, LE) + s1 = w_str1._value + s2 = w_str2._value + if s1 <= s2: + return space.w_True + else: + return space.w_False def eq__String_String(space, w_str1, w_str2): - return string_richcompare(space, w_str1, w_str2, EQ) + s1 = w_str1._value + s2 = w_str2._value + if s1 == s2: + return space.w_True + else: + return space.w_False def ne__String_String(space, w_str1, w_str2): - return string_richcompare(space, w_str1, w_str2, NE) + s1 = w_str1._value + s2 = w_str2._value + if s1 != s2: + return space.w_True + else: + return space.w_False def gt__String_String(space, w_str1, w_str2): - return string_richcompare(space, w_str1, w_str2, GT) + s1 = w_str1._value + s2 = w_str2._value + if s1 > s2: + return space.w_True + else: + return space.w_False def ge__String_String(space, w_str1, w_str2): - return string_richcompare(space, w_str1, w_str2, GE) + s1 = w_str1._value + s2 = w_str2._value + if s1 >= s2: + return space.w_True + else: + return space.w_False def getitem__String_Int(space, w_str, w_int): u = space.unwrap Modified: pypy/branch/src-newobjectmodel/pypy/tool/stdprofile.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/stdprofile.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/stdprofile.py Sat Jun 5 21:03:42 2004 @@ -1,5 +1,6 @@ #! /usr/bin/env python +import autopath import hotshot, os from pypy.objspace.std import StdObjSpace From mwh at codespeak.net Sun Jun 6 13:48:44 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 6 Jun 2004 13:48:44 +0200 (MEST) Subject: [pypy-svn] r4995 - pypy/branch/src-newobjectmodel/pypy/objspace/std Message-ID: <20040606114844.EA6185BE07@thoth.codespeak.net> Author: mwh Date: Sun Jun 6 13:48:44 2004 New Revision: 4995 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py Log: fix at least one performance insanity: actually *use* the hash values in getitem__Dict_ANY! this results in approximately a fourfold speeup! (this commit brought to you via NOMAD from a sunny patch of grass somewhere in Chalmers :-) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py Sun Jun 6 13:48:44 2004 @@ -9,9 +9,9 @@ from pypy.interpreter import gateway from stringobject import W_StringObject -class _NoValueInCell: pass +class _NoValueInCell(object): pass -class Cell: +class Cell(object): def __init__(self,w_value=_NoValueInCell): self.w_value = w_value @@ -50,8 +50,8 @@ return "%s(%s)" % (w_self.__class__.__name__, w_self.data) def non_empties(self): - return [ (w_key,cell) for w_key,hash,cell in self.data - if not cell.is_empty()] + return [ (w_key, hash, cell) for w_key,hash,cell in self.data + if not cell.is_empty()] def _cell(self,space,w_lookup): data = self.data @@ -81,7 +81,7 @@ def unwrap__Dict(space, w_dict): result = {} - for w_key, cell in w_dict.non_empties(): + for w_key, hash, cell in w_dict.non_empties(): result[space.unwrap(w_key)] = space.unwrap(cell.get()) return result @@ -107,8 +107,10 @@ def getitem__Dict_ANY(space, w_dict, w_lookup): data = w_dict.non_empties() - # XXX shouldn't this use hashing? -- mwh - for w_key, cell in data: + h = space.unwrap(space.hash(w_lookup)) + for w_key, hash, cell in data: + if hash != h: + continue if space.is_true(space.eq(w_lookup, w_key)): return cell.get() raise OperationError(space.w_KeyError, w_lookup) @@ -119,7 +121,10 @@ def delitem__Dict_ANY(space, w_dict, w_lookup): data = w_dict.non_empties() - for w_key,cell in data: + h = space.unwrap(space.hash(w_lookup)) + for w_key, hash, cell in data: + if hash != h: + continue if space.is_true(space.eq(w_lookup, w_key)): cell.make_empty() return @@ -136,7 +141,10 @@ def contains__Dict_ANY(space, w_dict, w_lookup): data = w_dict.non_empties() - for w_key,cell in data: + h = space.unwrap(space.hash(w_lookup)) + for w_key, hash, cell in data: + if hash != h: + continue if space.is_true(space.eq(w_lookup, w_key)): return space.w_True return space.w_False @@ -156,7 +164,7 @@ dataright = w_right.non_empties() if len(dataleft) != len(dataright): return space.w_False - for w_key, cell in dataleft: + for w_key, hash, cell in dataleft: try: w_rightval = space.getitem(w_right, w_key) except OperationError: @@ -175,7 +183,7 @@ return space.w_False # Same size - for w_key, cell in dataleft: + for w_key, hash, cell in dataleft: # This is incorrect, but we need to decide what comparisons on # dictionaries of equal size actually means # The Python language specification is silent on the subject @@ -193,21 +201,21 @@ def dict_copy__Dict(space, w_self): return W_DictObject(space, [(w_key,cell.get()) - for w_key,cell in + for w_key,hash,cell in w_self.non_empties()]) def dict_items__Dict(space, w_self): return space.newlist([ space.newtuple([w_key,cell.get()]) - for w_key,cell in + for w_key,hash,cell in w_self.non_empties()]) def dict_keys__Dict(space, w_self): return space.newlist([ w_key - for w_key,cell in + for w_key,hash,cell in w_self.non_empties()]) def dict_values__Dict(space, w_self): return space.newlist([ cell.get() - for w_key,cell in + for w_key,hash,cell in w_self.non_empties()]) def dict_clear__Dict(space, w_self): @@ -215,7 +223,10 @@ def dict_get__Dict_ANY_ANY(space, w_self, w_lookup, w_default): data = w_self.non_empties() - for w_key, cell in data: + h = space.unwrap(space.hash(w_lookup)) + for w_key, hash, cell in data: + if h != hash: + continue if space.is_true(space.eq(w_lookup, w_key)): return cell.get() return w_default From arigo at codespeak.net Sun Jun 6 14:34:20 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 14:34:20 +0200 (MEST) Subject: [pypy-svn] r4997 - pypy/branch/src-newobjectmodel/pypy/objspace Message-ID: <20040606123420.41CE35BE07@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 14:34:19 2004 New Revision: 4997 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Log: Almost fixed the trivial object space. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/trivial.py Sun Jun 6 14:34:19 2004 @@ -83,6 +83,8 @@ ) # make a wrapped None object none_typedef = TypeDef('NoneType', + __nonzero__ = gateway.interp2app(lambda space, w_None: + space.w_False), __repr__ = gateway.interp2app(lambda space, w_None: space.wrap('None'))) nonewrapperclass = self.hackwrapperclass(none_typedef) @@ -251,6 +253,12 @@ def not_(self, w_obj): # default implementation return self.wrap(not self.is_true(w_obj)) + def iter(self, w_obj): + if isinstance(w_obj, str) and not hasattr(w_obj, '__iter__'): + return iter(w_obj) # str.__iter__ is missing in CPython + else: + return DescrOperation.iter(self, w_obj) + # for _name in ('id', 'type', 'iter', 'repr', 'str', 'len', # 'pow', 'divmod', 'hash', 'setattr', 'delattr', 'hex', # 'oct', 'ord', 'getattr'): From arigo at codespeak.net Sun Jun 6 14:36:44 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 14:36:44 +0200 (MEST) Subject: [pypy-svn] r4998 - in pypy/branch/src-newobjectmodel/pypy/objspace/std: . test Message-ID: <20040606123644.34CC55BE07@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 14:36:43 2004 New Revision: 4998 Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py Log: Number of small random fixes. Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/dictobject.py Sun Jun 6 14:36:43 2004 @@ -9,80 +9,42 @@ from pypy.interpreter import gateway from stringobject import W_StringObject -class _NoValueInCell(object): pass - -class Cell(object): - def __init__(self,w_value=_NoValueInCell): - self.w_value = w_value - - def get(self): - if self.is_empty(): - raise ValueError, "get() from an empty cell" - return self.w_value - - def set(self,w_value): - self.w_value = w_value - - def make_empty(self): - if self.is_empty(): - raise ValueError, "make_empty() on an empty cell" - self.w_value = _NoValueInCell - - def is_empty(self): - return self.w_value is _NoValueInCell - - def __repr__(self): - """ representation for debugging purposes """ - return "%s(%s)" % (self.__class__.__name__, self.w_value) - - class W_DictObject(W_Object): from pypy.objspace.std.dicttype import dict_typedef as typedef def __init__(w_self, space, list_pairs_w): W_Object.__init__(w_self, space) - w_self.data = [ (w_key, space.unwrap(space.hash(w_key)), Cell(w_value)) + w_self.data = [ [space.unwrap(space.hash(w_key)), w_key, w_value] for w_key,w_value in list_pairs_w ] def __repr__(w_self): """ representation for debugging purposes """ return "%s(%s)" % (w_self.__class__.__name__, w_self.data) - def non_empties(self): - return [ (w_key, hash, cell) for w_key,hash,cell in self.data - if not cell.is_empty()] - - def _cell(self,space,w_lookup): - data = self.data + def lookup(self, w_lookup, create=False): # this lookup is where most of the start-up time is consumed. # Hashing helps a lot. + space = self.space lookup_hash = space.unwrap(space.hash(w_lookup)) - for w_key, hash, cell in data: - if lookup_hash == hash and space.is_true(space.eq(w_lookup, w_key)): + for cell in self.data: + if (cell[0] == lookup_hash and + space.is_true(space.eq(w_lookup, cell[1]))): break else: - cell = Cell() - data.append((w_lookup,lookup_hash,cell)) + if not create: + raise OperationError(space.w_KeyError, w_lookup) + cell = [lookup_hash, w_lookup, None] + self.data.append(cell) return cell - def cell(self,space,w_lookup): - return space.wrap(self._cell(space,w_lookup)) - - def _appendcell(self, space, w_lookup, w_cell): - # there should be no w_lookup entry already! - data = self.data - lookup_hash = space.unwrap(space.hash(w_lookup)) - cell = space.unwrap(w_cell) - data.append((w_lookup, lookup_hash, cell)) - registerimplementation(W_DictObject) def unwrap__Dict(space, w_dict): result = {} - for w_key, hash, cell in w_dict.non_empties(): - result[space.unwrap(w_key)] = space.unwrap(cell.get()) + for hash, w_key, w_value in w_dict.data: + result[space.unwrap(w_key)] = space.unwrap(w_value) return result def init__Dict(space, w_dict, w_args, w_kwds): @@ -106,48 +68,28 @@ space.call_method(w_dict, 'update', w_kwds) def getitem__Dict_ANY(space, w_dict, w_lookup): - data = w_dict.non_empties() - h = space.unwrap(space.hash(w_lookup)) - for w_key, hash, cell in data: - if hash != h: - continue - if space.is_true(space.eq(w_lookup, w_key)): - return cell.get() - raise OperationError(space.w_KeyError, w_lookup) + return w_dict.lookup(w_lookup)[2] def setitem__Dict_ANY_ANY(space, w_dict, w_newkey, w_newvalue): - cell = w_dict._cell(space,w_newkey) - cell.set(w_newvalue) + cell = w_dict.lookup(w_newkey, create=True) + cell[2] = w_newvalue def delitem__Dict_ANY(space, w_dict, w_lookup): - data = w_dict.non_empties() - h = space.unwrap(space.hash(w_lookup)) - for w_key, hash, cell in data: - if hash != h: - continue - if space.is_true(space.eq(w_lookup, w_key)): - cell.make_empty() - return - raise OperationError(space.w_KeyError, w_lookup) - -def nonzero__Dict(space, w_dict): - # this must be implemented in addition to len() for dictionaries - # for infinite recursion reasons (is_true -> len -> call to len -> - # checking for keywords -> is_true etc.) - return space.newbool(not not w_dict.non_empties()) + cell = w_dict.lookup(w_lookup) + # overwrite the cell with any other one removed from the dictionary + cell[:] = w_dict.data.pop() def len__Dict(space, w_dict): - return space.wrap(len(w_dict.non_empties())) + return space.wrap(len(w_dict.data)) def contains__Dict_ANY(space, w_dict, w_lookup): - data = w_dict.non_empties() - h = space.unwrap(space.hash(w_lookup)) - for w_key, hash, cell in data: - if hash != h: - continue - if space.is_true(space.eq(w_lookup, w_key)): - return space.w_True - return space.w_False + try: + w_dict.lookup(w_lookup) + except OperationError: + # assert e.match(space, space.w_KeyError) + return space.w_False + else: + return space.w_True dict_has_key__Dict_ANY = contains__Dict_ANY @@ -160,30 +102,30 @@ if space.is_true(space.is_(w_left, w_right)): return space.w_True - dataleft = w_left.non_empties() - dataright = w_right.non_empties() + dataleft = w_left.data + dataright = w_right.data if len(dataleft) != len(dataright): return space.w_False - for w_key, hash, cell in dataleft: + for hash, w_key, w_value in dataleft: try: w_rightval = space.getitem(w_right, w_key) except OperationError: return space.w_False - if not space.is_true(space.eq(cell.w_value, w_rightval)): + if not space.is_true(space.eq(w_value, w_rightval)): return space.w_False return space.w_True def lt__Dict_Dict(space, w_left, w_right): # Different sizes, no problem - dataleft = w_left.non_empties() - dataright = w_right.non_empties() + dataleft = w_left.data + dataright = w_right.data if len(dataleft) < len(dataright): return space.w_True if len(dataleft) > len(dataright): return space.w_False # Same size - for w_key, hash, cell in dataleft: + for hash, w_key, w_value in dataleft: # This is incorrect, but we need to decide what comparisons on # dictionaries of equal size actually means # The Python language specification is silent on the subject @@ -191,7 +133,7 @@ w_rightval = space.getitem(w_right, w_key) except OperationError: return space.w_True - if space.is_true(space.lt(cell.w_value, w_rightval)): + if space.is_true(space.lt(w_value, w_rightval)): return space.w_True # The dictionaries are equal. This is correct. return space.w_False @@ -200,37 +142,31 @@ raise OperationError(space.w_TypeError,space.wrap("dict objects are unhashable")) def dict_copy__Dict(space, w_self): - return W_DictObject(space, [(w_key,cell.get()) - for w_key,hash,cell in - w_self.non_empties()]) + return W_DictObject(space, [(w_key,w_value) + for hash,w_key,w_value in w_self.data]) + def dict_items__Dict(space, w_self): - return space.newlist([ space.newtuple([w_key,cell.get()]) - for w_key,hash,cell in - w_self.non_empties()]) + return space.newlist([ space.newtuple([w_key,w_value]) + for hash,w_key,w_value in w_self.data ]) def dict_keys__Dict(space, w_self): return space.newlist([ w_key - for w_key,hash,cell in - w_self.non_empties()]) + for hash,w_key,w_value in w_self.data ]) def dict_values__Dict(space, w_self): - return space.newlist([ cell.get() - for w_key,hash,cell in - w_self.non_empties()]) + return space.newlist([ w_value + for hash,w_key,w_value in w_self.data ]) def dict_clear__Dict(space, w_self): w_self.data = [] -def dict_get__Dict_ANY_ANY(space, w_self, w_lookup, w_default): - data = w_self.non_empties() - h = space.unwrap(space.hash(w_lookup)) - for w_key, hash, cell in data: - if h != hash: - continue - if space.is_true(space.eq(w_lookup, w_key)): - return cell.get() - return w_default - +def dict_get__Dict_ANY_ANY(space, w_dict, w_lookup, w_default): + try: + return w_dict.lookup(w_lookup)[2] + except OperationError: + # assert e.match(space, space.w_KeyError) + return w_default + # Now we only handle one implementation of dicts, this one. # The fix is to move this to dicttype.py, and do a # multimethod lookup mapping str to StdObjSpace.str Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/objspace.py Sun Jun 6 14:36:43 2004 @@ -323,18 +323,18 @@ # XXX a bit of hacking to gain more speed # if w_one is w_two: - return self.newbool(1) + 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.newbool(1) + return self.w_True return self.newbool(self.unwrap(w_one) is self.unwrap(w_two)) - return self.newbool(0) + return self.w_False def is_true(self, w_obj): # XXX don't look! if isinstance(w_obj, W_DictObject): - return not not w_obj.non_empties() + return not not w_obj.data else: return DescrOperation.is_true(self, w_obj) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stdtypedef.py Sun Jun 6 14:36:43 2004 @@ -47,6 +47,10 @@ # get all the sliced multimethods multimethods = slicemultimethods(space.__class__, typedef) for name, code in multimethods.items(): + # compute the slice and ignore the multimethod if empty + if not code.computeslice(space): + continue + # create a Function around the sliced multimethod code fn = function.Function(space, code, defs_w=code.getdefaults(space)) assert name not in rawdict, 'name clash: %s in %s_typedef' % ( name, typedef.name) @@ -97,10 +101,6 @@ # import all multimethods defined directly on the type without slicing for multimethod in typeclass.local_multimethods: slicemultimethod(multimethod, None, result) - # remove the empty slices - for name, code in result.items(): - if code.slice().is_empty(): - del result[name] return result class MultimethodCode(eval.Code): @@ -113,14 +113,25 @@ self.bound_position = bound_position self.framecls = framecls argnames = ['x%d'%(i+1) for i in range(multimethod.arity)] - argnames.insert(0, argnames.pop(self.bound_position)) varargname = kwargname = None if multimethod.extras.get('varargs', False): varargname = 'args' if multimethod.extras.get('keywords', False): kwargname = 'keywords' self.sig = argnames, varargname, kwargname - + + def computeslice(self, space): + if self.typeclass is None: + slice = self.basemultimethod + else: + slice = self.basemultimethod.slice(self.typeclass, + self.bound_position) + if slice.is_empty(): + return False + else: + self.mm = slice.get(space) + return True + def signature(self): return self.sig @@ -128,24 +139,15 @@ return [space.wrap(x) for x in self.basemultimethod.extras.get('defaults', ())] - def slice(self): - if self.typeclass is None: - return self.basemultimethod - else: - return self.basemultimethod.slice(self.typeclass, - self.bound_position) - def create_frame(self, space, w_globals, closure=None): return self.framecls(space, self) class MmFrame(eval.Frame): def run(self): "Call the multimethod, raising a TypeError if not implemented." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w - #print mm.multimethod.operatorsymbol, args - #print - w_result = mm(*args) + args = list(self.fastlocals_w) + args.insert(0, args.pop(self.code.bound_position)) + w_result = self.code.mm(*args) # we accept a real None from operations with no return value if w_result is None: w_result = self.space.w_None @@ -154,10 +156,10 @@ class SpecialMmFrame(eval.Frame): def run(self): "Call the multimethods, possibly returning a NotImplemented." - mm = self.code.slice().get(self.space) - args = self.fastlocals_w + args = list(self.fastlocals_w) + args.insert(0, args.pop(self.code.bound_position)) try: - return mm.perform_call(args) + return self.code.mm.perform_call(args) except FailedToImplement, e: if e.args: raise OperationError(*e.args) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/stringobject.py Sun Jun 6 14:36:43 2004 @@ -1017,6 +1017,10 @@ 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) Modified: pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/branch/src-newobjectmodel/pypy/objspace/std/test/test_dictobject.py Sun Jun 6 14:36:43 2004 @@ -47,48 +47,48 @@ 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_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): From arigo at codespeak.net Sun Jun 6 14:59:39 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 14:59:39 +0200 (MEST) Subject: [pypy-svn] r4999 - pypy/trunk/src/pypy/translator/test Message-ID: <20040606125939.5509B5BE07@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 14:59:38 2004 New Revision: 4999 Modified: pypy/trunk/src/pypy/translator/test/test_cltrans.py Log: (copied from r4971 by mwh) require flowobjspace for test_cltrans Modified: pypy/trunk/src/pypy/translator/test/test_cltrans.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_cltrans.py (original) +++ pypy/trunk/src/pypy/translator/test/test_cltrans.py Sun Jun 6 14:59:38 2004 @@ -42,6 +42,7 @@ class GenCLTestCase(testit.IntTestCase): def setUp(self): + self.space = testit.objspace('flow') if not global_cl: raise (testit.TestSkip, "Common Lisp neither configured nor detected.") From arigo at codespeak.net Sun Jun 6 15:00:36 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 15:00:36 +0200 (MEST) Subject: [pypy-svn] r5000 - pypy/branch/src-newobjectmodel/pypy/translator Message-ID: <20040606130036.8D8F25BE07@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 15:00:36 2004 New Revision: 5000 Removed: pypy/branch/src-newobjectmodel/pypy/translator/ Log: Merging... From arigo at codespeak.net Sun Jun 6 15:01:14 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 15:01:14 +0200 (MEST) Subject: [pypy-svn] r5001 - in pypy/branch/src-newobjectmodel/pypy/translator: . test Message-ID: <20040606130114.F02155BE15@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 15:01:14 2004 New Revision: 5001 Added: pypy/branch/src-newobjectmodel/pypy/translator/ - copied from r4998, pypy/trunk/src/pypy/translator/ pypy/branch/src-newobjectmodel/pypy/translator/test/test_cltrans.py - copied unchanged from r4999, pypy/trunk/src/pypy/translator/test/test_cltrans.py Log: Merging... From arigo at codespeak.net Sun Jun 6 15:04:53 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 15:04:53 +0200 (MEST) Subject: [pypy-svn] r5002 - pypy/branch/src-newobjectmodel/pypy/tool Message-ID: <20040606130453.B37445BE07@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 15:04:52 2004 New Revision: 5002 Added: pypy/branch/src-newobjectmodel/pypy/tool/bltinchecker.py - copied unchanged from r5001, pypy/trunk/src/pypy/tool/bltinchecker.py Modified: pypy/branch/src-newobjectmodel/pypy/tool/option.py pypy/branch/src-newobjectmodel/pypy/tool/testit.py Log: svn merge -r4824:HEAD ~/svn/pypy/trunk/src where HEAD=5001 Modified: pypy/branch/src-newobjectmodel/pypy/tool/option.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/option.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/option.py Sun Jun 6 15:04:52 2004 @@ -25,6 +25,8 @@ '-T', action="callback", callback=objspace_callback, callback_args=("trivial",), help="run in trivial object space")) + """ + unneeded options that don't even make sense any more? options.append(make_option( '-P', action="callback", callback=objspace_callback, callback_args=("trace",), @@ -33,6 +35,7 @@ '-A', action="callback", callback=objspace_callback, callback_args=("ann",), help="run in annotation object space")) + """ options.append(make_option( '-v', action="count", dest="verbose", help="verbose")) Modified: pypy/branch/src-newobjectmodel/pypy/tool/testit.py ============================================================================== --- pypy/branch/src-newobjectmodel/pypy/tool/testit.py (original) +++ pypy/branch/src-newobjectmodel/pypy/tool/testit.py Sun Jun 6 15:04:52 2004 @@ -357,7 +357,7 @@ Options.spacename = spacename warnings.defaultaction = Options.showwarning and 'default' or 'ignore' - print >> sys.stderr, "running tests via", repr(objspace()) + #print >> sys.stderr, "running tests via", repr(objspace()) runner.run(suite) def main(root=None): From arigo at codespeak.net Sun Jun 6 15:09:44 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 15:09:44 +0200 (MEST) Subject: [pypy-svn] r5004 - in pypy: branch/src-newobjectmodel trunk/src Message-ID: <20040606130944.628805BE07@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 15:09:43 2004 New Revision: 5004 Added: pypy/trunk/src/ - copied from r5003, pypy/branch/src-newobjectmodel/ Removed: pypy/branch/src-newobjectmodel/ Log: Merged. From hpk at codespeak.net Sun Jun 6 15:17:34 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 6 Jun 2004 15:17:34 +0200 (MEST) Subject: [pypy-svn] r5005 - pypy/trunk/src/pypy/objspace Message-ID: <20040606131734.0C9965BE07@thoth.codespeak.net> Author: hpk Date: Sun Jun 6 15:17:33 2004 New Revision: 5005 Modified: pypy/trunk/src/pypy/objspace/trivial.py Log: fix remaining trivial failures ... Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Sun Jun 6 15:17:33 2004 @@ -106,12 +106,12 @@ "slice": slice, } for n, c in cpy_builtin.__dict__.iteritems(): - #if n in ['xrange', # we define this in builtin_app - # 'staticmethod', - # 'classmethod', - # 'property', - # ]: - # continue + if n in ['xrange', # we define this in builtin_app + 'staticmethod', + 'classmethod', + 'property', + ]: + continue if isinstance(c, types.TypeType): setattr(self, 'w_' + c.__name__, c) newstuff[c.__name__] = c From hpk at codespeak.net Sun Jun 6 15:51:52 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 6 Jun 2004 15:51:52 +0200 (MEST) Subject: [pypy-svn] r5006 - pypy/trunk/doc Message-ID: <20040606135152.F13715BE07@thoth.codespeak.net> Author: hpk Date: Sun Jun 6 15:51:52 2004 New Revision: 5006 Added: pypy/trunk/doc/pypy-talk-ep2004.txt Log: rough sketch and role delegation for pypy ep 2004 talk Added: pypy/trunk/doc/pypy-talk-ep2004.txt ============================================================================== --- (empty file) +++ pypy/trunk/doc/pypy-talk-ep2004.txt Sun Jun 6 15:51:52 2004 @@ -0,0 +1,14 @@ + +EuroPython 2004 PyPy talk + +1. Motivation / small summary of our EU efforts (Laura?) + +2. architecture / pygame view (Michael, Armin) + +3. source explanation + lower level architecture + examples (Holger) + +4. translation (Samuele) + +5. future directions / how to get involved / questions + (al together) + From hpk at codespeak.net Sun Jun 6 15:53:16 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 6 Jun 2004 15:53:16 +0200 (MEST) Subject: [pypy-svn] r5007 - pypy/trunk/doc Message-ID: <20040606135316.3FF665BE15@thoth.codespeak.net> Author: hpk Date: Sun Jun 6 15:53:15 2004 New Revision: 5007 Modified: pypy/trunk/doc/pypy-talk-ep2004.txt Log: small addition Modified: pypy/trunk/doc/pypy-talk-ep2004.txt ============================================================================== --- pypy/trunk/doc/pypy-talk-ep2004.txt (original) +++ pypy/trunk/doc/pypy-talk-ep2004.txt Sun Jun 6 15:53:15 2004 @@ -7,7 +7,7 @@ 3. source explanation + lower level architecture + examples (Holger) -4. translation (Samuele) +4. translation / flowgraphs / (Samuele) 5. future directions / how to get involved / questions (al together) From mwh at codespeak.net Sun Jun 6 16:54:31 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 6 Jun 2004 16:54:31 +0200 (MEST) Subject: [pypy-svn] r5010 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040606145431.DA4655BE07@thoth.codespeak.net> Author: mwh Date: Sun Jun 6 16:54:31 2004 New Revision: 5010 Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: implement dicts as hashtables doesn't make much difference to performace (!) but it needed doing at some point 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 Sun Jun 6 16:54:31 2004 @@ -9,41 +9,87 @@ from pypy.interpreter import gateway from stringobject import W_StringObject +dummy = object() class W_DictObject(W_Object): from pypy.objspace.std.dicttype import dict_typedef as typedef def __init__(w_self, space, list_pairs_w): W_Object.__init__(w_self, space) - w_self.data = [ [space.unwrap(space.hash(w_key)), w_key, w_value] - for w_key,w_value in list_pairs_w ] - + + w_self.used = 0 + w_self.data = [[0, None, None]] + w_self.resize(len(list_pairs_w)*2) + for w_k, w_v in list_pairs_w: + w_self.insert(space.unwrap(space.hash(w_k)), w_k, w_v) + def __repr__(w_self): """ representation for debugging purposes """ return "%s(%s)" % (w_self.__class__.__name__, w_self.data) - def lookup(self, w_lookup, create=False): - # this lookup is where most of the start-up time is consumed. - # Hashing helps a lot. + def insert(self, h, w_key, w_value): + cell = self.lookdict(h, w_key) + if cell[2] is None: + self.used += 1 + cell[:] = [h, w_key, w_value] + else: + cell[2] = w_value + + def resize(self, minused): + newsize = 1 + while newsize < minused: + newsize *= 2 + od = self.data + + self.used = 0 + self.data = [[0, None, None] for i in range(newsize)] + for h, k, v in od: + if v is not None: + self.insert(h, k, v) + + def non_empties(self): + return [(h, w_k, w_v) for (h, w_k, w_v) in self.data if w_v is not None] + + def lookdict(self, lookup_hash, w_lookup): space = self.space - lookup_hash = space.unwrap(space.hash(w_lookup)) - for cell in self.data: - if (cell[0] == lookup_hash and - space.is_true(space.eq(w_lookup, cell[1]))): - break + i = lookup_hash % len(self.data) + + entry = self.data[i] + if entry[1] is None or \ + space.is_true(space.is_(w_lookup, entry[1])): + return entry + if entry[1] is dummy: + freeslot = entry else: - if not create: - raise OperationError(space.w_KeyError, w_lookup) - cell = [lookup_hash, w_lookup, None] - self.data.append(cell) - return cell + if entry[0] == lookup_hash and space.is_true( + space.eq(entry[1], w_lookup)): + return entry + freeslot = None + + perturb = lookup_hash + while 1: + # XXX HAAAAAAACK to avoid FutureWarnings :-( + i = ((i & 0x1FFFFFFF) << 2) + i + perturb + 1 + entry = self.data[i%len(self.data)] + if entry[1] is None: + if freeslot: + return freeslot + else: + return entry + if entry[0] == lookup_hash and entry[1] is not dummy \ + and space.is_true( + space.eq(entry[1], w_lookup)): + return entry + if entry[1] is dummy and freeslot is None: + freeslot = entry + perturb >>= 5 registerimplementation(W_DictObject) def unwrap__Dict(space, w_dict): result = {} - for hash, w_key, w_value in w_dict.data: + for hash, w_key, w_value in w_dict.non_empties(): result[space.unwrap(w_key)] = space.unwrap(w_value) return result @@ -68,28 +114,32 @@ space.call_method(w_dict, 'update', w_kwds) def getitem__Dict_ANY(space, w_dict, w_lookup): - return w_dict.lookup(w_lookup)[2] + entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + if entry[2] is not None: + return entry[2] + else: + raise OperationError(space.w_KeyError, w_lookup) def setitem__Dict_ANY_ANY(space, w_dict, w_newkey, w_newvalue): - cell = w_dict.lookup(w_newkey, create=True) - cell[2] = w_newvalue + w_dict.insert(space.unwrap(space.hash(w_newkey)), w_newkey, w_newvalue) + if 2*w_dict.used > len(w_dict.data): + w_dict.resize(2*w_dict.used) def delitem__Dict_ANY(space, w_dict, w_lookup): - cell = w_dict.lookup(w_lookup) - # overwrite the cell with any other one removed from the dictionary - cell[:] = w_dict.data.pop() - + entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + if entry[2] is not None: + w_dict.used -= 1 + entry[1] = dummy + entry[2] = None + else: + raise OperationError(space.w_KeyError, w_lookup) + def len__Dict(space, w_dict): - return space.wrap(len(w_dict.data)) + return space.wrap(w_dict.used) def contains__Dict_ANY(space, w_dict, w_lookup): - try: - w_dict.lookup(w_lookup) - except OperationError: - # assert e.match(space, space.w_KeyError) - return space.w_False - else: - return space.w_True + entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + return space.newbool(entry[2] is not None) dict_has_key__Dict_ANY = contains__Dict_ANY @@ -102,8 +152,8 @@ if space.is_true(space.is_(w_left, w_right)): return space.w_True - dataleft = w_left.data - dataright = w_right.data + dataleft = w_left.non_empties() + dataright = w_right.non_empties() if len(dataleft) != len(dataright): return space.w_False for hash, w_key, w_value in dataleft: @@ -117,8 +167,8 @@ def lt__Dict_Dict(space, w_left, w_right): # Different sizes, no problem - dataleft = w_left.data - dataright = w_right.data + dataleft = w_left.non_empties() + dataright = w_right.non_empties() if len(dataleft) < len(dataright): return space.w_True if len(dataleft) > len(dataright): @@ -143,28 +193,33 @@ def dict_copy__Dict(space, w_self): return W_DictObject(space, [(w_key,w_value) - for hash,w_key,w_value in w_self.data]) + for hash,w_key,w_value in w_self.data + if w_value is not None]) def dict_items__Dict(space, w_self): return space.newlist([ space.newtuple([w_key,w_value]) - for hash,w_key,w_value in w_self.data ]) + for hash,w_key,w_value in w_self.data + if w_value is not None]) def dict_keys__Dict(space, w_self): return space.newlist([ w_key - for hash,w_key,w_value in w_self.data ]) + for hash,w_key,w_value in w_self.data + if w_value is not None]) def dict_values__Dict(space, w_self): return space.newlist([ w_value - for hash,w_key,w_value in w_self.data ]) + for hash,w_key,w_value in w_self.data + if w_value is not None]) def dict_clear__Dict(space, w_self): - w_self.data = [] + w_self.data = [[0, None, None]] + w_self.used = 0 def dict_get__Dict_ANY_ANY(space, w_dict, w_lookup, w_default): - try: - return w_dict.lookup(w_lookup)[2] - except OperationError: - # assert e.match(space, space.w_KeyError) + entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + if entry[2] is not None: + return entry[2] + else: return w_default # Now we only handle one implementation of dicts, this one. 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 Sun Jun 6 16:54:31 2004 @@ -334,7 +334,7 @@ def is_true(self, w_obj): # XXX don't look! if isinstance(w_obj, W_DictObject): - return not not w_obj.data + return not not w_obj.used else: return DescrOperation.is_true(self, w_obj) From arigo at codespeak.net Sun Jun 6 17:06:24 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 6 Jun 2004 17:06:24 +0200 (MEST) Subject: [pypy-svn] r5011 - pypy/trunk/src/pypy/module Message-ID: <20040606150624.2ABA05BE15@thoth.codespeak.net> Author: arigo Date: Sun Jun 6 17:06:23 2004 New Revision: 5011 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: - Added input() and raw_input() - dummy class long 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 Sun Jun 6 17:06:23 2004 @@ -31,6 +31,13 @@ co = compile(source, filename, 'exec') exec co in glob, loc +def raw_input(): + import sys + return sys.stdin.readline() # XXX review + +def input(): + return eval(raw_input()) + def sum(sequence, total=0): # must forbid "summing" strings, per specs of built-in 'sum' @@ -938,6 +945,10 @@ # add radd, rsub, rmul, rdiv... + +class long: + pass # XXX do it + # ________________________________________________________________________ ## def app___import__(*args): ## # NOTE: No import statements can be done in this function, From hpk at codespeak.net Tue Jun 8 10:42:16 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 8 Jun 2004 10:42:16 +0200 (MEST) Subject: [pypy-svn] r5016 - pypy/trunk/doc Message-ID: <20040608084216.A1FF45BE15@thoth.codespeak.net> Author: hpk Date: Tue Jun 8 10:42:15 2004 New Revision: 5016 Added: pypy/trunk/doc/developers.txt Log: a first list of everyone who committed or contributed to the svn (src) repository so far. Added: pypy/trunk/doc/developers.txt ============================================================================== --- (empty file) +++ pypy/trunk/doc/developers.txt Tue Jun 8 10:42:15 2004 @@ -0,0 +1,25 @@ +pypy project developers:: + + Armin Rigo + Holger Krekel + Samuele Pedroni + Christian Tismer + Michael Hudson + Laura Creighton + Jacob Hallen + Alex Martelli + Richard Emslie + Seo Sanghyeon + Anna Ravencroft + Guido Van Rossum + Anders Lehmann + Tomek Meka + Stephan Diehl + Jens-Uwe Mager + Jonathan David Riehl + Guenter Jantzen + Stefan Schwarzer + Dinu Gherman + Patrick Maupin + Rocco Moretti + Andreas Friedge From hpk at codespeak.net Tue Jun 8 10:47:27 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 8 Jun 2004 10:47:27 +0200 (MEST) Subject: [pypy-svn] r5017 - pypy/trunk/doc Message-ID: <20040608084727.480FE5BE16@thoth.codespeak.net> Author: hpk Date: Tue Jun 8 10:47:26 2004 New Revision: 5017 Modified: pypy/trunk/doc/developers.txt Log: two columns and added Jiwons probable full name please edit if you think the order should be different (it's kind of arbitrary at the moment) Modified: pypy/trunk/doc/developers.txt ============================================================================== --- pypy/trunk/doc/developers.txt (original) +++ pypy/trunk/doc/developers.txt Tue Jun 8 10:47:26 2004 @@ -1,25 +1,18 @@ + + pypy project developers:: - Armin Rigo - Holger Krekel - Samuele Pedroni - Christian Tismer - Michael Hudson - Laura Creighton - Jacob Hallen - Alex Martelli - Richard Emslie - Seo Sanghyeon - Anna Ravencroft - Guido Van Rossum - Anders Lehmann - Tomek Meka - Stephan Diehl - Jens-Uwe Mager - Jonathan David Riehl - Guenter Jantzen - Stefan Schwarzer - Dinu Gherman - Patrick Maupin - Rocco Moretti - Andreas Friedge + Armin Rigo Holger Krekel + Samuele Pedroni Christian Tismer + Michael Hudson Laura Creighton + Jacob Hallen Alex Martelli + Richard Emslie Seo Sanghyeon + Anna Ravencroft Guido Van Rossum + Anders Lehmann Tomek Meka + Jiwon Seo Stephan Diehl + Jens-Uwe Mager Jonathan David Riehl + Guenter Jantzen Stefan Schwarzer + Dinu Gherman Patrick Maupin + Rocco Moretti Andreas Friedge + +PyPy Webpage: http://codespeak.net/pypy From hpk at codespeak.net Tue Jun 8 10:51:40 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 8 Jun 2004 10:51:40 +0200 (MEST) Subject: [pypy-svn] r5018 - pypy/trunk/doc Message-ID: <20040608085140.3FB315BE17@thoth.codespeak.net> Author: hpk Date: Tue Jun 8 10:51:39 2004 New Revision: 5018 Modified: pypy/trunk/doc/developers.txt Log: added Theo. Modified: pypy/trunk/doc/developers.txt ============================================================================== --- pypy/trunk/doc/developers.txt (original) +++ pypy/trunk/doc/developers.txt Tue Jun 8 10:51:39 2004 @@ -14,5 +14,6 @@ Guenter Jantzen Stefan Schwarzer Dinu Gherman Patrick Maupin Rocco Moretti Andreas Friedge + Theo de Ridder PyPy Webpage: http://codespeak.net/pypy From mwh at codespeak.net Thu Jun 10 12:10:13 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 10 Jun 2004 12:10:13 +0200 (MEST) Subject: [pypy-svn] r5022 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040610101013.E3B1A5BE15@thoth.codespeak.net> Author: mwh Date: Thu Jun 10 12:10:12 2004 New Revision: 5022 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: "unclear behaviour requirement" my ass! i'm not sure how sensible the fix is, though where is everyone? 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 Jun 10 12:10:12 2004 @@ -1012,7 +1012,11 @@ if c=='s': pieces.append(str(value)) elif c=='d': - pieces.append(str(int(value))) + 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': 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 Jun 10 12:10:12 2004 @@ -64,10 +64,7 @@ def test_format_string(self): self.assertEquals('23', '%s' % '23') self.assertEquals("'23'", '%r' % '23') - """ unclear behavior requirement, so, both commented for now...: - self.assertEquals('23', '%d' % '23') ...or...: - self.assertRaises(TypeError, '%d'.__mod__, ((23,),)) ...? - """ + self.assertRaises(TypeError, '%d'.__mod__, "23") def test_format_float(self): self.assertEquals('23', '%d' % 23.456) From arigo at codespeak.net Thu Jun 10 14:38:26 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 14:38:26 +0200 (MEST) Subject: [pypy-svn] r5024 - pypy/trunk/src/pypy/appspace Message-ID: <20040610123826.DF1675BE16@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 14:38:25 2004 New Revision: 5024 Added: pypy/trunk/src/pypy/appspace/random.py Log: Pure Python implementation of random.py, from Python 2.2. Added: pypy/trunk/src/pypy/appspace/random.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/random.py Thu Jun 10 14:38:25 2004 @@ -0,0 +1,782 @@ +# +# This module is stolen from Python 2.2. +# Python 2.3 uses a C extension. +# + +"""Random variable generators. + + integers + -------- + uniform within range + + sequences + --------- + pick random element + generate random permutation + + distributions on the real line: + ------------------------------ + uniform + normal (Gaussian) + lognormal + negative exponential + gamma + beta + + distributions on the circle (angles 0 to 2pi) + --------------------------------------------- + circular uniform + von Mises + +Translated from anonymously contributed C/C++ source. + +Multi-threading note: the random number generator used here is not thread- +safe; it is possible that two calls return the same random value. However, +you can instantiate a different instance of Random() in each thread to get +generators that don't share state, then use .setstate() and .jumpahead() to +move the generators to disjoint segments of the full period. For example, + +def create_generators(num, delta, firstseed=None): + ""\"Return list of num distinct generators. + Each generator has its own unique segment of delta elements from + Random.random()'s full period. + Seed the first generator with optional arg firstseed (default is + None, to seed from current time). + ""\" + + from random import Random + g = Random(firstseed) + result = [g] + for i in range(num - 1): + laststate = g.getstate() + g = Random() + g.setstate(laststate) + g.jumpahead(delta) + result.append(g) + return result + +gens = create_generators(10, 1000000) + +That creates 10 distinct generators, which can be passed out to 10 distinct +threads. The generators don't share state so can be called safely in +parallel. So long as no thread calls its g.random() more than a million +times (the second argument to create_generators), the sequences seen by +each thread will not overlap. + +The period of the underlying Wichmann-Hill generator is 6,953,607,871,644, +and that limits how far this technique can be pushed. + +Just for fun, note that since we know the period, .jumpahead() can also be +used to "move backward in time": + +>>> g = Random(42) # arbitrary +>>> g.random() +0.25420336316883324 +>>> g.jumpahead(6953607871644L - 1) # move *back* one +>>> g.random() +0.25420336316883324 +""" +# XXX The docstring sucks. + +from math import log as _log, exp as _exp, pi as _pi, e as _e +from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin +from math import floor as _floor + +__all__ = ["Random","seed","random","uniform","randint","choice", + "randrange","shuffle","normalvariate","lognormvariate", + "cunifvariate","expovariate","vonmisesvariate","gammavariate", + "stdgamma","gauss","betavariate","paretovariate","weibullvariate", + "getstate","setstate","jumpahead","whseed"] + +def _verify(name, computed, expected): + if abs(computed - expected) > 1e-7: + raise ValueError( + "computed value for %s deviates too much " + "(computed %g, expected %g)" % (name, computed, expected)) + +NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0) +_verify('NV_MAGICCONST', NV_MAGICCONST, 1.71552776992141) + +TWOPI = 2.0*_pi +_verify('TWOPI', TWOPI, 6.28318530718) + +LOG4 = _log(4.0) +_verify('LOG4', LOG4, 1.38629436111989) + +SG_MAGICCONST = 1.0 + _log(4.5) +_verify('SG_MAGICCONST', SG_MAGICCONST, 2.50407739677627) + +del _verify + +# Translated by Guido van Rossum from C source provided by +# Adrian Baddeley. + +class Random: + """Random number generator base class used by bound module functions. + + Used to instantiate instances of Random to get generators that don't + share state. Especially useful for multi-threaded programs, creating + a different instance of Random for each thread, and using the jumpahead() + method to ensure that the generated sequences seen by each thread don't + overlap. + + Class Random can also be subclassed if you want to use a different basic + generator of your own devising: in that case, override the following + methods: random(), seed(), getstate(), setstate() and jumpahead(). + + """ + + VERSION = 1 # used by getstate/setstate + + def __init__(self, x=None): + """Initialize an instance. + + Optional argument x controls seeding, as for Random.seed(). + """ + + self.seed(x) + +## -------------------- core generator ------------------- + + # Specific to Wichmann-Hill generator. Subclasses wishing to use a + # different core generator should override the seed(), random(), + # getstate(), setstate() and jumpahead() methods. + + def seed(self, a=None): + """Initialize internal state from hashable object. + + None or no argument seeds from current time. + + If a is not None or an int or long, hash(a) is used instead. + + If a is an int or long, a is used directly. Distinct values between + 0 and 27814431486575L inclusive are guaranteed to yield distinct + internal states (this guarantee is specific to the default + Wichmann-Hill generator). + """ + + if a is None: + # Initialize from current time + import time + a = long(time.time() * 256) + + if type(a) not in (type(3), type(3L)): + a = hash(a) + + a, x = divmod(a, 30268) + a, y = divmod(a, 30306) + a, z = divmod(a, 30322) + self._seed = int(x)+1, int(y)+1, int(z)+1 + + self.gauss_next = None + + def random(self): + """Get the next random number in the range [0.0, 1.0).""" + + # Wichman-Hill random number generator. + # + # Wichmann, B. A. & Hill, I. D. (1982) + # Algorithm AS 183: + # An efficient and portable pseudo-random number generator + # Applied Statistics 31 (1982) 188-190 + # + # see also: + # Correction to Algorithm AS 183 + # Applied Statistics 33 (1984) 123 + # + # McLeod, A. I. (1985) + # A remark on Algorithm AS 183 + # Applied Statistics 34 (1985),198-200 + + # This part is thread-unsafe: + # BEGIN CRITICAL SECTION + x, y, z = self._seed + x = (171 * x) % 30269 + y = (172 * y) % 30307 + z = (170 * z) % 30323 + self._seed = x, y, z + # END CRITICAL SECTION + + # Note: on a platform using IEEE-754 double arithmetic, this can + # never return 0.0 (asserted by Tim; proof too long for a comment). + return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0 + + def getstate(self): + """Return internal state; can be passed to setstate() later.""" + return self.VERSION, self._seed, self.gauss_next + + def setstate(self, state): + """Restore internal state from object returned by getstate().""" + version = state[0] + if version == 1: + version, self._seed, self.gauss_next = state + else: + raise ValueError("state with version %s passed to " + "Random.setstate() of version %s" % + (version, self.VERSION)) + + def jumpahead(self, n): + """Act as if n calls to random() were made, but quickly. + + n is an int, greater than or equal to 0. + + Example use: If you have 2 threads and know that each will + consume no more than a million random numbers, create two Random + objects r1 and r2, then do + r2.setstate(r1.getstate()) + r2.jumpahead(1000000) + Then r1 and r2 will use guaranteed-disjoint segments of the full + period. + """ + + if not n >= 0: + raise ValueError("n must be >= 0") + x, y, z = self._seed + x = int(x * pow(171, n, 30269)) % 30269 + y = int(y * pow(172, n, 30307)) % 30307 + z = int(z * pow(170, n, 30323)) % 30323 + self._seed = x, y, z + + def __whseed(self, x=0, y=0, z=0): + """Set the Wichmann-Hill seed from (x, y, z). + + These must be integers in the range [0, 256). + """ + + if not type(x) == type(y) == type(z) == type(0): + raise TypeError('seeds must be integers') + if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256): + raise ValueError('seeds must be in range(0, 256)') + if 0 == x == y == z: + # Initialize from current time + import time + t = long(time.time() * 256) + t = int((t&0xffffff) ^ (t>>24)) + t, x = divmod(t, 256) + t, y = divmod(t, 256) + t, z = divmod(t, 256) + # Zero is a poor seed, so substitute 1 + self._seed = (x or 1, y or 1, z or 1) + + self.gauss_next = None + + def whseed(self, a=None): + """Seed from hashable object's hash code. + + None or no argument seeds from current time. It is not guaranteed + that objects with distinct hash codes lead to distinct internal + states. + + This is obsolete, provided for compatibility with the seed routine + used prior to Python 2.1. Use the .seed() method instead. + """ + + if a is None: + self.__whseed() + return + a = hash(a) + a, x = divmod(a, 256) + a, y = divmod(a, 256) + a, z = divmod(a, 256) + x = (x + a) % 256 or 1 + y = (y + a) % 256 or 1 + z = (z + a) % 256 or 1 + self.__whseed(x, y, z) + +## ---- Methods below this point do not need to be overridden when +## ---- subclassing for the purpose of using a different core generator. + +## -------------------- pickle support ------------------- + + def __getstate__(self): # for pickle + return self.getstate() + + def __setstate__(self, state): # for pickle + self.setstate(state) + +## -------------------- integer methods ------------------- + + def randrange(self, start, stop=None, step=1, int=int, default=None): + """Choose a random item from range(start, stop[, step]). + + This fixes the problem with randint() which includes the + endpoint; in Python this is usually not what you want. + Do not supply the 'int' and 'default' arguments. + """ + + # This code is a bit messy to make it fast for the + # common case while still doing adequate error checking. + istart = int(start) + if istart != start: + raise ValueError, "non-integer arg 1 for randrange()" + if stop is default: + if istart > 0: + return int(self.random() * istart) + raise ValueError, "empty range for randrange()" + + # stop argument supplied. + istop = int(stop) + if istop != stop: + raise ValueError, "non-integer stop for randrange()" + if step == 1 and istart < istop: + try: + return istart + int(self.random()*(istop - istart)) + except OverflowError: + # This can happen if istop-istart > sys.maxint + 1, and + # multiplying by random() doesn't reduce it to something + # <= sys.maxint. We know that the overall result fits + # in an int, and can still do it correctly via math.floor(). + # But that adds another function call, so for speed we + # avoided that whenever possible. + return int(istart + _floor(self.random()*(istop - istart))) + if step == 1: + raise ValueError, "empty range for randrange()" + + # Non-unit step argument supplied. + istep = int(step) + if istep != step: + raise ValueError, "non-integer step for randrange()" + if istep > 0: + n = (istop - istart + istep - 1) / istep + elif istep < 0: + n = (istop - istart + istep + 1) / istep + else: + raise ValueError, "zero step for randrange()" + + if n <= 0: + raise ValueError, "empty range for randrange()" + return istart + istep*int(self.random() * n) + + def randint(self, a, b): + """Return random integer in range [a, b], including both end points. + """ + + return self.randrange(a, b+1) + +## -------------------- sequence methods ------------------- + + def choice(self, seq): + """Choose a random element from a non-empty sequence.""" + return seq[int(self.random() * len(seq))] + + def shuffle(self, x, random=None, int=int): + """x, random=random.random -> shuffle list x in place; return None. + + Optional arg random is a 0-argument function returning a random + float in [0.0, 1.0); by default, the standard random.random. + + Note that for even rather small len(x), the total number of + permutations of x is larger than the period of most random number + generators; this implies that "most" permutations of a long + sequence can never be generated. + """ + + if random is None: + random = self.random + for i in xrange(len(x)-1, 0, -1): + # pick an element in x[:i+1] with which to exchange x[i] + j = int(random() * (i+1)) + x[i], x[j] = x[j], x[i] + +## -------------------- real-valued distributions ------------------- + +## -------------------- uniform distribution ------------------- + + def uniform(self, a, b): + """Get a random number in the range [a, b).""" + return a + (b-a) * self.random() + +## -------------------- normal distribution -------------------- + + def normalvariate(self, mu, sigma): + """Normal distribution. + + mu is the mean, and sigma is the standard deviation. + + """ + # mu = mean, sigma = standard deviation + + # Uses Kinderman and Monahan method. Reference: Kinderman, + # A.J. and Monahan, J.F., "Computer generation of random + # variables using the ratio of uniform deviates", ACM Trans + # Math Software, 3, (1977), pp257-260. + + random = self.random + while 1: + u1 = random() + u2 = random() + z = NV_MAGICCONST*(u1-0.5)/u2 + zz = z*z/4.0 + if zz <= -_log(u2): + break + return mu + z*sigma + +## -------------------- lognormal distribution -------------------- + + def lognormvariate(self, mu, sigma): + """Log normal distribution. + + If you take the natural logarithm of this distribution, you'll get a + normal distribution with mean mu and standard deviation sigma. + mu can have any value, and sigma must be greater than zero. + + """ + return _exp(self.normalvariate(mu, sigma)) + +## -------------------- circular uniform -------------------- + + def cunifvariate(self, mean, arc): + """Circular uniform distribution. + + mean is the mean angle, and arc is the range of the distribution, + centered around the mean angle. Both values must be expressed in + radians. Returned values range between mean - arc/2 and + mean + arc/2 and are normalized to between 0 and pi. + + Deprecated in version 2.3. Use: + (mean + arc * (Random.random() - 0.5)) % Math.pi + + """ + # mean: mean angle (in radians between 0 and pi) + # arc: range of distribution (in radians between 0 and pi) + + return (mean + arc * (self.random() - 0.5)) % _pi + +## -------------------- exponential distribution -------------------- + + def expovariate(self, lambd): + """Exponential distribution. + + lambd is 1.0 divided by the desired mean. (The parameter would be + called "lambda", but that is a reserved word in Python.) Returned + values range from 0 to positive infinity. + + """ + # lambd: rate lambd = 1/mean + # ('lambda' is a Python reserved word) + + random = self.random + u = random() + while u <= 1e-7: + u = random() + return -_log(u)/lambd + +## -------------------- von Mises distribution -------------------- + + def vonmisesvariate(self, mu, kappa): + """Circular data distribution. + + mu is the mean angle, expressed in radians between 0 and 2*pi, and + kappa is the concentration parameter, which must be greater than or + equal to zero. If kappa is equal to zero, this distribution reduces + to a uniform random angle over the range 0 to 2*pi. + + """ + # mu: mean angle (in radians between 0 and 2*pi) + # kappa: concentration parameter kappa (>= 0) + # if kappa = 0 generate uniform random angle + + # Based upon an algorithm published in: Fisher, N.I., + # "Statistical Analysis of Circular Data", Cambridge + # University Press, 1993. + + # Thanks to Magnus Kessler for a correction to the + # implementation of step 4. + + random = self.random + if kappa <= 1e-6: + return TWOPI * random() + + a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa) + b = (a - _sqrt(2.0 * a))/(2.0 * kappa) + r = (1.0 + b * b)/(2.0 * b) + + while 1: + u1 = random() + + z = _cos(_pi * u1) + f = (1.0 + r * z)/(r + z) + c = kappa * (r - f) + + u2 = random() + + if not (u2 >= c * (2.0 - c) and u2 > c * _exp(1.0 - c)): + break + + u3 = random() + if u3 > 0.5: + theta = (mu % TWOPI) + _acos(f) + else: + theta = (mu % TWOPI) - _acos(f) + + return theta + +## -------------------- gamma distribution -------------------- + + def gammavariate(self, alpha, beta): + """Gamma distribution. Not the gamma function! + + Conditions on the parameters are alpha > 0 and beta > 0. + + """ + + # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 + + # Warning: a few older sources define the gamma distribution in terms + # of alpha > -1.0 + if alpha <= 0.0 or beta <= 0.0: + raise ValueError, 'gammavariate: alpha and beta must be > 0.0' + + random = self.random + if alpha > 1.0: + + # Uses R.C.H. Cheng, "The generation of Gamma + # variables with non-integral shape parameters", + # Applied Statistics, (1977), 26, No. 1, p71-74 + + ainv = _sqrt(2.0 * alpha - 1.0) + bbb = alpha - LOG4 + ccc = alpha + ainv + + while 1: + u1 = random() + u2 = random() + v = _log(u1/(1.0-u1))/ainv + x = alpha*_exp(v) + z = u1*u1*u2 + r = bbb+ccc*v-x + if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z): + return x * beta + + elif alpha == 1.0: + # expovariate(1) + u = random() + while u <= 1e-7: + u = random() + return -_log(u) * beta + + else: # alpha is between 0 and 1 (exclusive) + + # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle + + while 1: + u = random() + b = (_e + alpha)/_e + p = b*u + if p <= 1.0: + x = pow(p, 1.0/alpha) + else: + # p > 1 + x = -_log((b-p)/alpha) + u1 = random() + if not (((p <= 1.0) and (u1 > _exp(-x))) or + ((p > 1) and (u1 > pow(x, alpha - 1.0)))): + break + return x * beta + + + def stdgamma(self, alpha, ainv, bbb, ccc): + # This method was (and shall remain) undocumented. + # This method is deprecated + # for the following reasons: + # 1. Returns same as .gammavariate(alpha, 1.0) + # 2. Requires caller to provide 3 extra arguments + # that are functions of alpha anyway + # 3. Can't be used for alpha < 0.5 + + # ainv = sqrt(2 * alpha - 1) + # bbb = alpha - log(4) + # ccc = alpha + ainv + import warnings + warnings.warn("The stdgamma function is deprecated; " + "use gammavariate() instead", + DeprecationWarning) + return self.gammavariate(alpha, 1.0) + + + +## -------------------- Gauss (faster alternative) -------------------- + + def gauss(self, mu, sigma): + """Gaussian distribution. + + mu is the mean, and sigma is the standard deviation. This is + slightly faster than the normalvariate() function. + + Not thread-safe without a lock around calls. + + """ + + # When x and y are two variables from [0, 1), uniformly + # distributed, then + # + # cos(2*pi*x)*sqrt(-2*log(1-y)) + # sin(2*pi*x)*sqrt(-2*log(1-y)) + # + # are two *independent* variables with normal distribution + # (mu = 0, sigma = 1). + # (Lambert Meertens) + # (corrected version; bug discovered by Mike Miller, fixed by LM) + + # Multithreading note: When two threads call this function + # simultaneously, it is possible that they will receive the + # same return value. The window is very small though. To + # avoid this, you have to use a lock around all calls. (I + # didn't want to slow this down in the serial case by using a + # lock here.) + + random = self.random + z = self.gauss_next + self.gauss_next = None + if z is None: + x2pi = random() * TWOPI + g2rad = _sqrt(-2.0 * _log(1.0 - random())) + z = _cos(x2pi) * g2rad + self.gauss_next = _sin(x2pi) * g2rad + + return mu + z*sigma + +## -------------------- beta -------------------- +## See +## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470 +## for Ivan Frohne's insightful analysis of why the original implementation: +## +## def betavariate(self, alpha, beta): +## # Discrete Event Simulation in C, pp 87-88. +## +## y = self.expovariate(alpha) +## z = self.expovariate(1.0/beta) +## return z/(y+z) +## +## was dead wrong, and how it probably got that way. + + def betavariate(self, alpha, beta): + """Beta distribution. + + Conditions on the parameters are alpha > -1 and beta} > -1. + Returned values range between 0 and 1. + + """ + + # This version due to Janne Sinkkonen, and matches all the std + # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution"). + y = self.gammavariate(alpha, 1.) + if y == 0: + return 0.0 + else: + return y / (y + self.gammavariate(beta, 1.)) + +## -------------------- Pareto -------------------- + + def paretovariate(self, alpha): + """Pareto distribution. alpha is the shape parameter.""" + # Jain, pg. 495 + + u = self.random() + return 1.0 / pow(u, 1.0/alpha) + +## -------------------- Weibull -------------------- + + def weibullvariate(self, alpha, beta): + """Weibull distribution. + + alpha is the scale parameter and beta is the shape parameter. + + """ + # Jain, pg. 499; bug fix courtesy Bill Arms + + u = self.random() + return alpha * pow(-_log(u), 1.0/beta) + +## -------------------- test program -------------------- + +def _test_generator(n, funccall): + import time + print n, 'times', funccall + code = compile(funccall, funccall, 'eval') + sum = 0.0 + sqsum = 0.0 + smallest = 1e10 + largest = -1e10 + t0 = time.time() + for i in range(n): + x = eval(code) + sum = sum + x + sqsum = sqsum + x*x + smallest = min(x, smallest) + largest = max(x, largest) + t1 = time.time() + print round(t1-t0, 3), 'sec,', + avg = sum/n + stddev = _sqrt(sqsum/n - avg*avg) + print 'avg %g, stddev %g, min %g, max %g' % \ + (avg, stddev, smallest, largest) + +def _test(N=20000): + print 'TWOPI =', TWOPI + print 'LOG4 =', LOG4 + print 'NV_MAGICCONST =', NV_MAGICCONST + print 'SG_MAGICCONST =', SG_MAGICCONST + _test_generator(N, 'random()') + _test_generator(N, 'normalvariate(0.0, 1.0)') + _test_generator(N, 'lognormvariate(0.0, 1.0)') + _test_generator(N, 'cunifvariate(0.0, 1.0)') + _test_generator(N, 'expovariate(1.0)') + _test_generator(N, 'vonmisesvariate(0.0, 1.0)') + _test_generator(N, 'gammavariate(0.01, 1.0)') + _test_generator(N, 'gammavariate(0.1, 1.0)') + _test_generator(N, 'gammavariate(0.1, 2.0)') + _test_generator(N, 'gammavariate(0.5, 1.0)') + _test_generator(N, 'gammavariate(0.9, 1.0)') + _test_generator(N, 'gammavariate(1.0, 1.0)') + _test_generator(N, 'gammavariate(2.0, 1.0)') + _test_generator(N, 'gammavariate(20.0, 1.0)') + _test_generator(N, 'gammavariate(200.0, 1.0)') + _test_generator(N, 'gauss(0.0, 1.0)') + _test_generator(N, 'betavariate(3.0, 3.0)') + _test_generator(N, 'paretovariate(1.0)') + _test_generator(N, 'weibullvariate(1.0, 1.0)') + + # Test jumpahead. + s = getstate() + jumpahead(N) + r1 = random() + # now do it the slow way + setstate(s) + for i in range(N): + random() + r2 = random() + if r1 != r2: + raise ValueError("jumpahead test failed " + `(N, r1, r2)`) + +# Create one instance, seeded from current time, and export its methods +# as module-level functions. The functions are not threadsafe, and state +# is shared across all uses (both in the user's code and in the Python +# libraries), but that's fine for most programs and is easier for the +# casual user than making them instantiate their own Random() instance. +_inst = Random() +seed = _inst.seed +random = _inst.random +uniform = _inst.uniform +randint = _inst.randint +choice = _inst.choice +randrange = _inst.randrange +shuffle = _inst.shuffle +normalvariate = _inst.normalvariate +lognormvariate = _inst.lognormvariate +cunifvariate = _inst.cunifvariate +expovariate = _inst.expovariate +vonmisesvariate = _inst.vonmisesvariate +gammavariate = _inst.gammavariate +stdgamma = _inst.stdgamma +gauss = _inst.gauss +betavariate = _inst.betavariate +paretovariate = _inst.paretovariate +weibullvariate = _inst.weibullvariate +getstate = _inst.getstate +setstate = _inst.setstate +jumpahead = _inst.jumpahead +whseed = _inst.whseed + +if __name__ == '__main__': + _test() From arigo at codespeak.net Thu Jun 10 14:46:16 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 14:46:16 +0200 (MEST) Subject: [pypy-svn] r5025 - in pypy/trunk/src/pypy: interpreter module Message-ID: <20040610124616.27F6C5BE17@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 14:46:15 2004 New Revision: 5025 Modified: pypy/trunk/src/pypy/interpreter/error.py pypy/trunk/src/pypy/interpreter/interactive.py pypy/trunk/src/pypy/module/sysmodule.py Log: implement half of sys.excepthook(). It can be called by Python code. The missing half is actually calling it from the core. Modified: pypy/trunk/src/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/error.py (original) +++ pypy/trunk/src/pypy/interpreter/error.py Thu Jun 10 14:46:15 2004 @@ -1,4 +1,3 @@ -from pypy.tool.tb_server import publish_exc import os, sys AUTO_DEBUG = os.getenv('PYPY_DEBUG') @@ -150,14 +149,14 @@ self.file.write('\n') # installing the excepthook for OperationErrors -if hasattr(sys, 'excepthook'): # not implemented on PyPy - def operr_excepthook(exctype, value, traceback): - if issubclass(exctype, OperationError): - value.debug_excs.append((exctype, value, traceback)) - value.print_detailed_traceback() - else: - old_excepthook(exctype, value, traceback) - publish_exc((exctype, value, traceback)) - - old_excepthook = sys.excepthook - sys.excepthook = operr_excepthook +def operr_excepthook(exctype, value, traceback): + if issubclass(exctype, OperationError): + value.debug_excs.append((exctype, value, traceback)) + value.print_detailed_traceback() + else: + old_excepthook(exctype, value, traceback) + from pypy.tool import tb_server + tb_server.publish_exc((exctype, value, traceback)) + +old_excepthook = sys.excepthook +sys.excepthook = operr_excepthook Modified: pypy/trunk/src/pypy/interpreter/interactive.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/interactive.py (original) +++ pypy/trunk/src/pypy/interpreter/interactive.py Thu Jun 10 14:46:15 2004 @@ -52,6 +52,9 @@ except baseobjspace.OperationError, operationerr: # XXX insert exception info into the application-level sys.last_xxx operationerr.print_detailed_traceback(self.space) + # for debugging convenience we also insert the exception into + # the interpreter-level sys.last_xxx + sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() else: try: if sys.stdout.softspace: Modified: pypy/trunk/src/pypy/module/sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/sysmodule.py (original) +++ pypy/trunk/src/pypy/module/sysmodule.py Thu Jun 10 14:46:15 2004 @@ -19,3 +19,8 @@ executable = '' prefix = '' version = '0.0.0 (not released yet)' + +# XXX not called by the core yet +def excepthook(exctype, value, traceback): + from traceback import print_exception + print_exception(exctype, value, traceback) From arigo at codespeak.net Thu Jun 10 14:46:47 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 14:46:47 +0200 (MEST) Subject: [pypy-svn] r5026 - pypy/trunk/src/pypy/tool/tb_server Message-ID: <20040610124647.5A3AC5BE48@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 14:46:46 2004 New Revision: 5026 Modified: pypy/trunk/src/pypy/tool/tb_server/__init__.py Log: Lazily import the tb_server package's content (so don't import HTTP stuff unless it is really needed). Modified: pypy/trunk/src/pypy/tool/tb_server/__init__.py ============================================================================== --- pypy/trunk/src/pypy/tool/tb_server/__init__.py (original) +++ pypy/trunk/src/pypy/tool/tb_server/__init__.py Thu Jun 10 14:46:46 2004 @@ -1 +1,15 @@ -from server import start, stop, publish_exc, wait_until_interrupt +# Lazy import + +def start(): + global start, stop, publish_exc, wait_until_interrupt + from server import start, stop, publish_exc, wait_until_interrupt + return start() + +def stop(): + pass + +def wait_until_interrupt(): + pass + +def publish_exc(exc): + pass From arigo at codespeak.net Thu Jun 10 14:47:20 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 14:47:20 +0200 (MEST) Subject: [pypy-svn] r5027 - pypy/trunk/src/pypy/objspace Message-ID: <20040610124720.640395C16B@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 14:47:19 2004 New Revision: 5027 Modified: pypy/trunk/src/pypy/objspace/descroperation.py Log: Bug fix. Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Thu Jun 10 14:47:19 2004 @@ -375,6 +375,8 @@ specialname, = specialnames assert specialname.startswith('__i') and specialname.endswith('__') noninplacespacemethod = specialname[3:-2] + if noninplacespacemethod in ['or', 'and']: + noninplacespacemethod += '_' # not too clean def inplace_impl(space,w_lhs,w_rhs): w_impl = space.lookup(w_lhs,specialname) if w_impl is not None: From arigo at codespeak.net Thu Jun 10 14:48:40 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 14:48:40 +0200 (MEST) Subject: [pypy-svn] r5028 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040610124840.5DF625C16D@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 14:48:39 2004 New Revision: 5028 Modified: pypy/trunk/src/pypy/objspace/std/typetype.py Log: Make __new__ an unbound method of the metaclass, instead of a real class method. Looks like Python does the same in at least some cases, and this way we don't need 'classmethod' to be available at this point. 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 Thu Jun 10 14:48:39 2004 @@ -15,7 +15,11 @@ key = space.unwrap(w_key) assert isinstance(key, str) dict_w[key] = space.getitem(w_dict, w_key) - # XXX classmethod-ify w_dict['__new__'] + # make '__new__' an unbound method on w_typetype + # XXX check if this is correct in all cases + if '__new__' in dict_w: + dict_w['__new__'] = space.get(dict_w['__new__'], + space.w_None, w_typetype) w_type = W_TypeObject(space, name, bases_w or [space.w_object], dict_w, None) return space.w_type.check_user_subclass(w_typetype, w_type) From arigo at codespeak.net Thu Jun 10 14:50:52 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 14:50:52 +0200 (MEST) Subject: [pypy-svn] r5029 - in pypy/trunk/src/pypy: interpreter module objspace/std Message-ID: <20040610125052.7EEBD5C16E@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 14:50:51 2004 New Revision: 5029 Added: pypy/trunk/src/pypy/objspace/std/longobject.py pypy/trunk/src/pypy/objspace/std/longtype.py Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/intobject.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: Draft for 'long' objects. Currently delegates all operations to CPython longs. Having this at interp-level helps a lot for multimethod coherence, e.g. 'lst[2L:5L]' works now. Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Thu Jun 10 14:50:51 2004 @@ -225,6 +225,7 @@ ('xor', '^', 2, ['__xor__', '__rxor__']), ('int', 'int', 1, ['__int__']), ('float', 'float', 1, ['__float__']), + ('long', 'long', 1, ['__long__']), ('inplace_add', '+=', 2, ['__iadd__']), ('inplace_sub', '-=', 2, ['__isub__']), ('inplace_mul', '*=', 2, ['__imul__']), 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 Jun 10 14:50:51 2004 @@ -946,9 +946,6 @@ # add radd, rsub, rmul, rdiv... -class long: - pass # XXX do it - # ________________________________________________________________________ ## def app___import__(*args): ## # NOTE: No import statements can be done in this function, Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Thu Jun 10 14:50:51 2004 @@ -46,18 +46,18 @@ def cpython_unwrap(space, w_obj): cpyobj = w_obj.cpyobj - if hasattr(type(cpyobj), '__unwrap__'): - cpyobj = cpyobj.__unwrap__() + #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) +#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 @@ -85,9 +85,13 @@ name = exc.__name__ if hasattr(space, 'w_' + name): w_exc = getattr(space, 'w_' + name) + w_value = space.call(w_exc, + space.newtuple([space.wrap(a) for a in value.args]), + space.newdict([])) else: w_exc = space.wrap(exc) - raise OperationError, OperationError(w_exc, space.wrap(value)), tb + w_value = space.wrap(value) + raise OperationError, OperationError(w_exc, w_value), tb # in-place operators def inplace_pow(x1, x2): 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 Thu Jun 10 14:50:51 2004 @@ -277,8 +277,7 @@ # a derived integer object, where it should return # an exact one. def pos__Int(space, w_int1): - #not sure if this should be done this way: - if w_int1.__class__ is W_IntObject: + if space.is_true(space.is_(space.type(w_int1), space.w_int)): return w_int1 a = w_int1.intval return W_IntObject(space, a) @@ -313,6 +312,9 @@ ## the overflow checking, using macro Py_ARITHMETIC_RIGHT_SHIFT ## we *assume* that the overflow checking is done correctly ## in the code generator, which is not trivial! + + ## XXX also note that Python 2.3 returns a long and never raises + ## OverflowError. try: c = a << b ## the test in C code is Added: pypy/trunk/src/pypy/objspace/std/longobject.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/longobject.py Thu Jun 10 14:50:51 2004 @@ -0,0 +1,197 @@ +import sys +from pypy.objspace.std.objspace import * +from intobject import W_IntObject +from floatobject import W_FloatObject +from noneobject import W_NoneObject + +class W_LongObject(W_Object): + """This is a non-reimplementation of longs. + It uses real CPython longs. + XXX we must really choose another representation (e.g. list of ints) + XXX and implement it in detail. + """ + from pypy.objspace.std.longtype import long_typedef as typedef + + def __init__(w_self, space, longval=0L): + W_Object.__init__(w_self, space) + w_self.longval = longval + + +registerimplementation(W_LongObject) + +# int-to-long delegation +def delegate__Int(space, w_intobj): + return W_LongObject(space, long(w_intobj.intval)) +delegate__Int.result_class = W_LongObject +delegate__Int.priority = PRIORITY_CHANGE_TYPE + + +def long__Long(space, w_value): + return w_value + +def long__Int(space, w_intobj): + return W_LongObject(space, long(w_intobj.intval)) + +def int__Long(space, w_value): + if -sys.maxint-1 <= w_value.longval <= sys.maxint: + return space.newint(int(w_value.longval)) + else: + return w_value # 9999999999999L.__int__() == 9999999999999L + +def float__Long(space, w_longobj): + return space.newfloat(float(w_longobj.longval)) + +def long__Float(space, w_floatobj): + return W_LongObject(space, long(w_floatobj.floatval)) + +def unwrap__Long(space, w_long): + return w_long.longval + +def repr__Long(space, w_long): + return space.wrap(repr(w_long.longval)) + +def str__Long(space, w_long): + return space.wrap(str(w_long.longval)) + +def lt__Long_Long(space, w_long1, w_long2): + i = w_long1.longval + j = w_long2.longval + return space.newbool( i < j ) + +def hash__Long(space,w_value): + ## %reimplement% + # real Implementation should be taken from _Py_HashDouble in object.c + return space.wrap(hash(w_value.longval)) + +def add__Long_Long(space, w_long1, w_long2): + x = w_long1.longval + y = w_long2.longval + z = x + y + return W_LongObject(space, z) + +def sub__Long_Long(space, w_long1, w_long2): + x = w_long1.longval + y = w_long2.longval + z = x - y + return W_LongObject(space, z) + +def mul__Long_Long(space, w_long1, w_long2): + x = w_long1.longval + y = w_long2.longval + z = x * y + return W_LongObject(space, z) + +def div__Long_Long(space, w_long1, w_long2): + x = w_long1.longval + y = w_long2.longval + if not y: + raise OperationError(space.w_ZeroDivisionError, + space.wrap("long division")) + z = x / y + return W_LongObject(space, z) + +def floordiv__Long_Long(space, w_long1, w_long2): + x = w_long1.longval + y = w_long2.longval + if not y: + raise OperationError(space.w_ZeroDivisionError, + space.wrap("long division")) + z = x // y + return W_LongObject(space, z) + +def mod__Long_Long(space, w_long1, w_long2): + x = w_long1.longval + y = w_long2.longval + if not y: + raise OperationError(space.w_ZeroDivisionError, + space.wrap("long modulo")) + z = x % y + return W_LongObject(space, z) + +def divmod__Long_Long(space, w_long1, w_long2): + x = w_long1.longval + y = w_long2.longval + if not y: + raise OperationError(space.w_ZeroDivisionError, + space.wrap("long modulo")) + z1, z2 = divmod(x, y) + return space.newtuple([W_LongObject(space, z1), + W_LongObject(space, z2)]) + +def pow__Long_Long_None(space, w_long1, w_long2, w_none3): + x = w_long1.longval + y = w_long2.longval + z = x ** y + return W_LongObject(space, z) + +def pow__Long_Long_Long(space, w_long1, w_long2, w_long3): + x = w_long1.longval + y = w_long2.longval + z = w_long2.longval + t = pow(x, y, z) + return W_LongObject(space, t) + +def neg__Long(space, w_long1): + return W_LongObject(space, -w_long1.longval) + +def pos__Long(space, w_long): + if space.is_true(space.is_(space.type(w_long), space.w_long)): + return w_long + else: + return W_LongObject(space, w_long.longval) + +def abs__Long(space, w_long): + return W_LongObject(space, abs(w_long.longval)) + +def nonzero__Long(space, w_long): + return space.newbool(w_long.longval != 0L) + +def invert__Long(space, w_long): + return W_LongObject(space, ~w_long.longval) + +def lshift__Long_Int(space, w_long1, w_int2): + a = w_long1.longval + b = w_int2.intval + if b < 0: + raise OperationError(space.w_ValueError, + space.wrap("negative shift count")) + res = a << b + return W_LongObject(space, res) + +def rshift__Long_Int(space, w_long1, w_int2): + a = w_long1.longval + b = w_int2.intval + if b < 0: + raise OperationError(space.w_ValueError, + space.wrap("negative shift count")) + res = a >> b + return W_LongObject(space, res) + +def and__Long_Long(space, w_long1, w_long2): + a = w_long1.longval + b = w_long2.longval + res = a & b + return W_LongObject(space, res) + +def xor__Long_Long(space, w_long1, w_long2): + a = w_long1.longval + b = w_long2.longval + res = a ^ b + return W_LongObject(space, res) + +def or__Long_Long(space, w_long1, w_long2): + a = w_long1.longval + b = w_long2.longval + res = a | b + return W_LongObject(space, res) + +def oct__Long(space, w_long1): + x = w_long1.longval + return space.wrap(oct(x)) + +def hex__Long(space, w_long1): + x = w_long1.longval + return space.wrap(hex(x)) + + +register_all(vars()) Added: pypy/trunk/src/pypy/objspace/std/longtype.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/std/longtype.py Thu Jun 10 14:50:51 2004 @@ -0,0 +1,17 @@ +from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.objecttype import object_typedef +from pypy.interpreter.error import OperationError + +def descr__new__(space, w_longtype, w_value=None): + from longobject import W_LongObject + if w_value is None: + w_obj = W_LongObject(space) + else: + w_obj = space.long(w_value) + return space.w_long.check_user_subclass(w_longtype, w_obj) + +# ____________________________________________________________ + +long_typedef = StdTypeDef("long", [object_typedef], + __new__ = newmethod(descr__new__), + ) 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 Jun 10 14:50:51 2004 @@ -55,6 +55,7 @@ from stringtype import str_typedef from typetype import type_typedef from slicetype import slice_typedef + from longtype import long_typedef return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look @@ -138,11 +139,12 @@ import stringobject import typeobject import sliceobject + import longobject 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 + global W_TypeObject, W_SliceObject, W_LongObject global W_CPythonObject, W_BuiltinFunctionObject W_ObjectObject = objectobject.W_ObjectObject W_BoolObject = boolobject.W_BoolObject @@ -154,6 +156,7 @@ W_StringObject = stringobject.W_StringObject W_TypeObject = typeobject.W_TypeObject W_SliceObject = sliceobject.W_SliceObject + W_LongObject = longobject.W_LongObject W_CPythonObject = cpythonobject.W_CPythonObject W_BuiltinFunctionObject = cpythonobject.W_BuiltinFunctionObject # end of hacks @@ -226,6 +229,8 @@ if isinstance(x, list): wrappeditems = [self.wrap(item) for item in x] return W_ListObject(self, wrappeditems) + if isinstance(x, long): + return W_LongObject(self, x) if isinstance(x, Wrappable): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result @@ -233,7 +238,7 @@ SlotWrapperType = type(type(None).__repr__) if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): return W_BuiltinFunctionObject(self, x) - #print "cpython wrapping %r (%s)" % (x, type(x)) + #print "cpython wrapping %r" % (x,) #if hasattr(x, '__bases__'): # print "cpython wrapping a class %r (%s)" % (x, type(x)) #raise TypeError, "cannot wrap classes" From arigo at codespeak.net Thu Jun 10 14:58:17 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 14:58:17 +0200 (MEST) Subject: [pypy-svn] r5030 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040610125817.C0F1E5BE1A@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 14:58:16 2004 New Revision: 5030 Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py Log: Forgot three space.wrap(). 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 Jun 10 14:58:16 2004 @@ -60,16 +60,17 @@ return w_obj if not space.is_true(space.issubtype(w_subtype, w_self)): raise OperationError(space.w_TypeError, - "%s.__new__(%s): %s is not a subtype of %s" % ( - w_self.name, w_subtype.name, w_subtype.name, w_self.name)) + space.wrap("%s.__new__(%s): %s is not a subtype of %s" % ( + w_self.name, w_subtype.name, w_subtype.name, w_self.name))) if w_self.instancetypedef is not w_subtype.instancetypedef: raise OperationError(space.w_TypeError, - "%s.__new__(%s) is not safe, use %s.__new__()" % ( - w_self.name, w_subtype.name, w_subtype.name)) + space.wrap("%s.__new__(%s) is not safe, use %s.__new__()" % ( + w_self.name, w_subtype.name, w_subtype.name))) if w_self.instancetypedef is not w_obj.typedef: raise OperationError(space.w_TypeError, - "%s.__new__(): got an object of type %s instead of %s" % ( - w_self.name, space.type(w_obj).name, w_self.name)) + space.wrap("%s.__new__(): got an object of type %s " + "instead of %s" % ( + w_self.name, space.type(w_obj).name, w_self.name))) # stuff extra attributes into w_obj w_obj.w__class__ = w_subtype if w_subtype.needs_new_dict: From arigo at codespeak.net Thu Jun 10 15:55:52 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 15:55:52 +0200 (MEST) Subject: [pypy-svn] r5031 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040610135552.7BC455BE17@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 15:55:51 2004 New Revision: 5031 Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py pypy/trunk/src/pypy/objspace/std/test/test_dictobject.py Log: noticing 'class A: pass' hung where 'class C: pass' did not we hunted and killed a bug in dictionaries to do with horrible signedness issues. added hopefully comprehensive test of the dictionary mechanics 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 Jun 10 15:55:51 2004 @@ -9,6 +9,8 @@ from pypy.interpreter import gateway from stringobject import W_StringObject +from restricted_int import r_uint + dummy = object() class W_DictObject(W_Object): @@ -18,15 +20,19 @@ W_Object.__init__(w_self, space) w_self.used = 0 - w_self.data = [[0, None, None]] + w_self.data = [[r_uint(0), None, None]] w_self.resize(len(list_pairs_w)*2) for w_k, w_v in list_pairs_w: - w_self.insert(space.unwrap(space.hash(w_k)), w_k, w_v) + w_self.insert(w_self.hash(w_k), w_k, w_v) def __repr__(w_self): """ representation for debugging purposes """ return "%s(%s)" % (w_self.__class__.__name__, w_self.data) + def hash(w_self, w_obj): + space = w_self.space + return r_uint(space.unwrap(space.hash(w_obj))) + def insert(self, h, w_key, w_value): cell = self.lookdict(h, w_key) if cell[2] is None: @@ -42,7 +48,7 @@ od = self.data self.used = 0 - self.data = [[0, None, None] for i in range(newsize)] + self.data = [[r_uint(0), None, None] for i in range(newsize)] for h, k, v in od: if v is not None: self.insert(h, k, v) @@ -51,6 +57,7 @@ return [(h, w_k, w_v) for (h, w_k, w_v) in self.data if w_v is not None] def lookdict(self, lookup_hash, w_lookup): + assert isinstance(lookup_hash, r_uint) space = self.space i = lookup_hash % len(self.data) @@ -67,9 +74,14 @@ freeslot = None perturb = lookup_hash + c = 0 while 1: - # XXX HAAAAAAACK to avoid FutureWarnings :-( - i = ((i & 0x1FFFFFFF) << 2) + i + perturb + 1 + c += 1 + if c > 1000: + import pdb + pdb.set_trace() + + i = (i << 2) + i + perturb + 1 entry = self.data[i%len(self.data)] if entry[1] is None: if freeslot: @@ -114,19 +126,19 @@ space.call_method(w_dict, 'update', w_kwds) def getitem__Dict_ANY(space, w_dict, w_lookup): - entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + entry = w_dict.lookdict(w_dict.hash(w_lookup), w_lookup) if entry[2] is not None: return entry[2] else: raise OperationError(space.w_KeyError, w_lookup) def setitem__Dict_ANY_ANY(space, w_dict, w_newkey, w_newvalue): - w_dict.insert(space.unwrap(space.hash(w_newkey)), w_newkey, w_newvalue) + w_dict.insert(w_dict.hash(w_newkey), w_newkey, w_newvalue) if 2*w_dict.used > len(w_dict.data): w_dict.resize(2*w_dict.used) def delitem__Dict_ANY(space, w_dict, w_lookup): - entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + entry = w_dict.lookdict(w_dict.hash(w_lookup), w_lookup) if entry[2] is not None: w_dict.used -= 1 entry[1] = dummy @@ -138,7 +150,7 @@ return space.wrap(w_dict.used) def contains__Dict_ANY(space, w_dict, w_lookup): - entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + entry = w_dict.lookdict(w_dict.hash(w_lookup), w_lookup) return space.newbool(entry[2] is not None) dict_has_key__Dict_ANY = contains__Dict_ANY @@ -216,7 +228,7 @@ w_self.used = 0 def dict_get__Dict_ANY_ANY(space, w_dict, w_lookup, w_default): - entry = w_dict.lookdict(space.unwrap(space.hash(w_lookup)), w_lookup) + entry = w_dict.lookdict(w_dict.hash(w_lookup), w_lookup) if entry[2] is not None: return entry[2] else: 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 Jun 10 15:55:51 2004 @@ -344,5 +344,41 @@ self.assertEquals({1: 0, 2: 0, 3: 0}.fromkeys([1, '1'], 'j'), {1: 'j', '1': 'j'}) +# the minimal 'space' needed to use a W_DictObject +class FakeSpace: + def hash(self, obj): + return hash(obj) + def unwrap(self, x): + return x + def is_true(self, x): + return x + def is_(self, x, y): + return x is y + def eq(self, x, y): + return x == y + +from pypy.objspace.std.dictobject import getitem__Dict_ANY, setitem__Dict_ANY_ANY + +class TestDictImplementation(testit.TestCase): + + def setUp(self): + self.space = FakeSpace() + + def tearDown(self): + pass + + def test_stressdict(self): + from random import randint + d = W_DictObject(self.space, []) + N = 10000 + pydict = {} + for i in range(N): + x = randint(-N, N) + setitem__Dict_ANY_ANY(self.space, d, x, i) + pydict[x] = i + for x in pydict: + self.assertEqual(pydict[x], getitem__Dict_ANY(self.space, d, x)) + + if __name__ == '__main__': testit.main() From arigo at codespeak.net Thu Jun 10 18:25:31 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 18:25:31 +0200 (MEST) Subject: [pypy-svn] r5032 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040610162531.DB0325BE17@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 18:25:31 2004 New Revision: 5032 Modified: pypy/trunk/src/pypy/objspace/std/objspace.py Log: Minor clean-ups. 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 Jun 10 18:25:31 2004 @@ -140,11 +140,12 @@ import typeobject import sliceobject import longobject + import noneobject 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 + global W_TypeObject, W_SliceObject, W_LongObject, W_NoneObject global W_CPythonObject, W_BuiltinFunctionObject W_ObjectObject = objectobject.W_ObjectObject W_BoolObject = boolobject.W_BoolObject @@ -157,13 +158,11 @@ W_TypeObject = typeobject.W_TypeObject W_SliceObject = sliceobject.W_SliceObject W_LongObject = longobject.W_LongObject + W_NoneObject = noneobject.W_NoneObject W_CPythonObject = cpythonobject.W_CPythonObject W_BuiltinFunctionObject = cpythonobject.W_BuiltinFunctionObject # end of hacks - from noneobject import W_NoneObject - from boolobject import W_BoolObject - # singletons self.w_None = W_NoneObject(self) self.w_False = W_BoolObject(self, False) From arigo at codespeak.net Thu Jun 10 18:26:00 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 18:26:00 +0200 (MEST) Subject: [pypy-svn] r5033 - in pypy/trunk/src/pypy: interpreter interpreter/test module objspace/std Message-ID: <20040610162600.31CDC5BE1A@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 18:25:59 2004 New Revision: 5033 Modified: pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/test/test_class.py pypy/trunk/src/pypy/interpreter/typedef.py pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/objspace/std/stdtypedef.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/std/typetype.py Log: Eventually made __new__ a static method, as in CPython. Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Thu Jun 10 18:25:59 2004 @@ -235,3 +235,13 @@ return self.call(space.newtuple(list(args_w)), space.newdict([(space.wrap(key), w_item) for key, w_item in kwds_w.items()])) + +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.""" + + def __init__(self, w_function): + self.w_function = w_function + + def descr_staticmethod_get(self, w_obj, w_cls): + return self.w_function 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 Jun 10 18:25:59 2004 @@ -79,5 +79,12 @@ self.assertEquals(d.a, 42) self.assertEquals(D.a, 42) + def test___new__(self): + class A(object): + pass + self.assert_(isinstance(A(), A)) + self.assert_(isinstance(object.__new__(A), A)) + self.assert_(isinstance(A.__new__(A), A)) + 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 Thu Jun 10 18:25:59 2004 @@ -80,7 +80,7 @@ from pypy.interpreter.pycode import PyCode from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method +from pypy.interpreter.function import Function, Method, StaticMethod from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator @@ -148,6 +148,11 @@ # XXX getattribute/setattribute etc.pp ) +StaticMethod.typedef = TypeDef("staticmethod", + __get__ = interp2app(StaticMethod.descr_staticmethod_get.im_func), + # XXX getattribute etc.pp + ) + PyTraceback.typedef = TypeDef("traceback", tb_frame = attrproperty('frame'), tb_lasti = attrproperty('lasti'), 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 Jun 10 18:25:59 2004 @@ -523,6 +523,8 @@ self.fdel(obj, value) +# XXX there is an interp-level pypy.interpreter.function.StaticMethod +# XXX because __new__ needs to be a StaticMethod early. class staticmethod(object): def __init__(self, f): Modified: pypy/trunk/src/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stdtypedef.py (original) +++ pypy/trunk/src/pypy/objspace/std/stdtypedef.py Thu Jun 10 18:25:59 2004 @@ -27,7 +27,7 @@ return [self] def newmethod(descr_new): - # XXX make the result a staticmethod + # this is turned into a static method by the constructor of W_TypeObject. return gateway.interp2app(descr_new) # ____________________________________________________________ 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 Jun 10 18:25:59 2004 @@ -1,4 +1,5 @@ from pypy.objspace.std.objspace import * +from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter.typedef import attrproperty_w class W_TypeObject(W_Object): @@ -9,6 +10,7 @@ w_self.name = name w_self.bases_w = bases_w w_self.dict_w = dict_w + w_self.ensure_static__new__() w_self.needs_new_dict = False w_self.mro_w = compute_C3_mro(w_self) # XXX call type(w_self).mro() if overridetypedef is not None: @@ -40,6 +42,14 @@ elif nd: w_self.needs_new_dict = True + def ensure_static__new__(w_self): + # special-case __new__, as in CPython: + # if it is a Function, turn it into a static method + if '__new__' in w_self.dict_w: + w_new = w_self.dict_w['__new__'] + if isinstance(w_new, Function): + w_self.dict_w['__new__'] = StaticMethod(w_new) + def lookup(w_self, key): # note that this doesn't call __get__ on the result at all # XXX this should probably also return the (parent) class in which @@ -58,6 +68,10 @@ space = w_self.space if space.is_true(space.is_(w_self, w_subtype)): return w_obj + if not space.is_true(space.isinstance(w_subtype, space.w_type)): + raise OperationError(space.w_TypeError, + space.wrap("X is not a type object (%s)" % ( + space.type(w_subtype).name))) if not space.is_true(space.issubtype(w_subtype, w_self)): raise OperationError(space.w_TypeError, space.wrap("%s.__new__(%s): %s is not a subtype of %s" % ( @@ -84,7 +98,7 @@ len(args_w) == 1 and not space.is_true(w_kwds)): return space.type(args_w[0]) # invoke the __new__ of the type - w_descr = w_type.lookup('__new__') + w_descr = space.getattr(w_type, space.wrap('__new__')) w_extendedargs = space.newtuple([w_type] + args_w) w_newobject = space.call(w_descr, w_extendedargs, w_kwds) # maybe invoke the __init__ of the type 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 Thu Jun 10 18:25:59 2004 @@ -15,11 +15,6 @@ key = space.unwrap(w_key) assert isinstance(key, str) dict_w[key] = space.getitem(w_dict, w_key) - # make '__new__' an unbound method on w_typetype - # XXX check if this is correct in all cases - if '__new__' in dict_w: - dict_w['__new__'] = space.get(dict_w['__new__'], - space.w_None, w_typetype) w_type = W_TypeObject(space, name, bases_w or [space.w_object], dict_w, None) return space.w_type.check_user_subclass(w_typetype, w_type) From mwh at codespeak.net Thu Jun 10 18:29:33 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 10 Jun 2004 18:29:33 +0200 (MEST) Subject: [pypy-svn] r5034 - in pypy/trunk/src/pypy: interpreter module/test Message-ID: <20040610162933.D3CBA5BE1A@thoth.codespeak.net> Author: mwh Date: Thu Jun 10 18:29:32 2004 New Revision: 5034 Modified: pypy/trunk/src/pypy/interpreter/pyframe.py pypy/trunk/src/pypy/module/test/test_sysmodule.py Log: fix un-normalizing exception bug not certain this is the best fix Modified: pypy/trunk/src/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/src/pypy/interpreter/pyframe.py Thu Jun 10 18:29:32 2004 @@ -152,6 +152,9 @@ if frame.space.full_exceptions: w_normalized = normalize_exception(frame.space, w_type, w_value) w_type, w_value = frame.space.unpacktuple(w_normalized, 2) + # this is to make sure that sys.exc_info() etc see + # normalized exception -- not sure here is best place! + operationerr.w_value = w_value # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. Modified: pypy/trunk/src/pypy/module/test/test_sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/test/test_sysmodule.py (original) +++ pypy/trunk/src/pypy/module/test/test_sysmodule.py Thu Jun 10 18:29:32 2004 @@ -80,7 +80,16 @@ self.assertEquals(exc_type2,Exception) self.assertEquals(exc_val2,e2) self.assertEquals(tb2.tb_lineno - tb.tb_lineno, 5) - + + def test_exc_info_normalization(self): + import sys + try: + 1/0 + except ZeroDivisionError: + etype, val, tb = sys.exc_info() + self.assert_(isinstance(val, etype)) + else: + self.fail("ZeroDivisionError not caught") if __name__ == '__main__': testit.main() From arigo at codespeak.net Thu Jun 10 18:41:33 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 18:41:33 +0200 (MEST) Subject: [pypy-svn] r5035 - pypy/trunk/src/pypy/interpreter Message-ID: <20040610164133.CFC505C16B@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 18:41:32 2004 New Revision: 5035 Modified: pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/typedef.py Log: Made builtin-in __get__ methods accept only 1 argument. Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Thu Jun 10 18:41:32 2004 @@ -161,13 +161,14 @@ nkwds) raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - def descr_function_get(self, w_obj, w_cls): + def descr_function_get(self, w_obj, w_cls=None): space = self.space wrap = space.wrap - asking_for_bound = (not space.is_true(space.is_(w_obj, space.w_None)) or + asking_for_bound = (w_cls == space.w_None or + not space.is_true(space.is_(w_obj, space.w_None)) or space.is_true(space.is_(w_cls, space.type(space.w_None)))) if asking_for_bound: - if space.is_true(space.is_(w_cls, space.w_None)): + if w_cls == space.w_None: w_cls = space.type(w_obj) return wrap(Method(space, wrap(self), w_obj, w_cls)) else: @@ -243,5 +244,5 @@ def __init__(self, w_function): self.w_function = w_function - def descr_staticmethod_get(self, w_obj, w_cls): + def descr_staticmethod_get(self, w_obj, w_cls=None): return self.w_function Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Thu Jun 10 18:41:32 2004 @@ -27,10 +27,10 @@ self.fdel = fdel self.doc = doc - def descr_property_get(space, w_property, w_obj, w_ignored): + def descr_property_get(space, w_property, w_obj, w_cls=None): # XXX HAAAAAAAAAAAACK (but possibly a good one) - if w_obj == space.w_None and not space.is_true(space.is_(w_ignored, space.type(space.w_None))): - #print w_property, w_obj, w_ignored + if w_obj == space.w_None and not space.is_true(space.is_(w_cls, space.type(space.w_None))): + #print w_property, w_obj, w_cls return w_property else: return space.unwrap(w_property).fget(space, w_obj) From arigo at codespeak.net Thu Jun 10 18:59:59 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 18:59:59 +0200 (MEST) Subject: [pypy-svn] r5036 - pypy/trunk/src/pypy/module Message-ID: <20040610165959.B1CDA5C16D@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 18:59:58 2004 New Revision: 5036 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: Bug fix. 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 Jun 10 18:59:58 2004 @@ -434,7 +434,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, _pypy_get +from __interplevel__ import issubclass from __interplevel__ import compile, eval from __interplevel__ import globals, locals, _caller_globals, _caller_locals @@ -520,7 +520,7 @@ def __delete__(self, obj): if self.fdel is None: raise AttributeError, "can't delete attribute" - self.fdel(obj, value) + self.fdel(obj) # XXX there is an interp-level pypy.interpreter.function.StaticMethod @@ -949,124 +949,7 @@ # ________________________________________________________________________ -## def app___import__(*args): -## # NOTE: No import statements can be done in this function, -## # as that would involve a recursive call to this function ... -## -## # args => (name[, globals[, locals[, fromlist]]]) -## -## l = len(args) -## if l >= 1: -## modulename = args[0] -## else: -## raise TypeError('__import__() takes at least 1 argument (0 given)') -## if l >= 2: -## globals = args[1] -## try: -## local_context = self.imp_dirname(globals['__file__']) -## except KeyError: -## local_context = '' -## else: -## local_context = '' -## if l >= 4: -## fromlist = args[3] -## else: -## fromlist = [] -## if l > 4: -## raise TypeError('__import__() takes at most 4 arguments (%i given)' % l) -## -## def inner_load(f, fullname): -## """Load module from file `f` with canonical name `fullname`. -## """ -## mod = self.imp_module(fullname) # XXX - add in docstring -## self.imp_modules[fullname] = mod -## mod.__file__ = f -## dict = mod.__dict__ -## execfile(f, dict, dict) -## return mod -## -## def load(path, modulename, fullname): -## """Create a module. -## -## Create a mnodule with canonical name `fullname` from file -## `modulename`+'.py' in path `path`, if it exist. -## Or alternatively from the package -## `path`/`modulename`/'__init__.py'. -## If neither are found, return None. -## """ -## -## f = self.imp_join(path, modulename + '.py') -## if self.imp_exists(f): -## return inner_load(f, fullname) -## f = self.imp_join(path, modulename, '__init__.py') -## if self.imp_exists(f): -## return inner_load(f, fullname) -## else: -## return None -## -## names = modulename.split('.') -## -## if not names: -## raise ValueError("Cannot import an empty module name.") -## if len(names) == 1: -## if self.imp_modules.has_key(modulename): -## return self.imp_modules[modulename] -## #Relative Import -## if local_context: -## #Regular Module -## module = load(local_context, modulename, modulename) -## if module: -## return module -## #Standard Library Module Import -## for path in self.imp_path: -## #Regular Module -## module = load(path, modulename, modulename) -## if module: -## return module -## #Module Not Found -## raise ImportError(modulename) -## else: -## #Find most specific module already imported. -## for i in range(len(names),0,-1): -## base_name = '.'.join(names[0:i]) -## if self.imp_modules.has_key(base_name): -## break -## #Top level package not imported - import it. -## else: -## base_name = names[0] -## i = 1 -## #Relative Import -## if ((not local_context) or -## not load(local_context, base_name, base_name)): -## #Standard Module Import -## for path in self.imp_path: -## if load(path, base_name, base_name): -## break -## else: -## #Module Not Found -## raise ImportError(base_name) -## path = self.imp_dirname(self.imp_modules[base_name].__file__) -## full_name = base_name -## for j in range(i,len(names)): -## path = self.imp_join(path, names[j]) -## full_name = '.'.join((full_name, names[j])) -## if not load(path, '__init__', full_name): -## raise ImportError(full_name) -## ### load module from path -## if fromlist: -## return self.imp_modules[modulename] -## else: -## return self.imp_modules[names[0]] -## -## # Interpreter level helpers for app level import -## def imp_dirname(*args_w): -## return self.space.wrap(os.path.dirname(*self.space.unwrap(args_w))) -## -## def imp_join(*args_w): -## return self.space.wrap(os.path.join(*self.space.unwrap(args_w))) -## -## def imp_exists(*args_w): -## return self.space.wrap(os.path.exists(*self.space.unwrap(args_w))) -## -## def imp_module(w_name): -## return self.space.wrap(Module(self.space, w_name)) + +class buffer: + def __init__(self, object, offset=None, size=None): + raise NotImplementedError, "XXX nobody needs this anyway" From arigo at codespeak.net Thu Jun 10 19:15:37 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 19:15:37 +0200 (MEST) Subject: [pypy-svn] r5037 - pypy/trunk/src/pypy/appspace Message-ID: <20040610171537.665B55C16D@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 19:15:27 2004 New Revision: 5037 Modified: pypy/trunk/src/pypy/appspace/types.py Log: Fixed buffer name usage. Modified: pypy/trunk/src/pypy/appspace/types.py ============================================================================== --- pypy/trunk/src/pypy/appspace/types.py (original) +++ pypy/trunk/src/pypy/appspace/types.py Thu Jun 10 19:15:27 2004 @@ -43,7 +43,7 @@ StringTypes = (StringType,) try: - BufferType = type(buffer('')) + BufferType = buffer except NameError: pass From arigo at codespeak.net Thu Jun 10 19:16:39 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 19:16:39 +0200 (MEST) Subject: [pypy-svn] r5038 - in pypy/trunk/src/pypy: module module/test objspace/std Message-ID: <20040610171639.C564C5C170@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 19:16:33 2004 New Revision: 5038 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 pypy/trunk/src/pypy/module/test/test_newstyleclasses.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: - fixed super to use __getattribute__ instead of __getattr__ - corresponding tests - added object.__init__() 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 Jun 10 19:16:33 2004 @@ -301,8 +301,3 @@ def setattr(w_object, w_name, w_val): space.setattr(w_object, w_name, w_val) return space.w_None - -def _pypy_get(w_value, w_self, w_class=None): # XXX temporary - if w_class is None: - w_class = space.w_None - return space.get(w_value, w_self, w_class) 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 Jun 10 19:16:33 2004 @@ -563,6 +563,7 @@ # 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): @@ -570,14 +571,18 @@ else: self.__self_class__ = obj def __get__(self, obj, type=None): - if self.__self__ is None and obj is not None: - return super(self.__thisclass__, obj) + ga = object.__getattribute__ + if ga(self, '__self__') is None and obj is not None: + return super(ga(self, '__thisclass__'), obj) else: return self - def __getattr__(self, attr): - mro = iter(self.__self_class__.__mro__) + 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 self.__thisclass__: + if cls is d['__thisclass__']: break # Note: mro is an iterator, so the second loop # picks up where the first one left off! @@ -587,7 +592,7 @@ except KeyError: continue if hasattr(x, '__get__'): - x = x.__get__(self.__self__, type(self.__self__)) + x = x.__get__(d['__self__'], type(d['__self__'])) return x raise AttributeError, attr 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 Jun 10 19:16:33 2004 @@ -230,22 +230,6 @@ self.assertRaises(TypeError, hash, []) self.assertRaises(TypeError, hash, {}) - def test_super(self): - class A: - def f(self): - return 'A' - class B(A): - def f(self): - return 'B' + super(B,self).f() - class C(A): - def f(self): - return 'C' + super(C,self).f() - class D(B, C): - def f(self): - return 'D' + super(D,self).f() - d = D() - self.assertEquals(d.f(), "DBCA") - class TestInternal(testit.IntTestCase): Modified: pypy/trunk/src/pypy/module/test/test_newstyleclasses.py ============================================================================== --- pypy/trunk/src/pypy/module/test/test_newstyleclasses.py (original) +++ pypy/trunk/src/pypy/module/test/test_newstyleclasses.py Thu Jun 10 19:16:33 2004 @@ -36,7 +36,7 @@ self.assertEquals(d.f("abc"), (D, "abc")) self.assertEquals(D.f("abc"), (D, "abc")) - def xtest_property_simple(self): + def test_property_simple(self): class a(object): def _get(self): return 42 @@ -48,5 +48,30 @@ self.assertRaises(AttributeError, setattr, a1, 'name', 42) self.assertRaises(KeyError, delattr, a1, 'name') + def test_super(self): + class A: + def f(self): + return 'A' + class B(A): + def f(self): + return 'B' + super(B,self).f() + class C(A): + def f(self): + return 'C' + super(C,self).f() + class D(B, C): + def f(self): + return 'D' + super(D,self).f() + d = D() + self.assertEquals(d.f(), "DBCA") + + def test_super_metaclass(self): + class xtype(type): + def __init__(self, name, bases, dict): + super(xtype, self).__init__(name, bases, dict) + A = xtype('A', (), {}) + self.assert_(isinstance(A, xtype)) + a = A() + self.assert_(isinstance(a, A)) + if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Thu Jun 10 19:16:33 2004 @@ -26,6 +26,9 @@ w_obj = W_ObjectObject(space) return space.w_object.check_user_subclass(w_type, w_obj) +def descr__init__(space, *args_w, **kwds_w): + pass # XXX 2.2. behavior: ignoring all arguments + # ____________________________________________________________ object_typedef = StdTypeDef("object", [], @@ -37,4 +40,5 @@ __hash__ = gateway.interp2app(descr__hash__), __class__ = GetSetProperty(descr__class__), __new__ = newmethod(descr__new__), + __init__ = gateway.interp2app(descr__init__), ) 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 Jun 10 19:16:33 2004 @@ -237,7 +237,7 @@ SlotWrapperType = type(type(None).__repr__) if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, SlotWrapperType)): return W_BuiltinFunctionObject(self, x) - #print "cpython wrapping %r" % (x,) + print "cpython wrapping %r" % (x,) #if hasattr(x, '__bases__'): # print "cpython wrapping a class %r (%s)" % (x, type(x)) #raise TypeError, "cannot wrap classes" From arigo at codespeak.net Thu Jun 10 19:21:35 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 19:21:35 +0200 (MEST) Subject: [pypy-svn] r5039 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040610172135.D47DE5C16B@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 19:21:34 2004 New Revision: 5039 Modified: pypy/trunk/src/pypy/objspace/std/intobject.py Log: Typo. 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 Thu Jun 10 19:21:34 2004 @@ -303,7 +303,7 @@ raise OperationError(space.w_ValueError, space.wrap("negative shift count")) if a == 0 or b == 0: - return Int_pos(w_int1) + return pos__Int(w_int1) if b >= LONG_BIT: raise FailedToImplement(space.w_OverflowError, space.wrap("integer left shift")) From arigo at codespeak.net Thu Jun 10 19:26:44 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 10 Jun 2004 19:26:44 +0200 (MEST) Subject: [pypy-svn] r5040 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040610172644.C75735C16E@thoth.codespeak.net> Author: arigo Date: Thu Jun 10 19:26:43 2004 New Revision: 5040 Modified: pypy/trunk/src/pypy/objspace/std/intobject.py Log: Same typo as the previous check-in, just a few lines off. 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 Thu Jun 10 19:26:43 2004 @@ -303,7 +303,7 @@ raise OperationError(space.w_ValueError, space.wrap("negative shift count")) if a == 0 or b == 0: - return pos__Int(w_int1) + return pos__Int(space, w_int1) if b >= LONG_BIT: raise FailedToImplement(space.w_OverflowError, space.wrap("integer left shift")) @@ -333,7 +333,7 @@ raise OperationError(space.w_ValueError, space.wrap("negative shift count")) if a == 0 or b == 0: - return Int_pos(w_int1) + return pos__Int(space, w_int1) if b >= LONG_BIT: if a < 0: a = -1 From hpk at codespeak.net Thu Jun 10 19:29:13 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 10 Jun 2004 19:29:13 +0200 (MEST) Subject: [pypy-svn] r5041 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040610172913.55A125C170@thoth.codespeak.net> Author: hpk Date: Thu Jun 10 19:29:12 2004 New Revision: 5041 Removed: pypy/trunk/src/pypy/objspace/std/concretespace.py Modified: pypy/trunk/src/pypy/objspace/std/test/test_intobject.py Log: - remove obsolete 'concretespace.py' file - test that shift left/right with 0 returns the first obj Deleted: /pypy/trunk/src/pypy/objspace/std/concretespace.py ============================================================================== --- /pypy/trunk/src/pypy/objspace/std/concretespace.py Thu Jun 10 19:29:12 2004 +++ (empty file) @@ -1,62 +0,0 @@ -# I (mwh) wanted to get some stuff out of objspace.py - -# this file is intended to contain implementations of most of the -# "concrete objects" layer of the Python/C API - -# the idea is, roughly, e.g.: -# -# PyInt_FromLong -> space.int.from_long(w_int) -# PyList_GetItem -> space.list.getitem(w_list, i) -# -# etc. - -# I'm not sure this is a good idea. - -class ConcreteSpace(object): - __slots__ = ['space'] - def __init__(self, space): - self.space = space - -class IntObjSpace(ConcreteSpace): - __slots__ = [] - def check(self, ob): - return isinstance(ob, self.space.W_IntObject) - def check_exact(self, ob): - return ob.__class__ is self.space.W_IntObject - def from_string(self, s, base): - return self.from_long(int(s, base)) - def from_unicode(self, u, base): - return self.from_long(int(u, base)) - def from_long(self, l): - return self.space.W_IntObject(l) - def as_long(self, w_int): - if self.check(w_int): - return w_int.intval - else: - # XXX argh. should attempt conversion - raise OperationError( - self.space.w_TypeError, - self.space.W_StringObject("an integer is required")) - def get_max(self): - import sys - return self.from_long(sys.maxint) - -class FloatObjSpace(ConcreteSpace): - __slots__ = [] - def check(self, ob): - return isinstance(ob, self.space.W_FloatObject) - def check_exact(self, ob): - return ob.__class__ is self.space.W_FloatObject - def from_string(self, w_str): - return self.from_double(float(w_str)) - def from_double(self, d): - return self.space.W_FloatObject(d) - def as_double(self, w_float): - if self.check(w_float): - return w_float.floatval - else: - # XXX argh. should attempt conversion - raise OperationError( - self.space.w_TypeError, - self.space.W_StringObject("a float is required")) - 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 Thu Jun 10 19:29:12 2004 @@ -312,6 +312,9 @@ self.assertEquals(42, int('42', 10)) self.assertRaises(TypeError, int, 1, 10) + def test_shift_zeros(self): + assert (1 << 0) == 1 + assert (1 >> 0) == 1 if __name__ == '__main__': testit.main() From hpk at codespeak.net Thu Jun 10 20:32:25 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 10 Jun 2004 20:32:25 +0200 (MEST) Subject: [pypy-svn] r5042 - in pypy/trunk/src/pypy: appspace module Message-ID: <20040610183225.335BA5C16F@thoth.codespeak.net> Author: hpk Date: Thu Jun 10 20:32:22 2004 New Revision: 5042 Added: pypy/trunk/src/pypy/appspace/operator.py Modified: pypy/trunk/src/pypy/module/sysinterp.py Log: do operator.py at applevel Added: pypy/trunk/src/pypy/appspace/operator.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/operator.py Thu Jun 10 20:32:22 2004 @@ -0,0 +1,132 @@ +def abs(obj,): + 'abs(a) -- Same as abs(a).' + return abs(obj) +def add(obj1, obj2): + 'add(a, b) -- Same as a + b.' + return obj1 + obj2 +def and_(obj1,obj2): + 'and_(a, b) -- Same as a & b.' + return obj1 & obj2 +def concat(obj1, obj2): + 'concat(a, b) -- Same as a + b, for a and b sequences.' + return obj1 + obj2 # XXX +def contains(obj1,obj2): + 'contains(a, b) -- Same as b in a (note reversed operands).' + return obj2 in obj1 +def countOf(a,b): + 'countOf(a, b) -- Return the number of times b occurs in a.' + raise NotImplementedError +def delitem(obj, key): + 'delitem(a, b) -- Same as del a[b].' + del obj[key] +def delslice(obj, start, end): + 'delslice(a, b, c) -- Same as del a[b:c].' + del obj[start:end] +def div(a,b): + 'div(a, b) -- Same as a / b when __future__.division is not in effect.' + return a / b +def eq(a, b): + 'eq(a, b) -- Same as a==b.' + return a == b +def floordiv(a, b): + 'floordiv(a, b) -- Same as a // b.' + return a // b +def ge(a, b): + 'ge(a, b) -- Same as a>=b.' + return a >= b +def getitem(a, b): + 'getitem(a, b) -- Same as a[b].' + return a[b] +def getslice(a, start, end): + 'getslice(a, b, c) -- Same as a[b:c].' + return a[start:end] +def gt(a,b): + 'gt(a, b) -- Same as a>b.' + return a > b +def indexOf(a, b): + 'indexOf(a, b) -- Return the first index of b in a.' + raise NotImplementedError +def inv(obj,): + 'inv(a) -- Same as ~a.' + return ~obj +def invert(obj,): + 'invert(a) -- Same as ~a.' + return ~obj +def isCallable(obj,): + 'isCallable(a) -- Same as callable(a).' + return callable(obj) +def isMappingType(obj,): + 'isMappingType(a) -- Return True if a has a mapping type, False otherwise.' + return hasattr(obj, '__getitem__') # Xxx only close +def isNumberType(obj,): + 'isNumberType(a) -- Return True if a has a numeric type, False otherwise.' + return hasattr(obj, '__int__') or hasattr(obj, '__float__') +def isSequenceType(obj,): + 'isSequenceType(a) -- Return True if a has a sequence type, False otherwise.' + return hasattr(obj, '__getitem__') # Xxx only close +def is_(a, b): + 'is_(a, b) -- Same as a is b.' + return a is b +def is_not(a, b): + 'is_not(a, b) -- Same as a is not b.' + return a is not b +def le(a, b): + 'le(a, b) -- Same as a<=b.' + return a <= b +def lshift(a, b): + 'lshift(a, b) -- Same as a << b.' + return a << b +def lt(a, b): + 'lt(a, b) -- Same as a> b.' + return a >> b +def sequenceIncludes(a, b): + 'sequenceIncludes(a, b) -- Same as b in a (note reversed operands; deprecated).' + raise NotImplementedError +def setitem(obj, key, value): + 'setitem(a, b, c) -- Same as a[b] = c.' + obj[key] = value +def setslice(a, b, c, d): + 'setslice(a, b, c, d) -- Same as a[b:c] = d.' + a[b:c] = d +def sub(a, b): + 'sub(a, b) -- Same as a - b.' + return a - b +def truediv(a, b): + 'truediv(a, b) -- Same as a / b when __future__.division is in effect.' + return a / b +def truth(a,): + 'truth(a) -- Return True if a is true, False otherwise.' + return not not a +def xor(a, b): + 'xor(a, b) -- Same as a ^ b.' + return a ^ b Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Thu Jun 10 20:32:22 2004 @@ -39,7 +39,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', 'operator', + 'cStringIO', 'itertools', 'math', '_random', '_sre', 'time', 'imp', '_socket', 'errno', 'marshal', 'struct', 'binascii']: if fn not in builtin_modules: From mwh at codespeak.net Fri Jun 11 12:03:11 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 11 Jun 2004 12:03:11 +0200 (MEST) Subject: [pypy-svn] r5043 - pypy/trunk/src/pypy Message-ID: <20040611100311.903525BE16@thoth.codespeak.net> Author: mwh Date: Fri Jun 11 12:03:09 2004 New Revision: 5043 Modified: pypy/trunk/src/pypy/TODO Log: updates Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Fri Jun 11 12:03:09 2004 @@ -1,20 +1,18 @@ -* String Formatting: the % mod operator needs to be implemented - for dicts and the current hack for tuples (which just unwraps - to cpython and calls the % operator) needs to be properly - written at interp- or app-level. +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, ...) * Provide an importer that can import packages. (we have a - limited __import__ builtin defined) + limited __import__ builtin defined) <---- done now? Consider PEP 302, new import hooks. Try to write as much as possible in app-level. How would PyPy import CPython extensions? -* Implements super. Guido's paper, descrintro, has a pure Python - implementation. Let it run on PyPy. (as of r3461, it doesn't run.) - -* Supports traceback. At least sys.exc_info. (Many modules expect it.) - * (documentation) generate a nice dot-graph from the structure of PyPy * port pypy's testing framework to std.utest (probably a sprint topic, @@ -23,9 +21,6 @@ * (documentation) remove/retire all web-pages referencing e.g. AnnSpace or other deprecated stuff -* make application-level types work for (1) StdObjSpace types and (2) - core interpreter objects. - * 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 @@ -42,8 +37,16 @@ http://codespeak.net/pypy/index.cgi?doc/objspace/multimethod + (now irrelevant? not sure...) + +Translator +========== + * enhance the translator components to accept more of PyPy ... +Tools +===== + * add web server thread (!) that allows inspection of e.g. app-level tracebacks (and stop clogging the user's terminal with them). From mwh at codespeak.net Fri Jun 11 12:20:37 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 11 Jun 2004 12:20:37 +0200 (MEST) Subject: [pypy-svn] r5044 - pypy/trunk/src/pypy/appspace Message-ID: <20040611102037.D07DD5BE16@thoth.codespeak.net> Author: mwh Date: Fri Jun 11 12:20:36 2004 New Revision: 5044 Modified: pypy/trunk/src/pypy/appspace/operator.py Log: improvements to operator.py Modified: pypy/trunk/src/pypy/appspace/operator.py ============================================================================== --- pypy/trunk/src/pypy/appspace/operator.py (original) +++ pypy/trunk/src/pypy/appspace/operator.py Fri Jun 11 12:20:36 2004 @@ -1,57 +1,72 @@ def abs(obj,): 'abs(a) -- Same as abs(a).' return abs(obj) +__abs__ = abs def add(obj1, obj2): 'add(a, b) -- Same as a + b.' - return obj1 + obj2 + return obj1 + obj2 +__add__ = add def and_(obj1,obj2): 'and_(a, b) -- Same as a & b.' - return obj1 & obj2 + return obj1 & obj2 +__and__ = and_ def concat(obj1, obj2): 'concat(a, b) -- Same as a + b, for a and b sequences.' return obj1 + obj2 # XXX def contains(obj1,obj2): 'contains(a, b) -- Same as b in a (note reversed operands).' return obj2 in obj1 +__contains__ = contains def countOf(a,b): 'countOf(a, b) -- Return the number of times b occurs in a.' raise NotImplementedError def delitem(obj, key): 'delitem(a, b) -- Same as del a[b].' del obj[key] +__delitem__ = delitem def delslice(obj, start, end): 'delslice(a, b, c) -- Same as del a[b:c].' del obj[start:end] +__delslice__ = delslice def div(a,b): 'div(a, b) -- Same as a / b when __future__.division is not in effect.' return a / b +__div__ = div def eq(a, b): 'eq(a, b) -- Same as a==b.' return a == b +__eq__ = eq def floordiv(a, b): 'floordiv(a, b) -- Same as a // b.' return a // b +__floordiv__ = floordiv def ge(a, b): 'ge(a, b) -- Same as a>=b.' return a >= b +__ge__ = ge def getitem(a, b): 'getitem(a, b) -- Same as a[b].' return a[b] +__getitem__ = getitem def getslice(a, start, end): 'getslice(a, b, c) -- Same as a[b:c].' return a[start:end] +__getslice__ = getslice def gt(a,b): 'gt(a, b) -- Same as a>b.' return a > b +__gt__ = gt def indexOf(a, b): 'indexOf(a, b) -- Return the first index of b in a.' raise NotImplementedError def inv(obj,): 'inv(a) -- Same as ~a.' return ~obj +__inv__ = inv def invert(obj,): 'invert(a) -- Same as ~a.' return ~obj +__invert__ = invert def isCallable(obj,): 'isCallable(a) -- Same as callable(a).' return callable(obj) @@ -73,60 +88,83 @@ def le(a, b): 'le(a, b) -- Same as a<=b.' return a <= b +__le__ = le def lshift(a, b): 'lshift(a, b) -- Same as a << b.' return a << b +__lshift__ = lshift def lt(a, b): 'lt(a, b) -- Same as a> b.' return a >> b +__rshift__ = rshift def sequenceIncludes(a, b): 'sequenceIncludes(a, b) -- Same as b in a (note reversed operands; deprecated).' raise NotImplementedError def setitem(obj, key, value): 'setitem(a, b, c) -- Same as a[b] = c.' obj[key] = value +__setitem__ = setitem def setslice(a, b, c, d): 'setslice(a, b, c, d) -- Same as a[b:c] = d.' a[b:c] = d +__setslice__ = setslice def sub(a, b): 'sub(a, b) -- Same as a - b.' return a - b +__sub__ = sub def truediv(a, b): 'truediv(a, b) -- Same as a / b when __future__.division is in effect.' return a / b +__truediv__ = truediv def truth(a,): 'truth(a) -- Return True if a is true, False otherwise.' return not not a def xor(a, b): 'xor(a, b) -- Same as a ^ b.' return a ^ b +__xor__ = xor + +# ugh: +import types as _types +for n in globals(): + v = globals()[n] + if isinstance(v, _types.FunctionType): + globals()[n] = staticmethod(v) From arigo at codespeak.net Fri Jun 11 13:00:42 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 13:00:42 +0200 (MEST) Subject: [pypy-svn] r5045 - pypy/trunk/src/pypy/module Message-ID: <20040611110042.832D45BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 13:00:41 2004 New Revision: 5045 Modified: pypy/trunk/src/pypy/module/__builtin__interp.py Log: If application-level overrides sys.path with a new list object, it still works now. But it would be nice to have a general solution to this problem. 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 Fri Jun 11 13:00:41 2004 @@ -131,7 +131,9 @@ w_mod = None parts = modulename.split('.') prefix = [] - w_path = space.sys.w_path + # it would be nice if we could do here: w_path = space.sys.w_path + # instead: + w_path = space.getitem(space.sys.w_dict, space.wrap('path')) first = None level = 0 From mwh at codespeak.net Fri Jun 11 13:01:21 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 11 Jun 2004 13:01:21 +0200 (MEST) Subject: [pypy-svn] r5046 - pypy/trunk/src/pypy/interpreter Message-ID: <20040611110121.AEFC95BE16@thoth.codespeak.net> Author: mwh Date: Fri Jun 11 13:01:20 2004 New Revision: 5046 Modified: pypy/trunk/src/pypy/interpreter/nestedscope.py pypy/trunk/src/pypy/interpreter/typedef.py Log: make Cell Wrappable Modified: pypy/trunk/src/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/nestedscope.py (original) +++ pypy/trunk/src/pypy/interpreter/nestedscope.py Fri Jun 11 13:01:20 2004 @@ -2,9 +2,9 @@ from pypy.interpreter.eval import UNDEFINED from pypy.interpreter.pyopcode import PyInterpFrame from pypy.interpreter import function, pycode +from pypy.interpreter.baseobjspace import Wrappable - -class Cell(object): +class Cell(Wrappable): "A simple container for a wrapped value." def __init__(self, w_value=UNDEFINED): Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Fri Jun 11 13:01:20 2004 @@ -83,6 +83,7 @@ from pypy.interpreter.function import Function, Method, StaticMethod from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator +from pypy.interpreter.nestedscope import Cell Code.typedef = TypeDef('internal-code', co_name = attrproperty('co_name'), @@ -166,3 +167,5 @@ gi_running = attrproperty('running'), gi_frame = attrproperty('frame'), ) + +Cell.typedef = TypeDef("Cell") From mwh at codespeak.net Fri Jun 11 13:02:43 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 11 Jun 2004 13:02:43 +0200 (MEST) Subject: [pypy-svn] r5047 - pypy/trunk/src/pypy/module Message-ID: <20040611110243.1253C5BE16@thoth.codespeak.net> Author: mwh Date: Fri Jun 11 13:02:42 2004 New Revision: 5047 Modified: pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/__builtin__module.py Log: support optional prompt to raw_input() hacks to try_getattr (see comments) 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 Fri Jun 11 13:02:42 2004 @@ -52,8 +52,8 @@ try: return space.getattr(w_obj, w_name) except OperationError, e: - if not e.match(space, space.w_AttributeError): - raise + # ugh, but blame CPython :-/ this is supposed to emulate + # hasattr, which eats all exceptions. return None def try_getitem(w_obj,w_key): 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 Jun 11 13:02:42 2004 @@ -31,8 +31,11 @@ co = compile(source, filename, 'exec') exec co in glob, loc -def raw_input(): +def raw_input(prompt=None): import sys + if prompt is not None: + sys.stdout.write(prompt) + sys.stdout.flush() return sys.stdin.readline() # XXX review def input(): From arigo at codespeak.net Fri Jun 11 13:08:03 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 13:08:03 +0200 (MEST) Subject: [pypy-svn] r5048 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040611110803.9FC7E5BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 13:08:02 2004 New Revision: 5048 Modified: pypy/trunk/src/pypy/objspace/std/test/test_instmethobject.py Log: Fixed broken test. Modified: pypy/trunk/src/pypy/objspace/std/test/test_instmethobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_instmethobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_instmethobject.py Fri Jun 11 13:08:02 2004 @@ -21,13 +21,13 @@ def test_getBound(self): def f(l,x): return l[x+1] - bound = _pypy_get(f, 'abcdef') # XXX replace with f.__get__() + bound = f.__get__('abcdef') self.assertEquals(bound(1), 'c') self.assertRaises(TypeError, bound) self.assertRaises(TypeError, bound, 2, 3) def test_getUnbound(self): def f(l,x): return l[x+1] - unbound = _pypy_get(f, None, str) # XXX replace with f.__get__() + unbound = f.__get__(None, str) self.assertEquals(unbound('abcdef', 2), 'd') self.assertRaises(TypeError, unbound) self.assertRaises(TypeError, unbound, 4) From arigo at codespeak.net Fri Jun 11 14:19:55 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 14:19:55 +0200 (MEST) Subject: [pypy-svn] r5049 - pypy/trunk/src/pypy/module Message-ID: <20040611121955.27B695BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 14:19:54 2004 New Revision: 5049 Modified: pypy/trunk/src/pypy/module/sysinterp.py pypy/trunk/src/pypy/module/sysmodule.py Log: Renamed w_path into w_initialpath. Seems that our autopath.py is buggy and removes .../appspace from sys.path. Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Fri Jun 11 14:19:54 2004 @@ -63,7 +63,7 @@ # Initialize the default path srcdir = os.path.dirname(autopath.pypydir) appdir = os.path.join(autopath.pypydir, 'appspace') -w_path = space.newlist([space.wrap(''), space.wrap(appdir)] + +w_initialpath = space.newlist([space.wrap(''), space.wrap(appdir)] + [space.wrap(p) for p in cpy_sys.path if p!= srcdir]) # XXX - Replace with appropriate PyPy version numbering Modified: pypy/trunk/src/pypy/module/sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/sysmodule.py (original) +++ pypy/trunk/src/pypy/module/sysmodule.py Fri Jun 11 14:19:54 2004 @@ -5,7 +5,8 @@ __interplevel__execfile('sysinterp.py') # Common data structures -from __interplevel__ import path, modules, argv +from __interplevel__ import initialpath as path +from __interplevel__ import modules, argv from __interplevel__ import warnoptions, builtin_module_names # Objects from interpreter-level From arigo at codespeak.net Fri Jun 11 14:25:36 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 14:25:36 +0200 (MEST) Subject: [pypy-svn] r5050 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040611122536.593015BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 14:25:35 2004 New Revision: 5050 Modified: pypy/trunk/src/pypy/objspace/std/listobject.py Log: [].remove(x) -> ValueError instead of IndexError. Modified: pypy/trunk/src/pypy/objspace/std/listobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/listobject.py Fri Jun 11 14:25:35 2004 @@ -395,7 +395,7 @@ if space.is_true(cmp): _del_slice(w_list, i, i+1) return space.w_None - raise OperationError(space.w_IndexError, + raise OperationError(space.w_ValueError, space.wrap("list.remove(x): x not in list")) def list_index__List_ANY_Int_Int(space, w_list, w_any, w_start, w_stop): From arigo at codespeak.net Fri Jun 11 14:26:54 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 14:26:54 +0200 (MEST) Subject: [pypy-svn] r5051 - in pypy/trunk/src/pypy: annotation/test appspace appspace/test interpreter interpreter/test module/test objspace/flow/test objspace/std/test objspace/test tool tool/test tool/testdata translator/test translator/tool translator/tool/pygame Message-ID: <20040611122654.B079A5BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 14:26:53 2004 New Revision: 5051 Modified: pypy/trunk/src/pypy/annotation/test/autopath.py pypy/trunk/src/pypy/appspace/autopath.py pypy/trunk/src/pypy/appspace/test/autopath.py pypy/trunk/src/pypy/interpreter/autopath.py pypy/trunk/src/pypy/interpreter/test/autopath.py pypy/trunk/src/pypy/module/test/autopath.py pypy/trunk/src/pypy/objspace/flow/test/autopath.py pypy/trunk/src/pypy/objspace/std/test/autopath.py pypy/trunk/src/pypy/objspace/test/autopath.py pypy/trunk/src/pypy/tool/autopath.py pypy/trunk/src/pypy/tool/test/autopath.py pypy/trunk/src/pypy/tool/testdata/autopath.py pypy/trunk/src/pypy/translator/test/autopath.py pypy/trunk/src/pypy/translator/tool/autopath.py pypy/trunk/src/pypy/translator/tool/pygame/autopath.py Log: autopath used to remove too much from sys.path. Modified: pypy/trunk/src/pypy/annotation/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/annotation/test/autopath.py (original) +++ pypy/trunk/src/pypy/annotation/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/appspace/autopath.py ============================================================================== --- pypy/trunk/src/pypy/appspace/autopath.py (original) +++ pypy/trunk/src/pypy/appspace/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/appspace/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/appspace/test/autopath.py (original) +++ pypy/trunk/src/pypy/appspace/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/interpreter/autopath.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/autopath.py (original) +++ pypy/trunk/src/pypy/interpreter/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/interpreter/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/autopath.py (original) +++ pypy/trunk/src/pypy/interpreter/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/module/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/module/test/autopath.py (original) +++ pypy/trunk/src/pypy/module/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/objspace/flow/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/autopath.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/objspace/std/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/autopath.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/objspace/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/objspace/test/autopath.py (original) +++ pypy/trunk/src/pypy/objspace/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/tool/autopath.py ============================================================================== --- pypy/trunk/src/pypy/tool/autopath.py (original) +++ pypy/trunk/src/pypy/tool/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/tool/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/tool/test/autopath.py (original) +++ pypy/trunk/src/pypy/tool/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/tool/testdata/autopath.py ============================================================================== --- pypy/trunk/src/pypy/tool/testdata/autopath.py (original) +++ pypy/trunk/src/pypy/tool/testdata/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/translator/test/autopath.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/autopath.py (original) +++ pypy/trunk/src/pypy/translator/test/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/translator/tool/autopath.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/autopath.py (original) +++ pypy/trunk/src/pypy/translator/tool/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) Modified: pypy/trunk/src/pypy/translator/tool/pygame/autopath.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/pygame/autopath.py (original) +++ pypy/trunk/src/pypy/translator/tool/pygame/autopath.py Fri Jun 11 14:26:53 2004 @@ -37,9 +37,11 @@ partdir = head head, tail = os.path.split(head) if tail == part: - sys.path = [p for p in sys.path if not p.startswith(head)] - if head not in sys.path: - sys.path.insert(0, head) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) return partdir, this_dir raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) From arigo at codespeak.net Fri Jun 11 14:38:23 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 14:38:23 +0200 (MEST) Subject: [pypy-svn] r5052 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040611123823.B52E45BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 14:38:22 2004 New Revision: 5052 Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/default.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: Improved internal __repr__ and unwrap error message. Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Fri Jun 11 14:38:22 2004 @@ -5,6 +5,7 @@ from pypy.interpreter.function import Function from stringobject import W_StringObject from intobject import W_IntObject +from default import UnwrapError import sys, operator, types class W_BuiltinFunctionObject(Function): @@ -19,11 +20,14 @@ def call(self, w_args, w_kwds): space = self.space - args = space.unwrap(w_args) - kwds = {} - keys_w = space.unpackiterable(w_kwds) - for w_key in keys_w: - kwds[space.unwrap(w_key)] = space.unwrap(space.getitem(w_kwds, w_key)) + try: + args = space.unwrap(w_args) + kwds = {} + keys_w = space.unpackiterable(w_kwds) + for w_key in keys_w: + kwds[space.unwrap(w_key)] = space.unwrap(space.getitem(w_kwds, w_key)) + except UnwrapError, e: + raise UnwrapError('calling %s: %s' % (self.cpyfunc, e)) try: result = apply(self.cpyfunc, args, kwds) except: Modified: pypy/trunk/src/pypy/objspace/std/default.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/default.py (original) +++ pypy/trunk/src/pypy/objspace/std/default.py Fri Jun 11 14:38:22 2004 @@ -216,11 +216,14 @@ # ugh +class UnwrapError(Exception): + pass + def unwrap__ANY(space, w_obj): if isinstance(w_obj, Wrappable): return w_obj else: - raise TypeError, 'cannot unwrap %r' % (w_obj,) + raise UnwrapError, 'cannot unwrap %r' % (w_obj,) register_all(vars()) 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 Jun 11 14:38:22 2004 @@ -13,11 +13,14 @@ w_self.space = space # XXX not sure this is ever used any more def __repr__(self): - return '%s(%s)' % ( + s = '%s(%s)' % ( self.__class__.__name__, #', '.join(['%s=%r' % keyvalue for keyvalue in self.__dict__.items()]) getattr(self, 'name', '') ) + if hasattr(self, 'w__class__'): + s += ' instance of %s' % self.w__class__ + return '<%s>' % s # delegation priorities PRIORITY_SAME_TYPE = 2 # converting between several impls of the same type From arigo at codespeak.net Fri Jun 11 14:57:55 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 14:57:55 +0200 (MEST) Subject: [pypy-svn] r5053 - in pypy/trunk/src/pypy: interpreter objspace objspace/std Message-ID: <20040611125755.69D845BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 14:57:54 2004 New Revision: 5053 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/pyframe.py pypy/trunk/src/pypy/objspace/std/default.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/trivial.py Log: - introduced an old-style BaseWrappable with Wrappable as a new-style subclass of it - made ControlFlowException a subclass of BaseWrappable Now most internal classes inherit from Wrappable but the checks must be 'isinstance(x, BaseWrappable)'. Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Fri Jun 11 14:57:54 2004 @@ -3,15 +3,18 @@ from pypy.interpreter.miscutils import Stack, getthreadlocals import pypy.module -__all__ = ['ObjSpace', 'OperationError', 'Wrappable'] +__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable'] -class Wrappable(object): - """A subclass of Wrappable is an internal, interpreter-level class +class BaseWrappable: + """A subclass of BaseWrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" def __spacebind__(self, space): return self +class Wrappable(BaseWrappable, object): + """Same as BaseWrappable, just new-style instead.""" + class ObjSpace: """Base class for the interpreter-level implementations of object spaces. http://codespeak.net/moin/pypy/moin.cgi/ObjectSpace""" Modified: pypy/trunk/src/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/src/pypy/interpreter/pyframe.py Fri Jun 11 14:57:54 2004 @@ -216,7 +216,7 @@ ### Internal exceptions that change the control flow ### ### and (typically) unroll the block stack ### -class ControlFlowException(Exception): +class ControlFlowException(Exception, baseobjspace.BaseWrappable): """Abstract base class for interpreter-level exceptions that instruct the interpreter to change the control flow and the block stack. Modified: pypy/trunk/src/pypy/objspace/std/default.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/default.py (original) +++ pypy/trunk/src/pypy/objspace/std/default.py Fri Jun 11 14:57:54 2004 @@ -220,7 +220,7 @@ pass def unwrap__ANY(space, w_obj): - if isinstance(w_obj, Wrappable): + if isinstance(w_obj, BaseWrappable): return w_obj else: raise UnwrapError, 'cannot unwrap %r' % (w_obj,) 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 Jun 11 14:57:54 2004 @@ -233,7 +233,7 @@ return W_ListObject(self, wrappeditems) if isinstance(x, long): return W_LongObject(self, x) - if isinstance(x, Wrappable): + if isinstance(x, BaseWrappable): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 11 14:57:54 2004 @@ -120,7 +120,7 @@ # general stuff def wrap(self, x): - if isinstance(x, Wrappable): + if isinstance(x, BaseWrappable): x = x.__spacebind__(self) wrapperclass = self.hackwrapperclass(x.typedef) instance = CPyWrapper.__new__(wrapperclass) @@ -438,7 +438,7 @@ # return round(*args) def lookup(space, w_obj, name): - assert not isinstance(w_obj, Wrappable) + assert not isinstance(w_obj, BaseWrappable) if isinstance(w_obj, CPyWrapper): typedef = type(w_obj).__internalpypytypedef__ for basedef in typedef.mro(space): From mwh at codespeak.net Fri Jun 11 15:13:19 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 11 Jun 2004 15:13:19 +0200 (MEST) Subject: [pypy-svn] r5055 - pypy/trunk/src/pypy Message-ID: <20040611131319.D240F5BE16@thoth.codespeak.net> Author: mwh Date: Fri Jun 11 15:13:18 2004 New Revision: 5055 Modified: pypy/trunk/src/pypy/TODO Log: add a todo item Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Fri Jun 11 15:13:18 2004 @@ -1,3 +1,8 @@ +General +======= + +* not all of CPython's exceptions use the same __init__! + StdObjSpace =========== From arigo at codespeak.net Fri Jun 11 15:20:38 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 15:20:38 +0200 (MEST) Subject: [pypy-svn] r5056 - in pypy/trunk/src/pypy: interpreter module Message-ID: <20040611132038.1BE565BE16@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 15:20:38 2004 New Revision: 5056 Modified: pypy/trunk/src/pypy/interpreter/interactive.py pypy/trunk/src/pypy/interpreter/py.py pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/module/sysmodule.py Log: Nice ways to exit the PyPy interpreter: raise SystemExit, sys.exit(), Ctrl-D. Modified: pypy/trunk/src/pypy/interpreter/interactive.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/interactive.py (original) +++ pypy/trunk/src/pypy/interpreter/interactive.py Fri Jun 11 15:20:38 2004 @@ -50,8 +50,12 @@ try: pycode.exec_code(self.space, self.w_globals, self.w_globals) except baseobjspace.OperationError, operationerr: + space = self.space + if operationerr.match(space, space.w_SystemExit): + # XXX fetch the exit code from somewhere inside the w_SystemExit + raise SystemExit # XXX insert exception info into the application-level sys.last_xxx - operationerr.print_detailed_traceback(self.space) + operationerr.print_detailed_traceback(space) # for debugging convenience we also insert the exception into # the interpreter-level sys.last_xxx sys.last_type, sys.last_value, sys.last_traceback = sys.exc_info() Modified: pypy/trunk/src/pypy/interpreter/py.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/py.py (original) +++ pypy/trunk/src/pypy/interpreter/py.py Fri Jun 11 15:20:38 2004 @@ -62,7 +62,12 @@ space.__class__.__name__) con.interact(banner) except: - sys.excepthook(*sys.exc_info()) + exc_type, value, tb = sys.exc_info() + if (isinstance(exc_type, type(SystemExit)) and + issubclass(exc_type, SystemExit)): + pass # don't print tracebacks for SystemExit + else: + sys.excepthook(exc_type, value, tb) tb_server.wait_until_interrupt() tb_server.stop() 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 Jun 11 15:20:38 2004 @@ -36,7 +36,10 @@ if prompt is not None: sys.stdout.write(prompt) sys.stdout.flush() - return sys.stdin.readline() # XXX review + line = sys.stdin.readline() + if not line: # inputting an empty line gives line == '\n' + raise EOFError + return line def input(): return eval(raw_input()) Modified: pypy/trunk/src/pypy/module/sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/sysmodule.py (original) +++ pypy/trunk/src/pypy/module/sysmodule.py Fri Jun 11 15:20:38 2004 @@ -25,3 +25,6 @@ def excepthook(exctype, value, traceback): from traceback import print_exception print_exception(exctype, value, traceback) + +def exit(exitcode=0): + raise SystemExit(exitcode) From mwh at codespeak.net Fri Jun 11 15:49:12 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 11 Jun 2004 15:49:12 +0200 (MEST) Subject: [pypy-svn] r5057 - in pypy/trunk/src/pypy: annotation interpreter module objspace objspace/flow objspace/flow/test objspace/std tool Message-ID: <20040611134912.03DC85BE16@thoth.codespeak.net> Author: mwh Date: Fri Jun 11 15:49:11 2004 New Revision: 5057 Modified: pypy/trunk/src/pypy/annotation/unaryop.py pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/debug.py pypy/trunk/src/pypy/interpreter/extmodule.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/generator.py pypy/trunk/src/pypy/interpreter/interactive.py pypy/trunk/src/pypy/interpreter/main.py pypy/trunk/src/pypy/interpreter/py.py pypy/trunk/src/pypy/interpreter/pycode.py pypy/trunk/src/pypy/interpreter/pyopcode.py pypy/trunk/src/pypy/interpreter/unittest_w.py pypy/trunk/src/pypy/module/sysinterp.py pypy/trunk/src/pypy/objspace/flow/flowcontext.py pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/objspace/flow/test/test_model.py pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/dictobject.py pypy/trunk/src/pypy/objspace/std/longtype.py pypy/trunk/src/pypy/objspace/trivial.py pypy/trunk/src/pypy/tool/pydis.py Log: remove a bunch of unused imports Modified: pypy/trunk/src/pypy/annotation/unaryop.py ============================================================================== --- pypy/trunk/src/pypy/annotation/unaryop.py (original) +++ pypy/trunk/src/pypy/annotation/unaryop.py Fri Jun 11 15:49:11 2004 @@ -2,7 +2,7 @@ Unary operations on SomeValues. """ -from pypy.annotation.pairtype import pair, pairtype +from pypy.annotation.pairtype import pair from pypy.annotation.model import SomeObject, SomeInteger, SomeBool from pypy.annotation.model import SomeString, SomeList, SomeDict from pypy.annotation.model import SomeTuple, SomeImpossibleValue Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Fri Jun 11 15:49:11 2004 @@ -1,7 +1,6 @@ from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.error import OperationError -from pypy.interpreter.miscutils import Stack, getthreadlocals -import pypy.module +from pypy.interpreter.miscutils import getthreadlocals __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable'] Modified: pypy/trunk/src/pypy/interpreter/debug.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/debug.py (original) +++ pypy/trunk/src/pypy/interpreter/debug.py Fri Jun 11 15:49:11 2004 @@ -2,7 +2,7 @@ PyPy-oriented interface to pdb. """ -import pdb, sys +import pdb def fire(operationerr): if not operationerr.debug_excs: Modified: pypy/trunk/src/pypy/interpreter/extmodule.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/extmodule.py (original) +++ pypy/trunk/src/pypy/interpreter/extmodule.py Fri Jun 11 15:49:11 2004 @@ -5,7 +5,7 @@ """ from __future__ import generators # for generators.compiler_flag -import os, sys, types +import os, sys import autopath from pypy.interpreter import gateway from pypy.interpreter.error import OperationError Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Fri Jun 11 15:49:11 2004 @@ -17,7 +17,7 @@ WeakKeyDictionary = dict # XXX for PyPy from pypy.interpreter import eval, pycode from pypy.interpreter.function import Function, Method -from pypy.interpreter.baseobjspace import Wrappable, ObjSpace +from pypy.interpreter.baseobjspace import Wrappable class BuiltinCode(eval.Code): Modified: pypy/trunk/src/pypy/interpreter/generator.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/generator.py (original) +++ pypy/trunk/src/pypy/interpreter/generator.py Fri Jun 11 15:49:11 2004 @@ -2,7 +2,6 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.eval import Frame from pypy.interpreter.pyframe import ControlFlowException, ExitFrame -from pypy.interpreter import function, gateway # # Generator support. Note that GeneratorFrame is not a subclass of PyFrame. Modified: pypy/trunk/src/pypy/interpreter/interactive.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/interactive.py (original) +++ pypy/trunk/src/pypy/interpreter/interactive.py Fri Jun 11 15:49:11 2004 @@ -1,9 +1,8 @@ import autopath -from pypy.interpreter import executioncontext, pyframe, baseobjspace +from pypy.interpreter import executioncontext, baseobjspace import sys import code -import linecache class PyPyConsole(code.InteractiveConsole): Modified: pypy/trunk/src/pypy/interpreter/main.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/main.py (original) +++ pypy/trunk/src/pypy/interpreter/main.py Fri Jun 11 15:49:11 2004 @@ -1,8 +1,8 @@ import autopath from pypy.tool import option -from pypy.interpreter import executioncontext, baseobjspace, gateway, module +from pypy.interpreter import executioncontext, module from pypy.interpreter.error import OperationError, PyPyError -import sys, os +import sys def _run_eval_string(source, filename, space, eval): if eval: Modified: pypy/trunk/src/pypy/interpreter/py.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/py.py (original) +++ pypy/trunk/src/pypy/interpreter/py.py Fri Jun 11 15:49:11 2004 @@ -7,7 +7,7 @@ from pypy.tool import option from pypy.tool.optik import make_option -from pypy.interpreter import main, interactive, baseobjspace, error +from pypy.interpreter import main, interactive, error import sys class Options(option.Options): Modified: pypy/trunk/src/pypy/interpreter/pycode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pycode.py (original) +++ pypy/trunk/src/pypy/interpreter/pycode.py Fri Jun 11 15:49:11 2004 @@ -6,8 +6,6 @@ import dis from pypy.interpreter import eval -from pypy.interpreter.error import OperationError - # code object contants, for co_flags below CO_OPTIMIZED = 0x0001 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Fri Jun 11 15:49:11 2004 @@ -6,7 +6,7 @@ from pypy.interpreter.baseobjspace import OperationError from pypy.interpreter.eval import UNDEFINED -from pypy.interpreter import baseobjspace, gateway, function +from pypy.interpreter import gateway, function from pypy.interpreter import pyframe, pytraceback from pypy.interpreter.miscutils import InitializedClass Modified: pypy/trunk/src/pypy/interpreter/unittest_w.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/unittest_w.py (original) +++ pypy/trunk/src/pypy/interpreter/unittest_w.py Fri Jun 11 15:49:11 2004 @@ -1,6 +1,6 @@ import autopath -import sys, os +import os import unittest from pypy.interpreter import gateway Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Fri Jun 11 15:49:11 2004 @@ -3,8 +3,7 @@ """ import os from pypy.interpreter import autopath -from pypy.interpreter.module import Module -from pypy.interpreter.pycode import PyCode +#from pypy.interpreter.module import Module from pypy.interpreter.error import OperationError import sys as cpy_sys Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Fri Jun 11 15:49:11 2004 @@ -1,7 +1,5 @@ from pypy.interpreter.executioncontext import ExecutionContext -from pypy.interpreter.miscutils import Stack -from pypy.interpreter.pyframe \ - import ControlFlowException, ExitFrame, PyFrame +from pypy.interpreter.pyframe import ExitFrame from pypy.interpreter.error import OperationError from pypy.objspace.flow.model import * from pypy.objspace.flow.framestate import FrameState Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Fri Jun 11 15:49:11 2004 @@ -1,6 +1,5 @@ # ______________________________________________________________________ -import sys, operator, types -import pypy +import sys, operator from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError Modified: pypy/trunk/src/pypy/objspace/flow/test/test_model.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/test_model.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/test_model.py Fri Jun 11 15:49:11 2004 @@ -23,6 +23,7 @@ def test_simplefunc(self): graph = self.getflow(self.simplefunc) l = flatten(graph) + print l self.assertEquals(len(l), 4) def test_class(self): Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Fri Jun 11 15:49:11 2004 @@ -3,8 +3,6 @@ from pypy.objspace.std.objspace import * from pypy.interpreter.function import Function -from stringobject import W_StringObject -from intobject import W_IntObject from default import UnwrapError import sys, operator, types 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 Fri Jun 11 15:49:11 2004 @@ -7,7 +7,6 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from stringobject import W_StringObject from restricted_int import r_uint 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 Fri Jun 11 15:49:11 2004 @@ -1,6 +1,5 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.objecttype import object_typedef -from pypy.interpreter.error import OperationError def descr__new__(space, w_longtype, w_value=None): from longobject import W_LongObject Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 11 15:49:11 2004 @@ -4,10 +4,10 @@ # correctly wrap the exceptions. # -from pypy.interpreter import pyframe, gateway +from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import * from pypy.objspace.descroperation import DescrOperation, Object -import operator, types, new, sys +import operator, types, sys import __builtin__ as cpy_builtin class CPyWrapper(object): Modified: pypy/trunk/src/pypy/tool/pydis.py ============================================================================== --- pypy/trunk/src/pypy/tool/pydis.py (original) +++ pypy/trunk/src/pypy/tool/pydis.py Fri Jun 11 15:49:11 2004 @@ -7,7 +7,6 @@ import autopath import sys -import types from pypy.tool.opcode import * from pypy.tool.opcode import __all__ as _opcodes_all From arigo at codespeak.net Fri Jun 11 16:43:35 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 16:43:35 +0200 (MEST) Subject: [pypy-svn] r5059 - pypy/trunk/src/pypy/interpreter Message-ID: <20040611144335.0384D5BE15@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 16:43:35 2004 New Revision: 5059 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py Log: Convenience space.eval() and space.exec_(). Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Fri Jun 11 16:43:35 2004 @@ -181,6 +181,30 @@ w_objtype = self.type(w_obj) return self.issubtype(w_objtype, w_type) + def eval(self, expression, w_globals, w_locals): + "For internal debugging." + import types + from pypy.interpreter.pycode import PyCode + if isinstance(expression, str): + expression = compile(expression, '?', 'eval') + if isinstance(expression, types.CodeType): + expression = PyCode()._from_code(expression) + if not isinstance(expression, PyCode): + raise TypeError, 'space.eval(): expected a string, code or PyCode object' + return expression.exec_code(self, w_globals, w_locals) + + def exec_(self, statement, w_globals, w_locals): + "For internal debugging." + import types + from pypy.interpreter.pycode import PyCode + if isinstance(statement, str): + statement = compile(statement, '?', 'exec') + if isinstance(statement, types.CodeType): + statement = PyCode()._from_code(statement) + if not isinstance(statement, PyCode): + raise TypeError, 'space.exec_(): expected a string, code or PyCode object' + return statement.exec_code(self, w_globals, w_locals) + ## Table describing the regular part of the interface of object spaces, ## namely all methods which only take w_ arguments and return a w_ result From arigo at codespeak.net Fri Jun 11 16:43:58 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 16:43:58 +0200 (MEST) Subject: [pypy-svn] r5060 - pypy/trunk/src/pypy/interpreter Message-ID: <20040611144358.278105BE15@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 16:43:57 2004 New Revision: 5060 Modified: pypy/trunk/src/pypy/interpreter/module.py pypy/trunk/src/pypy/interpreter/typedef.py Log: Make ModuleType callable to create new modules. Modified: pypy/trunk/src/pypy/interpreter/module.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/module.py (original) +++ pypy/trunk/src/pypy/interpreter/module.py Fri Jun 11 16:43:57 2004 @@ -14,3 +14,11 @@ self.w_dict = w_dict self.w_name = w_name space.setitem(w_dict, space.wrap('__name__'), w_name) + + def descr_module__new__(space, *args_w, **kwds_w): + return Module(space, space.wrap('?')) + + def descr_module__init__(self, w_name): + space = self.space + self.w_name = w_name + space.setitem(self.w_dict, space.wrap('__name__'), w_name) Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Fri Jun 11 16:43:57 2004 @@ -120,6 +120,8 @@ Module.typedef = TypeDef("module", __dict__ = attrproperty_w('w_dict'), + __new__ = interp2app(Module.descr_module__new__.im_func), + __init__ = interp2app(Module.descr_module__init__.im_func), ) getset_func_doc = GetSetProperty(Function.fget_func_doc, From arigo at codespeak.net Fri Jun 11 18:05:13 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 18:05:13 +0200 (MEST) Subject: [pypy-svn] r5061 - in pypy/trunk/src/pypy: interpreter objspace/std Message-ID: <20040611160513.223935BE15@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 18:05:11 2004 New Revision: 5061 Modified: pypy/trunk/src/pypy/interpreter/module.py pypy/trunk/src/pypy/objspace/std/dicttype.py pypy/trunk/src/pypy/objspace/std/floattype.py pypy/trunk/src/pypy/objspace/std/inttype.py pypy/trunk/src/pypy/objspace/std/listtype.py pypy/trunk/src/pypy/objspace/std/longtype.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/slicetype.py pypy/trunk/src/pypy/objspace/std/stringtype.py pypy/trunk/src/pypy/objspace/std/tupletype.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/std/typetype.py Log: - Make ModuleType subclassable (bis). - Renamed check_user_subclass() to build_user_subclass(). Modified: pypy/trunk/src/pypy/interpreter/module.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/module.py (original) +++ pypy/trunk/src/pypy/interpreter/module.py Fri Jun 11 18:05:11 2004 @@ -15,8 +15,9 @@ self.w_name = w_name space.setitem(w_dict, space.wrap('__name__'), w_name) - def descr_module__new__(space, *args_w, **kwds_w): - return Module(space, space.wrap('?')) + def descr_module__new__(space, w_subtype, *args_w, **kwds_w): + w_obj = space.wrap(Module(space, space.wrap('?'))) + return space.build_user_subclass(Module.typedef, w_subtype, w_obj) def descr_module__init__(self, w_name): space = self.space Modified: pypy/trunk/src/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/dicttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/dicttype.py Fri Jun 11 18:05:11 2004 @@ -97,7 +97,7 @@ def descr__new__(space, w_dicttype, *args_w, **kwds_w): from pypy.objspace.std.dictobject import W_DictObject w_obj = W_DictObject(space, []) - return space.w_dict.check_user_subclass(w_dicttype, w_obj) + return space.w_dict.build_user_subclass(w_dicttype, w_obj) # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/floattype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/floattype.py (original) +++ pypy/trunk/src/pypy/objspace/std/floattype.py Fri Jun 11 18:05:11 2004 @@ -13,7 +13,7 @@ space.wrap(str(e))) else: w_obj = space.float(w_value) - return space.w_float.check_user_subclass(w_floattype, w_obj) + return space.w_float.build_user_subclass(w_floattype, w_obj) # ____________________________________________________________ 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 Fri Jun 11 18:05:11 2004 @@ -29,7 +29,7 @@ raise OperationError(space.w_OverflowError, space.wrap(str(e))) w_obj = W_IntObject(space, value) - return space.w_int.check_user_subclass(w_inttype, w_obj) + return space.w_int.build_user_subclass(w_inttype, w_obj) # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/listtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/listtype.py Fri Jun 11 18:05:11 2004 @@ -16,7 +16,7 @@ def descr__new__(space, w_listtype, *args_w, **kwds_w): w_obj = space.newlist([]) - return space.w_list.check_user_subclass(w_listtype, w_obj) + return space.w_list.build_user_subclass(w_listtype, w_obj) # ____________________________________________________________ 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 Fri Jun 11 18:05:11 2004 @@ -7,7 +7,7 @@ w_obj = W_LongObject(space) else: w_obj = space.long(w_value) - return space.w_long.check_user_subclass(w_longtype, w_obj) + return space.w_long.build_user_subclass(w_longtype, w_obj) # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Fri Jun 11 18:05:11 2004 @@ -24,7 +24,7 @@ # XXX 2.2 behavior: ignoring all arguments from objectobject import W_ObjectObject w_obj = W_ObjectObject(space) - return space.w_object.check_user_subclass(w_type, w_obj) + return space.w_object.build_user_subclass(w_type, w_obj) def descr__init__(space, *args_w, **kwds_w): pass # XXX 2.2. behavior: ignoring all arguments 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 Jun 11 18:05:11 2004 @@ -299,6 +299,10 @@ return self.wrap(cls.__dict__[name]) return None + def build_user_subclass(self, typedef, w_subtype, w_obj): + w_type = self.gettypeobject(typedef) + return w_type.build_user_subclass(w_subtype, w_obj) + def unpacktuple(self, w_tuple, expected_length=None): assert isinstance(w_tuple, W_TupleObject) t = w_tuple.wrappeditems Modified: pypy/trunk/src/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/slicetype.py (original) +++ pypy/trunk/src/pypy/objspace/std/slicetype.py Fri Jun 11 18:05:11 2004 @@ -98,7 +98,7 @@ raise OperationError(space.w_TypeError, space.wrap("slice() takes at least 1 argument")) w_obj = space.newslice(w_start, w_stop, w_step) - return space.w_slice.check_user_subclass(w_slicetype, w_obj) + return space.w_slice.build_user_subclass(w_slicetype, w_obj) # ____________________________________________________________ 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 Jun 11 18:05:11 2004 @@ -41,7 +41,7 @@ w_obj = space.newstring('') else: w_obj = space.str(w_obj) - return space.w_str.check_user_subclass(w_stringtype, w_obj) + return space.w_str.build_user_subclass(w_stringtype, w_obj) # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/tupletype.py (original) +++ pypy/trunk/src/pypy/objspace/std/tupletype.py Fri Jun 11 18:05:11 2004 @@ -8,7 +8,7 @@ else: tuple_w = space.unpackiterable(w_items) w_obj = space.newtuple(tuple_w) - return space.w_tuple.check_user_subclass(w_tupletype, w_obj) + return space.w_tuple.build_user_subclass(w_tupletype, w_obj) # ____________________________________________________________ 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 Fri Jun 11 18:05:11 2004 @@ -62,7 +62,7 @@ pass return None - def check_user_subclass(w_self, w_subtype, w_obj): + def build_user_subclass(w_self, w_subtype, w_obj): """This morphs an object newly created by the w_self's __new__ function into an instance of a subclass of w_self if needed.""" space = w_self.space 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 Jun 11 18:05:11 2004 @@ -16,7 +16,7 @@ assert isinstance(key, str) dict_w[key] = space.getitem(w_dict, w_key) w_type = W_TypeObject(space, name, bases_w or [space.w_object], dict_w, None) - return space.w_type.check_user_subclass(w_typetype, w_type) + return space.w_type.build_user_subclass(w_typetype, w_type) def descr_get__mro__(space, w_type): # XXX this should be inside typeobject.py From arigo at codespeak.net Fri Jun 11 18:19:33 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 18:19:33 +0200 (MEST) Subject: [pypy-svn] r5062 - pypy/trunk/src/pypy/interpreter Message-ID: <20040611161933.4B3825BE15@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 18:19:32 2004 New Revision: 5062 Modified: pypy/trunk/src/pypy/interpreter/py.py Log: Enabled 'pdb.pm()' after a PyPy crash. py.py used to eat and display the exception itself without making it available as sys.last_xxx. Modified: pypy/trunk/src/pypy/interpreter/py.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/py.py (original) +++ pypy/trunk/src/pypy/interpreter/py.py Fri Jun 11 18:19:32 2004 @@ -67,6 +67,9 @@ issubclass(exc_type, SystemExit)): pass # don't print tracebacks for SystemExit else: + sys.last_type = exc_type + sys.last_value = value + sys.last_traceback = tb sys.excepthook(exc_type, value, tb) tb_server.wait_until_interrupt() From arigo at codespeak.net Fri Jun 11 20:01:18 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 11 Jun 2004 20:01:18 +0200 (MEST) Subject: [pypy-svn] r5063 - in pypy/trunk/src/pypy: interpreter objspace objspace/std objspace/std/test Message-ID: <20040611180118.818845BE15@thoth.codespeak.net> Author: arigo Date: Fri Jun 11 20:01:13 2004 New Revision: 5063 Modified: pypy/trunk/src/pypy/interpreter/typedef.py pypy/trunk/src/pypy/objspace/std/booltype.py pypy/trunk/src/pypy/objspace/std/dicttype.py pypy/trunk/src/pypy/objspace/std/floattype.py pypy/trunk/src/pypy/objspace/std/inttype.py pypy/trunk/src/pypy/objspace/std/itertype.py pypy/trunk/src/pypy/objspace/std/listtype.py pypy/trunk/src/pypy/objspace/std/longtype.py pypy/trunk/src/pypy/objspace/std/nonetype.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/slicetype.py pypy/trunk/src/pypy/objspace/std/stdtypedef.py pypy/trunk/src/pypy/objspace/std/stringtype.py pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py pypy/trunk/src/pypy/objspace/std/tupletype.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/std/typetype.py pypy/trunk/src/pypy/objspace/trivial.py Log: - enforced single inheritance at the TypeDef level. - cleaned up StdTypeDef by merging the 'base' stuff to TypeDef. - changed all objspace/std/xxxtype.py to use single inheritance and default to the object_typedef base. - fixed the trivial object space accordingly. - new test for 'class A(int, dict)' failing. Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Fri Jun 11 20:01:13 2004 @@ -7,15 +7,11 @@ from pypy.interpreter.error import OperationError class TypeDef: - def __init__(self, __name, **rawdict): + def __init__(self, __name, __base=None, **rawdict): self.name = __name + self.base = __base self.rawdict = rawdict - def mro(self, space): - if self is space.object_typedef: - return [self] - else: - return [self, space.object_typedef] class GetSetProperty(Wrappable): def __init__(self, fget, fset=None, fdel=None, doc=None): @@ -78,7 +74,7 @@ from pypy.interpreter.eval import Code, Frame from pypy.interpreter.pycode import PyCode -from pypy.interpreter.pyframe import PyFrame +from pypy.interpreter.pyframe import PyFrame, ControlFlowException from pypy.interpreter.module import Module from pypy.interpreter.function import Function, Method, StaticMethod from pypy.interpreter.pytraceback import PyTraceback @@ -171,3 +167,5 @@ ) Cell.typedef = TypeDef("Cell") + +ControlFlowException.typedef = TypeDef("ControlFlowException") Modified: pypy/trunk/src/pypy/objspace/std/booltype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/booltype.py (original) +++ pypy/trunk/src/pypy/objspace/std/booltype.py Fri Jun 11 20:01:13 2004 @@ -10,6 +10,6 @@ # ____________________________________________________________ -bool_typedef = StdTypeDef("bool", [int_typedef], +bool_typedef = StdTypeDef("bool", int_typedef, __new__ = newmethod(descr__new__), ) Modified: pypy/trunk/src/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/dicttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/dicttype.py Fri Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef from pypy.objspace.std.register_all import register_all dict_copy = MultiMethod('copy', 1) @@ -101,7 +100,7 @@ # ____________________________________________________________ -dict_typedef = StdTypeDef("dict", [object_typedef], +dict_typedef = StdTypeDef("dict", __new__ = newmethod(descr__new__), ) dict_typedef.registermethods(globals()) Modified: pypy/trunk/src/pypy/objspace/std/floattype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/floattype.py (original) +++ pypy/trunk/src/pypy/objspace/std/floattype.py Fri Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef def descr__new__(space, w_floattype, w_value=None): if w_value is None: @@ -17,6 +16,6 @@ # ____________________________________________________________ -float_typedef = StdTypeDef("float", [object_typedef], +float_typedef = StdTypeDef("float", __new__ = newmethod(descr__new__), ) 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 Fri Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef from pypy.interpreter.error import OperationError def descr__new__(space, w_inttype, w_value=None, w_base=None): @@ -33,6 +32,6 @@ # ____________________________________________________________ -int_typedef = StdTypeDef("int", [object_typedef], +int_typedef = StdTypeDef("int", __new__ = newmethod(descr__new__), ) Modified: pypy/trunk/src/pypy/objspace/std/itertype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/itertype.py (original) +++ pypy/trunk/src/pypy/objspace/std/itertype.py Fri Jun 11 20:01:13 2004 @@ -1,10 +1,6 @@ -""" -Reviewed 03-06-22 -""" from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef # ____________________________________________________________ -iter_typedef = StdTypeDef("sequence-iterator", [object_typedef], +iter_typedef = StdTypeDef("sequence-iterator", ) Modified: pypy/trunk/src/pypy/objspace/std/listtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/listtype.py Fri Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef from sys import maxint list_append = MultiMethod('append', 2) @@ -20,7 +19,7 @@ # ____________________________________________________________ -list_typedef = StdTypeDef("list", [object_typedef], +list_typedef = StdTypeDef("list", __new__ = newmethod(descr__new__), ) list_typedef.registermethods(globals()) 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 Fri Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef def descr__new__(space, w_longtype, w_value=None): from longobject import W_LongObject @@ -11,6 +10,6 @@ # ____________________________________________________________ -long_typedef = StdTypeDef("long", [object_typedef], +long_typedef = StdTypeDef("long", __new__ = newmethod(descr__new__), ) Modified: pypy/trunk/src/pypy/objspace/std/nonetype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/nonetype.py (original) +++ pypy/trunk/src/pypy/objspace/std/nonetype.py Fri Jun 11 20:01:13 2004 @@ -1,8 +1,7 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef # ____________________________________________________________ -none_typedef = StdTypeDef("NoneType", [object_typedef], +none_typedef = StdTypeDef("NoneType", ) Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Fri Jun 11 20:01:13 2004 @@ -31,7 +31,7 @@ # ____________________________________________________________ -object_typedef = StdTypeDef("object", [], +object_typedef = StdTypeDef("object", __getattribute__ = gateway.interp2app(Object.descr__getattribute__.im_func), __setattr__ = gateway.interp2app(Object.descr__setattr__.im_func), __delattr__ = gateway.interp2app(Object.descr__delattr__.im_func), 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 Jun 11 20:01:13 2004 @@ -182,8 +182,6 @@ } # types - from pypy.objspace.std.objecttype import object_typedef - self.object_typedef = object_typedef self.types_w = {} for typedef in self.standard_types(): w_type = self.gettypeobject(typedef) Modified: pypy/trunk/src/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/slicetype.py (original) +++ pypy/trunk/src/pypy/objspace/std/slicetype.py Fri Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError @@ -102,7 +101,7 @@ # ____________________________________________________________ -slice_typedef = StdTypeDef("slice", [object_typedef], +slice_typedef = StdTypeDef("slice", __new__ = newmethod(descr__new__), start = attrproperty_w('w_start'), stop = attrproperty_w('w_stop'), Modified: pypy/trunk/src/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stdtypedef.py (original) +++ pypy/trunk/src/pypy/objspace/std/stdtypedef.py Fri Jun 11 20:01:13 2004 @@ -11,20 +11,23 @@ class StdTypeDef(TypeDef): - def __init__(self, name, bases, **rawdict): - TypeDef.__init__(self, name, **rawdict) - self.bases = bases + def __init__(self, __name, __base=None, **rawdict): + TypeDef.__init__(self, __name, __base, **rawdict) self.local_multimethods = [] def registermethods(self, namespace): self.local_multimethods += hack_out_multimethods(namespace) - def mro(self, space): - assert len(self.bases) <= 1 - if self.bases: - return [self] + self.bases[0].mro(space) - else: - return [self] +def issubtypedef(a, b): + from pypy.objspace.std.objecttype import object_typedef + if b is object_typedef: + return True + while a is not b: + a = a.base + if a is None: + return False + return True + def newmethod(descr_new): # this is turned into a static method by the constructor of W_TypeObject. @@ -39,6 +42,7 @@ def buildtypeobject(typedef, space): # build a W_TypeObject from this StdTypeDef from pypy.objspace.std.typeobject import W_TypeObject + from pypy.objspace.std.objecttype import object_typedef w = space.wrap rawdict = typedef.rawdict.copy() @@ -55,10 +59,13 @@ assert name not in rawdict, 'name clash: %s in %s_typedef' % ( name, typedef.name) rawdict[name] = fn - bases_w = [space.gettypeobject(basedef) for basedef in typedef.bases] + + # compute the bases + if typedef is object_typedef: + bases_w = [] else: - from pypy.objspace.std.objecttype import object_typedef - bases_w = [space.gettypeobject(object_typedef)] + base = typedef.base or object_typedef + bases_w = [space.gettypeobject(base)] # wrap everything dict_w = {} 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 Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef str_join = MultiMethod('join', 2) str_split = MultiMethod('split', 3, defaults=(None,-1)) @@ -45,7 +44,7 @@ # ____________________________________________________________ -str_typedef = StdTypeDef("str", [object_typedef], +str_typedef = StdTypeDef("str", __new__ = newmethod(descr__new__), ) str_typedef.registermethods(globals()) Modified: pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py Fri Jun 11 20:01:13 2004 @@ -89,5 +89,14 @@ self.assertEquals(f.__call__(a=1, b=2, c=3), ((), {"a": 1, "b": 2, "c": 3})) + def test_multipleinheritance_fail(self): + try: + class A(int, dict): + pass + except TypeError: + pass + else: + raise AssertionError, "this multiple inheritance should fail" + if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/tupletype.py (original) +++ pypy/trunk/src/pypy/objspace/std/tupletype.py Fri Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef def descr__new__(space, w_tupletype, w_items=None): @@ -12,6 +11,6 @@ # ____________________________________________________________ -tuple_typedef = StdTypeDef("tuple", [object_typedef], +tuple_typedef = StdTypeDef("tuple", __new__ = newmethod(descr__new__), ) 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 Fri Jun 11 20:01:13 2004 @@ -1,6 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter.typedef import attrproperty_w +from pypy.objspace.std.stdtypedef import issubtypedef class W_TypeObject(W_Object): from pypy.objspace.std.typetype import type_typedef as typedef @@ -16,19 +17,31 @@ if overridetypedef is not None: w_self.instancetypedef = overridetypedef else: - # find the most specific typedef - longest_mro = [space.object_typedef] - for w_base in bases_w: - mro = w_base.instancetypedef.mro(space) - if len(mro) > len(longest_mro): - longest_mro = mro - # check that it is a sub-typedef of all other ones - for w_base in bases_w: - if w_base.instancetypedef not in longest_mro: +## # find the most specific typedef +## longest_mro = [space.object_typedef] +## for w_base in bases_w: +## mro = w_base.instancetypedef.mro(space) +## if len(mro) > len(longest_mro): +## longest_mro = mro +## # check that it is a sub-typedef of all other ones +## for w_base in bases_w: +## if w_base.instancetypedef not in longest_mro: +## raise OperationError(space.w_TypeError, +## space.wrap("instance layout conflicts in " +## "multiple inheritance")) +## w_self.instancetypedef = longest_mro[0] + + assert bases_w # typetype.descr__new__ should take care that there + # is always at least one base + instancetypedef = bases_w[0].instancetypedef + w_self.instancetypedef = instancetypedef + # check that the remaining bases don't have an incompatible 'layout' + for w_base in bases_w[1:]: + if not issubtypedef(instancetypedef, w_base.instancetypedef): raise OperationError(space.w_TypeError, space.wrap("instance layout conflicts in " "multiple inheritance")) - w_self.instancetypedef = longest_mro[0] + nd = False for w_base in bases_w: if w_base.needs_new_dict: 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 Jun 11 20:01:13 2004 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objecttype import object_typedef def descr__new__(space, w_typetype, w_name, w_bases, w_dict): @@ -34,7 +33,7 @@ # ____________________________________________________________ -type_typedef = StdTypeDef("type", [object_typedef], +type_typedef = StdTypeDef("type", __new__ = newmethod(descr__new__), __name__ = attrproperty('name'), __bases__ = GetSetProperty(descr__bases), Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 11 20:01:13 2004 @@ -150,43 +150,41 @@ except AttributeError: from pypy.interpreter.gateway import interp2app - # make the base first (assuming single inheritance) - mro = typedef.mro(self) - if len(mro) > 1: - bases = (self.hackwrapperclass(mro[1]),) + # make the base first + if typedef.base: + bases = (self.hackwrapperclass(typedef.base),) else: bases = (CPyWrapper,) # make the class dict with descriptors redirecting to the ones # in rawdict descrdict = {'__internalpypytypedef__': typedef} - if typedef.name != 'object': - for descrname, descr in typedef.rawdict.items(): - if isinstance(descr, interp2app): - def make_stuff(descr=descr, descrname=descrname, space=self): - def stuff(w_obj, *args, **kwds): - fn = descr.get_function(space) - try: - return fn.descr_function_call(w_obj, *args, **kwds) - except OperationError, e: - if not hasattr(e.w_type, 'originalex'): - raise # XXX - # XXX normalize ... - #if isinstance(e.w_value, e.w_type): - raise e.w_type.originalex(repr(e.w_value)) # e.w_value) - return stuff - descrdict[descrname] = make_stuff() - else: - # more generally, defining a property - def fget(w_obj, descr=descr, space=self): - w_descr = space.wrap(descr) - return space.get(w_descr, w_obj, space.type(w_obj)) - def fset(w_obj, w_value, descr=descr, space=self): - w_descr = space.wrap(descr) - return space.set(w_descr, w_obj, w_value) - def fdel(w_obj, descr=descr, space=self): - w_descr = space.wrap(descr) - return space.set(w_descr, w_obj) - descrdict[descrname] = property(fget, fset, fdel) + for descrname, descr in typedef.rawdict.items(): + if isinstance(descr, interp2app): + def make_stuff(descr=descr, descrname=descrname, space=self): + def stuff(w_obj, *args, **kwds): + fn = descr.get_function(space) + try: + return fn.descr_function_call(w_obj, *args, **kwds) + except OperationError, e: + if not hasattr(e.w_type, 'originalex'): + raise # XXX + # XXX normalize ... + #if isinstance(e.w_value, e.w_type): + raise e.w_type.originalex(repr(e.w_value)) # e.w_value) + return stuff + descrdict[descrname] = make_stuff() + else: + # more generally, defining a property + def fget(w_obj, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.get(w_descr, w_obj, space.type(w_obj)) + def fset(w_obj, w_value, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.set(w_descr, w_obj, w_value) + def fdel(w_obj, descr=descr, space=self): + w_descr = space.wrap(descr) + return space.set(w_descr, w_obj) + descrdict[descrname] = property(fget, fset, fdel) cls = type('CPyWrapped '+typedef.name, bases, descrdict) typedef.trivialwrapperclass = cls return cls @@ -441,9 +439,12 @@ assert not isinstance(w_obj, BaseWrappable) if isinstance(w_obj, CPyWrapper): typedef = type(w_obj).__internalpypytypedef__ - for basedef in typedef.mro(space): - if name in basedef.rawdict: - return space.wrap(basedef.rawdict[name]) + while typedef is not None: + if name in typedef.rawdict: + return space.wrap(typedef.rawdict[name]) + typedef = typedef.base + if name in space.object_typedef.rawdict: + return space.wrap(space.object_typedef.rawdict[name]) return None else: for cls in w_obj.__class__.__mro__: From hpk at codespeak.net Sat Jun 12 10:53:42 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 12 Jun 2004 10:53:42 +0200 (MEST) Subject: [pypy-svn] r5064 - pypy/trunk/src/pypy Message-ID: <20040612085342.CE6C65A1B9@thoth.codespeak.net> Author: hpk Date: Sat Jun 12 10:53:41 2004 New Revision: 5064 Modified: pypy/trunk/src/pypy/TODO Log: some updates to TODO to the best of my knowledge Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Sat Jun 12 10:53:41 2004 @@ -29,7 +29,10 @@ * 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) + 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 @@ -42,7 +45,9 @@ http://codespeak.net/pypy/index.cgi?doc/objspace/multimethod - (now irrelevant? not sure...) + (now irrelevant? not sure... (nowadays, we have the descriptor + mechanism implemented right before EuroPython 2004 for both the + trivial and the stdobjspace)) Translator ========== @@ -54,7 +59,9 @@ * 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 * improve traceobjectspace! currently it only catches calls from outside the space into the space but not - the ones where the space calls operations on itself! + the ones where space operations involve calling more space + operations (the latter are not traced)! From hpk at codespeak.net Sat Jun 12 10:56:58 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 12 Jun 2004 10:56:58 +0200 (MEST) Subject: [pypy-svn] r5065 - pypy/trunk/src/pypy/annotation Message-ID: <20040612085658.5599E5A1B9@thoth.codespeak.net> Author: hpk Date: Sat Jun 12 10:56:57 2004 New Revision: 5065 Modified: pypy/trunk/src/pypy/annotation/factory.py Log: delete unused import Modified: pypy/trunk/src/pypy/annotation/factory.py ============================================================================== --- pypy/trunk/src/pypy/annotation/factory.py (original) +++ pypy/trunk/src/pypy/annotation/factory.py Sat Jun 12 10:56:57 2004 @@ -8,7 +8,6 @@ from __future__ import generators from types import FunctionType -from pypy.annotation.pairtype import pair from pypy.annotation.model import SomeImpossibleValue, SomeList, SomeDict from pypy.annotation.model import SomeObject, SomeInstance from pypy.annotation.model import unionof, immutablevalue From jacob at codespeak.net Sat Jun 12 12:48:52 2004 From: jacob at codespeak.net (jacob at codespeak.net) Date: Sat, 12 Jun 2004 12:48:52 +0200 (MEST) Subject: [pypy-svn] r5067 - pypy/branch/src-new-utest Message-ID: <20040612104852.1E91A5A1B9@thoth.codespeak.net> Author: jacob Date: Sat Jun 12 12:48:52 2004 New Revision: 5067 Added: pypy/branch/src-new-utest/ - copied from r5066, pypy/trunk/src/ Log: Creating a branch for converting unit tests to the new utest format. From arigo at codespeak.net Sat Jun 12 14:14:13 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 14:14:13 +0200 (MEST) Subject: [pypy-svn] r5069 - in pypy/trunk/src/pypy: interpreter objspace objspace/std Message-ID: <20040612121413.A906D5A1B9@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 14:14:09 2004 New Revision: 5069 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/module.py pypy/trunk/src/pypy/interpreter/typedef.py pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/std/booltype.py pypy/trunk/src/pypy/objspace/std/dicttype.py pypy/trunk/src/pypy/objspace/std/floattype.py pypy/trunk/src/pypy/objspace/std/inttype.py pypy/trunk/src/pypy/objspace/std/listtype.py pypy/trunk/src/pypy/objspace/std/longtype.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/slicetype.py pypy/trunk/src/pypy/objspace/std/stringtype.py pypy/trunk/src/pypy/objspace/std/tupletype.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/std/typetype.py Log: Rewrite of user-defined subclasses of built-in types: * every interp-level subclass of BaseWrappable and W_Object has exactly one shadowing UserXxx subclass at interp-level, which is used to implement any application-level instance of user-defined subclasses. * space.allocate_instance(cls, w_type) creates an interp-level instance of 'cls' without actually calling __init__(): the equivalent of tp_alloc(). * space.getdict() no longer uses the __dict__ descriptor but calls w_obj.hasdict & w_obj.getdict(). * we have a global object.__dict__ which uses w_obj.hasdict, w_obj.getdict and w_obj.setdict. * the trivial object space is still not converted -- i.e. presumably completely broken. Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Sat Jun 12 14:14:09 2004 @@ -8,6 +8,7 @@ class BaseWrappable: """A subclass of BaseWrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" + hasdict = False def __spacebind__(self, space): return self Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Sat Jun 12 14:14:09 2004 @@ -160,7 +160,13 @@ self.name, nkwds) raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - + + hasdict = True + def getdict(self): + return self.w_func_dict + def setdict(self, w_dict): + self.w_func_dict = w_dict + def descr_function_get(self, w_obj, w_cls=None): space = self.space wrap = space.wrap Modified: pypy/trunk/src/pypy/interpreter/module.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/module.py (original) +++ pypy/trunk/src/pypy/interpreter/module.py Sat Jun 12 14:14:09 2004 @@ -15,9 +15,16 @@ self.w_name = w_name space.setitem(w_dict, space.wrap('__name__'), w_name) + hasdict = True + def getdict(self): + return self.w_dict + def setdict(self, w_dict): + self.w_dict = w_dict + def descr_module__new__(space, w_subtype, *args_w, **kwds_w): - w_obj = space.wrap(Module(space, space.wrap('?'))) - return space.build_user_subclass(Module.typedef, w_subtype, w_obj) + module = space.allocate_instance(Module, w_subtype) + module.__init__(space, space.wrap('?')) + return space.wrap(module) def descr_module__init__(self, w_name): space = self.space Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Sat Jun 12 14:14:09 2004 @@ -13,6 +13,61 @@ self.rawdict = rawdict +unique_interplevel_subclass_cache = {} +def get_unique_interplevel_subclass(cls): + try: + return unique_interplevel_subclass_cache[cls] + except KeyError: + typedef = cls.typedef + name = 'User' + cls.__name__ + body = {} + + class User_InsertNameHere(object): + + def getclass(self): + return self.w__class__ + + def setclass(self, w_subtype): + # XXX sanity checks here + self.w__class__ = w_subtype + + if cls.hasdict: + def user_setup(self, space, w_subtype): + self.space = space + self.w__class__ = w_subtype + + else: + hasdict = True + def getdict(self): + return self.w__dict__ + + def setdict(self, w_dict): + space = self.space + if not space.is_true(space.isinstance(w_dict, space.w_dict)): + raise OperationError(space.w_TypeError, + space.wrap("setting dictionary to a non-dict")) + self.w__dict__ = w_dict + + def user_setup(self, space, w_subtype): + self.space = space + self.w__class__ = w_subtype + self.w__dict__ = space.newdict([]) + + body = dict(User_InsertNameHere.__dict__.items()) + subcls = type(name, (cls, UserSubclass), body) + unique_interplevel_subclass_cache[cls] = subcls + return subcls + +class UserSubclass(object): + pass # XXX this should probably not exist + +def instantiate(cls): + "Create an empty instance of 'cls'." + if isinstance(cls, type): + return object.__new__(cls) + else: + return new.instance(cls) + class GetSetProperty(Wrappable): def __init__(self, fget, fset=None, fdel=None, doc=None): fget = getattr(fget, 'im_func', fget) @@ -115,7 +170,6 @@ **Frame.typedef.rawdict) Module.typedef = TypeDef("module", - __dict__ = attrproperty_w('w_dict'), __new__ = interp2app(Module.descr_module__new__.im_func), __init__ = interp2app(Module.descr_module__init__.im_func), ) @@ -135,7 +189,6 @@ func_globals = attrproperty_w('w_func_globals'), __doc__ = getset_func_doc, __name__ = attrproperty('name'), - __dict__ = attrproperty_w('w_func_dict'), # XXX func_closure, etc.pp ) Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Sat Jun 12 14:14:09 2004 @@ -53,10 +53,10 @@ class DescrOperation: def getdict(space, w_obj): - w_descr = space.lookup(w_obj, '__dict__') - if w_descr is None: - return None - return space.get(w_descr, w_obj, space.type(w_obj)) + if w_obj.hasdict: + return w_obj.getdict() + else: + return None def is_data_descr(space, w_obj): return space.lookup(w_obj, '__set__') is not None @@ -163,10 +163,12 @@ def str(space,w_obj): w_descr = space.lookup(w_obj,'__str__') return space.get_and_call_function(w_descr,w_obj) + # XXX PyObject_Str() checks that the result is a string def repr(space,w_obj): w_descr = space.lookup(w_obj,'__repr__') 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__') Modified: pypy/trunk/src/pypy/objspace/std/booltype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/booltype.py (original) +++ pypy/trunk/src/pypy/objspace/std/booltype.py Sat Jun 12 14:14:09 2004 @@ -1,6 +1,8 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.inttype import int_typedef +# XXX should forbit subclassing of 'bool' + def descr__new__(space, w_booltype, w_obj=None): if w_obj is not None and space.is_true(w_obj): Modified: pypy/trunk/src/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/dicttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/dicttype.py Sat Jun 12 14:14:09 2004 @@ -95,8 +95,9 @@ def descr__new__(space, w_dicttype, *args_w, **kwds_w): from pypy.objspace.std.dictobject import W_DictObject - w_obj = W_DictObject(space, []) - return space.w_dict.build_user_subclass(w_dicttype, w_obj) + w_obj = space.allocate_instance(W_DictObject, w_dicttype) + w_obj.__init__(space, []) + return w_obj # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/floattype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/floattype.py (original) +++ pypy/trunk/src/pypy/objspace/std/floattype.py Sat Jun 12 14:14:09 2004 @@ -1,18 +1,29 @@ from pypy.objspace.std.stdtypedef import * def descr__new__(space, w_floattype, w_value=None): + from pypy.objspace.std.floatobject import W_FloatObject if w_value is None: - w_obj = space.newfloat(0.0) + value = 0.0 + elif space.is_true(space.isinstance(w_value, space.w_str)): + try: + value = float(space.unwrap(w_value)) + except ValueError, e: + raise OperationError(space.w_ValueError, + space.wrap(str(e))) else: - if space.is_true(space.isinstance(w_value, space.w_str)): - try: - w_obj = space.newfloat(float(space.unwrap(w_value))) - except ValueError, e: - raise OperationError(space.w_ValueError, - space.wrap(str(e))) - else: - w_obj = space.float(w_value) - return space.w_float.build_user_subclass(w_floattype, w_obj) + w_obj = space.float(w_value) + if space.is_true(space.is_(w_floattype, space.w_float)): + return w_obj # 'float(x)' should return + # whatever x.__float__() returned + value = space.unwrap(w_obj) + if isinstance(value, int): # XXX typechecking in unwrap! + value = float(value) + if not isinstance(value, float): # XXX typechecking in unwrap! + raise OperationError(space.w_ValueError, + space.wrap("value can't be converted to float")) + w_obj = space.allocate_instance(W_FloatObject, w_floattype) + w_obj.__init__(space, value) + return w_obj # ____________________________________________________________ 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 Sat Jun 12 14:14:09 2004 @@ -6,9 +6,15 @@ if w_base is None: w_base = space.w_None if w_value is None: - w_obj = space.newint(0) + value = 0 elif w_base == space.w_None and not space.is_true(space.isinstance(w_value, space.w_str)): - w_obj = space.int(w_value) + w_obj = space.int(w_value) + if space.is_true(space.is_(w_inttype, space.w_int)): + return w_obj # 'int(x)' should return whatever x.__int__() returned + value = space.unwrap(w_obj) + if not isinstance(value, int): # XXX typechecking in unwrap! + raise OperationError(space.w_ValueError, + space.wrap("value can't be converted to int")) else: if w_base == space.w_None: base = -909 # don't blame us!! @@ -27,8 +33,9 @@ except OverflowError, e: raise OperationError(space.w_OverflowError, space.wrap(str(e))) - w_obj = W_IntObject(space, value) - return space.w_int.build_user_subclass(w_inttype, w_obj) + w_obj = space.allocate_instance(W_IntObject, w_inttype) + w_obj.__init__(space, value) + return w_obj # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/listtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/listtype.py Sat Jun 12 14:14:09 2004 @@ -14,8 +14,10 @@ # ____________________________________________________________ def descr__new__(space, w_listtype, *args_w, **kwds_w): - w_obj = space.newlist([]) - return space.w_list.build_user_subclass(w_listtype, w_obj) + from listobject import W_ListObject + w_obj = space.allocate_instance(W_ListObject, w_listtype) + w_obj.__init__(space, []) + return w_obj # ____________________________________________________________ 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 Sat Jun 12 14:14:09 2004 @@ -3,10 +3,28 @@ def descr__new__(space, w_longtype, w_value=None): from longobject import W_LongObject if w_value is None: - w_obj = W_LongObject(space) + 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: w_obj = space.long(w_value) - return space.w_long.build_user_subclass(w_longtype, w_obj) + if space.is_true(space.is_(w_longtype, space.w_long)): + return w_obj # 'long(x)' should return + # whatever x.__long__() returned + value = space.unwrap(w_obj) + if isinstance(value, int): # XXX typechecking in unwrap! + value = long(value) + if not isinstance(value, long): # XXX typechecking in unwrap! + raise OperationError(space.w_ValueError, + space.wrap("value can't be converted to long")) + w_obj = space.allocate_instance(W_LongObject, w_longtype) + w_obj.__init__(space, value) + return w_obj # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Sat Jun 12 14:14:09 2004 @@ -1,3 +1,4 @@ +from pypy.interpreter.error import OperationError from pypy.objspace.descroperation import Object from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all @@ -23,12 +24,29 @@ def descr__new__(space, w_type, *args_w, **kwds_w): # XXX 2.2 behavior: ignoring all arguments from objectobject import W_ObjectObject - w_obj = W_ObjectObject(space) - return space.w_object.build_user_subclass(w_type, w_obj) + w_obj = space.allocate_instance(W_ObjectObject, w_type) + w_obj.__init__(space) + return w_obj def descr__init__(space, *args_w, **kwds_w): pass # XXX 2.2. behavior: ignoring all arguments +def descr__dict__(space, w_obj): + if w_obj.hasdict: + return w_obj.getdict() + else: + raise OperationError(space.w_AttributeError, + space.wrap("%s instances don't have a __dict__" % ( + space.type(w_obj).name))) + +def descr_set__dict__(space, w_obj, w_dict): + if w_obj.hasdict: + w_obj.setdict(w_dict) + else: + raise OperationError(space.w_AttributeError, + space.wrap("%s instances don't have a __dict__" % ( + space.type(w_obj).name))) + # ____________________________________________________________ object_typedef = StdTypeDef("object", @@ -41,4 +59,5 @@ __class__ = GetSetProperty(descr__class__), __new__ = newmethod(descr__new__), __init__ = gateway.interp2app(descr__init__), + __dict__ = GetSetProperty(descr__dict__, descr_set__dict__), ) 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 Sat Jun 12 14:14:09 2004 @@ -1,13 +1,16 @@ from pypy.objspace.std.register_all import register_all from pypy.interpreter.baseobjspace import * +from pypy.interpreter.typedef import get_unique_interplevel_subclass +from pypy.interpreter.typedef import instantiate, UserSubclass from pypy.objspace.std.multimethod import * from pypy.objspace.descroperation import DescrOperation import types -class W_Object: +class W_Object(object): "Parent base class for wrapped objects." typedef = None + hasdict = False def __init__(w_self, space): w_self.space = space # XXX not sure this is ever used any more @@ -276,11 +279,11 @@ return W_StringObject(self, ''.join(chars)) def type(self, w_obj): - if isinstance(w_obj, W_CPythonObject): - #raise TypeError, str(w_obj.cpyobj) - return self.wrap(type(w_obj.cpyobj)) - elif hasattr(w_obj, 'w__class__'): - return w_obj.w__class__ # user-defined classes + if isinstance(w_obj, UserSubclass): + return w_obj.getclass() + elif isinstance(w_obj, W_CPythonObject): + #raise TypeError, str(w_obj.cpyobj) + return self.wrap(type(w_obj.cpyobj)) else: assert w_obj.typedef, w_obj return self.gettypeobject(w_obj.typedef) @@ -297,9 +300,18 @@ return self.wrap(cls.__dict__[name]) return None - def build_user_subclass(self, typedef, w_subtype, w_obj): - w_type = self.gettypeobject(typedef) - return w_type.build_user_subclass(w_subtype, w_obj) + def allocate_instance(self, cls, w_subtype): + """Allocate the memory needed for an instance of an internal or + user-defined type, without actually __init__ializing the instance.""" + w_type = self.gettypeobject(cls.typedef) + if self.is_true(self.is_(w_type, w_subtype)): + return instantiate(cls) + else: + w_type.check_user_subclass(w_subtype) + subcls = get_unique_interplevel_subclass(cls) + instance = instantiate(subcls) + instance.user_setup(self, w_subtype) + return instance def unpacktuple(self, w_tuple, expected_length=None): assert isinstance(w_tuple, W_TupleObject) Modified: pypy/trunk/src/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/slicetype.py (original) +++ pypy/trunk/src/pypy/objspace/std/slicetype.py Sat Jun 12 14:14:09 2004 @@ -81,6 +81,7 @@ # ____________________________________________________________ def descr__new__(space, w_slicetype, *args_w): + from pypy.objspace.std.sliceobject import W_SliceObject w_start = space.w_None w_stop = space.w_None w_step = space.w_None @@ -96,8 +97,9 @@ else: raise OperationError(space.w_TypeError, space.wrap("slice() takes at least 1 argument")) - w_obj = space.newslice(w_start, w_stop, w_step) - return space.w_slice.build_user_subclass(w_slicetype, w_obj) + w_obj = space.allocate_instance(W_SliceObject, w_slicetype) + w_obj.__init__(space, w_start, w_stop, w_step) + return w_obj # ____________________________________________________________ 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 Sat Jun 12 14:14:09 2004 @@ -36,11 +36,18 @@ # ____________________________________________________________ def descr__new__(space, w_stringtype, w_obj=None): + from pypy.objspace.std.stringobject import W_StringObject if w_obj is None: - w_obj = space.newstring('') + value = '' else: w_obj = space.str(w_obj) - return space.w_str.build_user_subclass(w_stringtype, w_obj) + if space.is_true(space.is_(w_stringtype, space.w_str)): + return w_obj # XXX might be reworked when space.str() typechecks + value = space.unwrap(w_obj) + assert isinstance(value, str) # XXX should be checked by space.str() + w_obj = space.allocate_instance(W_StringObject, w_stringtype) + w_obj.__init__(space, value) + return w_obj # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/tupletype.py (original) +++ pypy/trunk/src/pypy/objspace/std/tupletype.py Sat Jun 12 14:14:09 2004 @@ -2,12 +2,14 @@ def descr__new__(space, w_tupletype, w_items=None): + from pypy.objspace.std.tupleobject import W_TupleObject if w_items is None: tuple_w = [] else: tuple_w = space.unpackiterable(w_items) - w_obj = space.newtuple(tuple_w) - return space.w_tuple.build_user_subclass(w_tupletype, w_obj) + w_obj = space.allocate_instance(W_TupleObject, w_tupletype) + w_obj.__init__(space, tuple_w) + return w_obj # ____________________________________________________________ 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 Sat Jun 12 14:14:09 2004 @@ -12,7 +12,6 @@ w_self.bases_w = bases_w w_self.dict_w = dict_w w_self.ensure_static__new__() - w_self.needs_new_dict = False w_self.mro_w = compute_C3_mro(w_self) # XXX call type(w_self).mro() if overridetypedef is not None: w_self.instancetypedef = overridetypedef @@ -42,19 +41,6 @@ space.wrap("instance layout conflicts in " "multiple inheritance")) - nd = False - for w_base in bases_w: - if w_base.needs_new_dict: - nd = True - break - - # provide a __dict__ for the instances if there isn't any yet - if w_self.lookup('__dict__') is None: - w_self.needs_new_dict = True - w_self.dict_w['__dict__'] = space.wrap(attrproperty_w('w__dict__')) - elif nd: - w_self.needs_new_dict = True - def ensure_static__new__(w_self): # special-case __new__, as in CPython: # if it is a Function, turn it into a static method @@ -75,12 +61,8 @@ pass return None - def build_user_subclass(w_self, w_subtype, w_obj): - """This morphs an object newly created by the w_self's __new__ - function into an instance of a subclass of w_self if needed.""" + def check_user_subclass(w_self, w_subtype): space = w_self.space - if space.is_true(space.is_(w_self, w_subtype)): - return w_obj if not space.is_true(space.isinstance(w_subtype, space.w_type)): raise OperationError(space.w_TypeError, space.wrap("X is not a type object (%s)" % ( @@ -93,16 +75,22 @@ raise OperationError(space.w_TypeError, space.wrap("%s.__new__(%s) is not safe, use %s.__new__()" % ( w_self.name, w_subtype.name, w_subtype.name))) - if w_self.instancetypedef is not w_obj.typedef: - raise OperationError(space.w_TypeError, - space.wrap("%s.__new__(): got an object of type %s " - "instead of %s" % ( - w_self.name, space.type(w_obj).name, w_self.name))) - # stuff extra attributes into w_obj - w_obj.w__class__ = w_subtype - if w_subtype.needs_new_dict: - w_obj.w__dict__ = space.newdict([]) - return w_obj + + hasdict = True + def getdict(w_self): + # XXX should return a + space = w_self.space + dictspec = [] + for key, w_value in w_self.dict_w.items(): + dictspec.append((space.wrap(key), w_value)) + return space.newdict(dictspec) + + def setdict(w_self, w_dict): + space = w_self.space + raise OperationError(space.w_TypeError, + space.wrap("attribute '__dict__' of type objects " + "is not writable")) + def call__Type(space, w_type, w_args, w_kwds): args_w = space.unpacktuple(w_args) 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 Sat Jun 12 14:14:09 2004 @@ -14,20 +14,14 @@ key = space.unwrap(w_key) assert isinstance(key, str) dict_w[key] = space.getitem(w_dict, w_key) - w_type = W_TypeObject(space, name, bases_w or [space.w_object], dict_w, None) - return space.w_type.build_user_subclass(w_typetype, w_type) + w_type = space.allocate_instance(W_TypeObject, w_typetype) + w_type.__init__(space, name, bases_w or [space.w_object], dict_w, None) + return w_type def descr_get__mro__(space, w_type): # XXX this should be inside typeobject.py return space.newtuple(w_type.mro_w) -def descr__dict__(space, w_type): - # XXX should return a - dictspec = [] - for key, w_value in w_type.dict_w.items(): - dictspec.append((space.wrap(key), w_value)) - return space.newdict(dictspec) - def descr__bases(space, w_type): return space.newtuple(w_type.bases_w) @@ -37,6 +31,5 @@ __new__ = newmethod(descr__new__), __name__ = attrproperty('name'), __bases__ = GetSetProperty(descr__bases), - __dict__ = GetSetProperty(descr__dict__), __mro__ = GetSetProperty(descr_get__mro__), ) From arigo at codespeak.net Sat Jun 12 14:35:04 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 14:35:04 +0200 (MEST) Subject: [pypy-svn] r5070 - pypy/trunk/src/pypy/objspace Message-ID: <20040612123504.36E665A1B9@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 14:35:03 2004 New Revision: 5070 Modified: pypy/trunk/src/pypy/objspace/trivial.py Log: Fixed the trivial object space. Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Sat Jun 12 14:35:03 2004 @@ -80,6 +80,7 @@ __repr__ = gateway.interp2app(lambda space, w_x: repr(w_x)), __class__ = GetSetProperty(self.__class__.type), __init__ = gateway.interp2app(Object.descr__init__.im_func), + __dict__ = GetSetProperty(self.__class__.getdict_or_complain), ) # make a wrapped None object none_typedef = TypeDef('NoneType', @@ -144,6 +145,29 @@ unwrap_builtin = unwrap + def getdict(self, w_obj): + if isinstance(w_obj, CPyWrapper): + obj = self.unwrap(w_obj) + if obj.hasdict: + return obj.getdict() + else: + return None + else: + try: + return w_obj.__dict__ + except: + self.reraise() + + def getdict_or_complain(self, w_obj): + result = self.getdict(w_obj) + if result is None: + raise OperationError(self.w_AttributeError, + self.wrap('no __dict__')) + return result + + def allocate_instance(self, cls, w_subtype): + raise NotImplementedError("cannot manually instantiate built-in types") + def hackwrapperclass(self, typedef): try: return typedef.trivialwrapperclass From arigo at codespeak.net Sat Jun 12 16:12:08 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 16:12:08 +0200 (MEST) Subject: [pypy-svn] r5071 - in pypy/trunk/src/pypy: interpreter module/test objspace objspace/std objspace/std/test Message-ID: <20040612141208.212CA5A1B9@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 16:12:04 2004 New Revision: 5071 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/module.py pypy/trunk/src/pypy/interpreter/typedef.py pypy/trunk/src/pypy/module/test/test_newstyleclasses.py pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/stdtypedef.py pypy/trunk/src/pypy/objspace/std/test/test_userobject.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/std/typetype.py pypy/trunk/src/pypy/objspace/trivial.py Log: * Removed the hasdict class attribute introduced last time. * Added typedef.hasdict instead. * All classes have getdict(), defaulting to return None. * The point of all this is to have only classes with a __dict__ really have a __dict__ descriptor. * Added a couple of tests. * Fixed the "find most specific typedef for new subclass" algorithm. Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Sat Jun 12 16:12:04 2004 @@ -8,7 +8,8 @@ class BaseWrappable: """A subclass of BaseWrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" - hasdict = False + def getdict(self): + return None def __spacebind__(self, space): return self Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Sat Jun 12 16:12:04 2004 @@ -161,9 +161,9 @@ nkwds) raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - hasdict = True def getdict(self): return self.w_func_dict + def setdict(self, w_dict): self.w_func_dict = w_dict Modified: pypy/trunk/src/pypy/interpreter/module.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/module.py (original) +++ pypy/trunk/src/pypy/interpreter/module.py Sat Jun 12 16:12:04 2004 @@ -15,9 +15,9 @@ self.w_name = w_name space.setitem(w_dict, space.wrap('__name__'), w_name) - hasdict = True def getdict(self): return self.w_dict + def setdict(self, w_dict): self.w_dict = w_dict Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Sat Jun 12 16:12:04 2004 @@ -10,6 +10,7 @@ def __init__(self, __name, __base=None, **rawdict): self.name = __name self.base = __base + self.hasdict = '__dict__' in rawdict or (__base and __base.hasdict) self.rawdict = rawdict @@ -31,13 +32,12 @@ # XXX sanity checks here self.w__class__ = w_subtype - if cls.hasdict: + if typedef.hasdict: def user_setup(self, space, w_subtype): self.space = space self.w__class__ = w_subtype else: - hasdict = True def getdict(self): return self.w__dict__ @@ -136,6 +136,17 @@ from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell +def descr_get_dict(space, w_obj): + w_dict = w_obj.getdict() + assert w_dict is not None, repr(w_obj) + return w_dict + +def descr_set_dict(space, w_obj, w_dict): + w_obj.setdict(w_dict) + +default_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict) + + Code.typedef = TypeDef('internal-code', co_name = attrproperty('co_name'), # XXX compute more co_xxx from the methods in Code @@ -172,6 +183,7 @@ Module.typedef = TypeDef("module", __new__ = interp2app(Module.descr_module__new__.im_func), __init__ = interp2app(Module.descr_module__init__.im_func), + __dict__ = default_dict_descr, ) getset_func_doc = GetSetProperty(Function.fget_func_doc, @@ -188,7 +200,8 @@ func_defaults = GetSetProperty(Function.fget_func_defaults), func_globals = attrproperty_w('w_func_globals'), __doc__ = getset_func_doc, - __name__ = attrproperty('name'), + __name__ = attrproperty('name'), + __dict__ = default_dict_descr, # XXX func_closure, etc.pp ) Modified: pypy/trunk/src/pypy/module/test/test_newstyleclasses.py ============================================================================== --- pypy/trunk/src/pypy/module/test/test_newstyleclasses.py (original) +++ pypy/trunk/src/pypy/module/test/test_newstyleclasses.py Sat Jun 12 16:12:04 2004 @@ -49,7 +49,7 @@ self.assertRaises(KeyError, delattr, a1, 'name') def test_super(self): - class A: + class A(object): def f(self): return 'A' class B(A): @@ -63,6 +63,7 @@ return 'D' + super(D,self).f() d = D() self.assertEquals(d.f(), "DBCA") + self.assertEquals(D.__mro__, (D, B, C, A, object)) def test_super_metaclass(self): class xtype(type): Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Sat Jun 12 16:12:04 2004 @@ -53,10 +53,7 @@ class DescrOperation: def getdict(space, w_obj): - if w_obj.hasdict: - return w_obj.getdict() - else: - return None + return w_obj.getdict() def is_data_descr(space, w_obj): return space.lookup(w_obj, '__set__') is not None Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Sat Jun 12 16:12:04 2004 @@ -31,22 +31,6 @@ def descr__init__(space, *args_w, **kwds_w): pass # XXX 2.2. behavior: ignoring all arguments -def descr__dict__(space, w_obj): - if w_obj.hasdict: - return w_obj.getdict() - else: - raise OperationError(space.w_AttributeError, - space.wrap("%s instances don't have a __dict__" % ( - space.type(w_obj).name))) - -def descr_set__dict__(space, w_obj, w_dict): - if w_obj.hasdict: - w_obj.setdict(w_dict) - else: - raise OperationError(space.w_AttributeError, - space.wrap("%s instances don't have a __dict__" % ( - space.type(w_obj).name))) - # ____________________________________________________________ object_typedef = StdTypeDef("object", @@ -59,5 +43,4 @@ __class__ = GetSetProperty(descr__class__), __new__ = newmethod(descr__new__), __init__ = gateway.interp2app(descr__init__), - __dict__ = GetSetProperty(descr__dict__, descr_set__dict__), ) 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 Sat Jun 12 16:12:04 2004 @@ -10,8 +10,7 @@ class W_Object(object): "Parent base class for wrapped objects." typedef = None - hasdict = False - + def __init__(w_self, space): w_self.space = space # XXX not sure this is ever used any more @@ -25,6 +24,9 @@ s += ' instance of %s' % self.w__class__ return '<%s>' % s + def getdict(self): + return None + # delegation priorities PRIORITY_SAME_TYPE = 2 # converting between several impls of the same type PRIORITY_PARENT_TYPE = 1 # converting to a base type (e.g. bool -> int) Modified: pypy/trunk/src/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stdtypedef.py (original) +++ pypy/trunk/src/pypy/objspace/std/stdtypedef.py Sat Jun 12 16:12:04 2004 @@ -72,7 +72,8 @@ for descrname, descrvalue in rawdict.items(): dict_w[descrname] = w(descrvalue) - return W_TypeObject(space, typedef.name, bases_w, dict_w, typedef) + return W_TypeObject(space, typedef.name, bases_w, dict_w, + overridetypedef=typedef, forcedict=False) def hack_out_multimethods(ns): result = [] Modified: pypy/trunk/src/pypy/objspace/std/test/test_userobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_userobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_userobject.py Sat Jun 12 16:12:04 2004 @@ -129,5 +129,20 @@ c1.a = 5 self.assertEquals(c1.a, 5) + def test_dict(self): + class A(object): + pass + class B(A): + pass + self.failIf('__dict__' in object.__dict__) + self.assert_('__dict__' in A.__dict__) + self.failIf('__dict__' in B.__dict__) + a = A() + a.x = 5 + self.assertEquals(a.__dict__, {'x': 5}) + a.__dict__ = {'y': 6} + self.assertEquals(a.y, 6) + self.failIf(hasattr(a, 'x')) + 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 Sat Jun 12 16:12:04 2004 @@ -1,12 +1,14 @@ from pypy.objspace.std.objspace import * from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter.typedef import attrproperty_w +from pypy.interpreter.typedef import default_dict_descr from pypy.objspace.std.stdtypedef import issubtypedef +from pypy.objspace.std.objecttype import object_typedef class W_TypeObject(W_Object): from pypy.objspace.std.typetype import type_typedef as typedef - def __init__(w_self, space, name, bases_w, dict_w, overridetypedef=None): + def __init__(w_self, space, name, bases_w, dict_w, + overridetypedef=None, forcedict=True): W_Object.__init__(w_self, space) w_self.name = name w_self.bases_w = bases_w @@ -16,30 +18,18 @@ if overridetypedef is not None: w_self.instancetypedef = overridetypedef else: -## # find the most specific typedef -## longest_mro = [space.object_typedef] -## for w_base in bases_w: -## mro = w_base.instancetypedef.mro(space) -## if len(mro) > len(longest_mro): -## longest_mro = mro -## # check that it is a sub-typedef of all other ones -## for w_base in bases_w: -## if w_base.instancetypedef not in longest_mro: -## raise OperationError(space.w_TypeError, -## space.wrap("instance layout conflicts in " -## "multiple inheritance")) -## w_self.instancetypedef = longest_mro[0] - - assert bases_w # typetype.descr__new__ should take care that there - # is always at least one base - instancetypedef = bases_w[0].instancetypedef - w_self.instancetypedef = instancetypedef - # check that the remaining bases don't have an incompatible 'layout' - for w_base in bases_w[1:]: - if not issubtypedef(instancetypedef, w_base.instancetypedef): + # find the most specific typedef + instancetypedef = object_typedef + for w_base in bases_w: + if issubtypedef(w_base.instancetypedef, instancetypedef): + instancetypedef = w_base.instancetypedef + elif not issubtypedef(instancetypedef, w_base.instancetypedef): raise OperationError(space.w_TypeError, space.wrap("instance layout conflicts in " "multiple inheritance")) + w_self.instancetypedef = instancetypedef + if forcedict and not w_self.lookup('__dict__'): + w_self.dict_w['__dict__'] = space.wrap(default_dict_descr) def ensure_static__new__(w_self): # special-case __new__, as in CPython: @@ -76,7 +66,6 @@ space.wrap("%s.__new__(%s) is not safe, use %s.__new__()" % ( w_self.name, w_subtype.name, w_subtype.name))) - hasdict = True def getdict(w_self): # XXX should return a space = w_self.space 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 Sat Jun 12 16:12:04 2004 @@ -1,4 +1,5 @@ from pypy.objspace.std.stdtypedef import * +from pypy.interpreter.typedef import default_dict_descr def descr__new__(space, w_typetype, w_name, w_bases, w_dict): @@ -15,7 +16,7 @@ assert isinstance(key, str) dict_w[key] = space.getitem(w_dict, w_key) w_type = space.allocate_instance(W_TypeObject, w_typetype) - w_type.__init__(space, name, bases_w or [space.w_object], dict_w, None) + w_type.__init__(space, name, bases_w or [space.w_object], dict_w) return w_type def descr_get__mro__(space, w_type): @@ -32,4 +33,5 @@ __name__ = attrproperty('name'), __bases__ = GetSetProperty(descr__bases), __mro__ = GetSetProperty(descr_get__mro__), + __dict__ = default_dict_descr, ) Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Sat Jun 12 16:12:04 2004 @@ -148,10 +148,7 @@ def getdict(self, w_obj): if isinstance(w_obj, CPyWrapper): obj = self.unwrap(w_obj) - if obj.hasdict: - return obj.getdict() - else: - return None + return obj.getdict() else: try: return w_obj.__dict__ From arigo at codespeak.net Sat Jun 12 16:14:27 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 16:14:27 +0200 (MEST) Subject: [pypy-svn] r5072 - pypy/trunk/src/pypy/interpreter Message-ID: <20040612141427.E6FD15A1B9@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 16:14:27 2004 New Revision: 5072 Modified: pypy/trunk/src/pypy/interpreter/typedef.py Log: Yet Another Fix for the trivial object space. Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Sat Jun 12 16:14:27 2004 @@ -137,12 +137,14 @@ from pypy.interpreter.nestedscope import Cell def descr_get_dict(space, w_obj): - w_dict = w_obj.getdict() - assert w_dict is not None, repr(w_obj) + obj = space.unwrap_builtin(w_obj) + w_dict = obj.getdict() + assert w_dict is not None, repr(obj) return w_dict def descr_set_dict(space, w_obj, w_dict): - w_obj.setdict(w_dict) + obj = space.unwrap_builtin(w_obj) + obj.setdict(w_dict) default_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict) From arigo at codespeak.net Sat Jun 12 16:21:36 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 16:21:36 +0200 (MEST) Subject: [pypy-svn] r5073 - in pypy/trunk/src/pypy/objspace: . std Message-ID: <20040612142136.EAAFC5A1B9@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 16:21:36 2004 New Revision: 5073 Modified: pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/trivial.py Log: Be careful about the names found in the 'exceptions' module, which is a regular app-level module with PyPy. 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 Sat Jun 12 16:21:36 2004 @@ -105,7 +105,9 @@ for k in dir(exceptions): if k not in done: v = getattr(exceptions, k) - if isinstance(v, str): + if not isinstance(v, type(Exception)): + continue + if not issubclass(v, Exception): continue stack = [k] while stack: Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Sat Jun 12 16:21:36 2004 @@ -43,11 +43,11 @@ # connections we have go in the inconvenient direction... for k in dir(exceptions): - if k.startswith('_'): - continue if k not in done: v = getattr(exceptions, k) - if isinstance(v, str): + if not isinstance(v, type(Exception)): + continue + if not issubclass(v, Exception): continue stack = [k] while stack: From arigo at codespeak.net Sat Jun 12 16:40:44 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 16:40:44 +0200 (MEST) Subject: [pypy-svn] r5074 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040612144044.6934D5A1B9@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 16:40:43 2004 New Revision: 5074 Modified: pypy/trunk/src/pypy/objspace/std/objspace.py Log: Hack to replace the cpython-wrapped os.error with our own OSError at wrap time. 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 Sat Jun 12 16:40:43 2004 @@ -242,9 +242,13 @@ w_result = x.__spacebind__(self) #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)) From arigo at codespeak.net Sat Jun 12 16:51:15 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 16:51:15 +0200 (MEST) Subject: [pypy-svn] r5075 - in pypy/trunk/src/pypy: module objspace/std Message-ID: <20040612145115.9C0F05B000@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 16:51:15 2004 New Revision: 5075 Modified: pypy/trunk/src/pypy/module/sysinterp.py pypy/trunk/src/pypy/objspace/std/cpythonobject.py Log: * Copy all exception attributes over to the w_Exception instance in wrap_exception(). * No-one should be allowed to import the 'imp' of CPython! Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Sat Jun 12 16:51:15 2004 @@ -39,7 +39,7 @@ # steal them from Python. for fn in ['posix', 'nt', 'os2', 'mac', 'ce', 'riscos', 'cStringIO', 'itertools', 'math', - '_random', '_sre', 'time', 'imp', '_socket', 'errno', + '_random', '_sre', 'time', '_socket', 'errno', 'marshal', 'struct', 'binascii']: if fn not in builtin_modules: try: Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Sat Jun 12 16:51:15 2004 @@ -90,6 +90,9 @@ w_value = space.call(w_exc, space.newtuple([space.wrap(a) for a in value.args]), space.newdict([])) + 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) From arigo at codespeak.net Sat Jun 12 17:01:53 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 17:01:53 +0200 (MEST) Subject: [pypy-svn] r5076 - in pypy/trunk/src/pypy/module: . test Message-ID: <20040612150153.8ED5E5C0C2@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 17:01:52 2004 New Revision: 5076 Modified: pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/test/test_builtin.py Log: Fixed the built-in compile() to catch SyntaxError (duh!). Added tests. 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 Sat Jun 12 17:01:52 2004 @@ -209,6 +209,8 @@ # It would be nice to propagate all exceptions to app level, # but here we only propagate the 'usual' ones, until we figure # out how to do it generically. + except SyntaxError,e: + raise OperationError(space.w_SyntaxError,space.wrap(str(e))) except ValueError,e: raise OperationError(space.w_ValueError,space.wrap(str(e))) except TypeError,e: 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 Sat Jun 12 17:01:52 2004 @@ -230,6 +230,14 @@ self.assertRaises(TypeError, hash, []) self.assertRaises(TypeError, hash, {}) + def test_compile(self): + co = compile('1+2', '?', 'eval') + self.assertEquals(eval(co), 3) + self.assertRaises(SyntaxError, compile, '-', '?', 'eval') + self.assertRaises(ValueError, compile, '"\\xt"', '?', 'eval') + self.assertRaises(ValueError, compile, '1+2', '?', 'maybenot') + self.assertRaises(TypeError, compile, '1+2', 12, 34) + class TestInternal(testit.IntTestCase): From mwh at codespeak.net Sat Jun 12 17:45:00 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 12 Jun 2004 17:45:00 +0200 (MEST) Subject: [pypy-svn] r5077 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040612154500.E73465C0C2@thoth.codespeak.net> Author: mwh Date: Sat Jun 12 17:44:59 2004 New Revision: 5077 Modified: pypy/trunk/src/pypy/objspace/std/boolobject.py pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/default.py pypy/trunk/src/pypy/objspace/std/dictobject.py pypy/trunk/src/pypy/objspace/std/floatobject.py pypy/trunk/src/pypy/objspace/std/intobject.py pypy/trunk/src/pypy/objspace/std/inttype.py pypy/trunk/src/pypy/objspace/std/listobject.py pypy/trunk/src/pypy/objspace/std/listtype.py pypy/trunk/src/pypy/objspace/std/longobject.py pypy/trunk/src/pypy/objspace/std/longtype.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/tupleobject.py Log: mass unrelativization of imports in the std objspace. 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 Sat Jun 12 17:44:59 2004 @@ -1,9 +1,9 @@ from pypy.objspace.std.objspace import * -import intobject +from pypy.objspace.std import intobject class W_BoolObject(W_Object): - from booltype import bool_typedef as typedef + from pypy.objspace.std.booltype import bool_typedef as typedef def __init__(w_self, space, boolval): W_Object.__init__(w_self, space) Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Sat Jun 12 17:44:59 2004 @@ -3,7 +3,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter.function import Function -from default import UnwrapError +from pypy.objspace.std.default import UnwrapError import sys, operator, types class W_BuiltinFunctionObject(Function): Modified: pypy/trunk/src/pypy/objspace/std/default.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/default.py (original) +++ pypy/trunk/src/pypy/objspace/std/default.py Sat Jun 12 17:44:59 2004 @@ -8,7 +8,7 @@ def id__ANY(space, w_obj): #print 'id:', w_obj - import intobject + from pypy.objspace.std import intobject return intobject.W_IntObject(space, id(w_obj)) # __init__ should succeed if called internally as a multimethod 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 Sat Jun 12 17:44:59 2004 @@ -8,7 +8,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from restricted_int import r_uint +from pypy.objspace.std.restricted_int import r_uint dummy = object() @@ -155,7 +155,7 @@ dict_has_key__Dict_ANY = contains__Dict_ANY def iter__Dict(space, w_dict): - import iterobject + from pypy.objspace.std import iterobject w_keys = dict_keys__Dict(space, w_dict) return iterobject.W_SeqIterObject(space, w_keys) 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 Jun 12 17:44:59 2004 @@ -1,5 +1,5 @@ from pypy.objspace.std.objspace import * -from noneobject import W_NoneObject +from pypy.objspace.std.noneobject import W_NoneObject ############################################################## # for the time being, all calls that are made to some external @@ -8,7 +8,7 @@ ############################################################## import math -from intobject import W_IntObject +from pypy.objspace.std.intobject import W_IntObject class W_FloatObject(W_Object): """This is a reimplementation of the CPython "PyFloatObject" 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 Sat Jun 12 17:44:59 2004 @@ -1,6 +1,6 @@ from pypy.objspace.std.objspace import * -from noneobject import W_NoneObject -from restricted_int import r_int, LONG_BIT +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.restricted_int import r_int, LONG_BIT """ The implementation of integers is a bit difficult, @@ -18,7 +18,7 @@ """ class W_IntObject(W_Object): - from inttype import int_typedef as typedef + from pypy.objspace.std.inttype import int_typedef as typedef def __init__(w_self, space, intval): W_Object.__init__(w_self, space) 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 Sat Jun 12 17:44:59 2004 @@ -2,7 +2,7 @@ from pypy.interpreter.error import OperationError def descr__new__(space, w_inttype, w_value=None, w_base=None): - from intobject import W_IntObject + from pypy.objspace.std.intobject import W_IntObject if w_base is None: w_base = space.w_None if w_value is None: Modified: pypy/trunk/src/pypy/objspace/std/listobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/listobject.py Sat Jun 12 17:44:59 2004 @@ -1,11 +1,11 @@ from pypy.objspace.std.objspace import * -from intobject import W_IntObject -from sliceobject import W_SliceObject -from tupleobject import W_TupleObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.tupleobject import W_TupleObject -import slicetype +from pypy.objspace.std import slicetype from pypy.interpreter import gateway -from restricted_int import r_int, r_uint +from pypy.objspace.std.restricted_int import r_int, r_uint class W_ListObject(W_Object): @@ -90,7 +90,7 @@ return w_res def iter__List(space, w_list): - import iterobject + from pypy.objspace.std import iterobject return iterobject.W_SeqIterObject(space, w_list) def add__List_List(space, w_list1, w_list2): Modified: pypy/trunk/src/pypy/objspace/std/listtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/listtype.py Sat Jun 12 17:44:59 2004 @@ -14,7 +14,7 @@ # ____________________________________________________________ def descr__new__(space, w_listtype, *args_w, **kwds_w): - from listobject import W_ListObject + from pypy.objspace.std.listobject import W_ListObject w_obj = space.allocate_instance(W_ListObject, w_listtype) w_obj.__init__(space, []) return w_obj 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 Sat Jun 12 17:44:59 2004 @@ -1,8 +1,8 @@ import sys from pypy.objspace.std.objspace import * -from intobject import W_IntObject -from floatobject import W_FloatObject -from noneobject import W_NoneObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.floatobject import W_FloatObject +from pypy.objspace.std.noneobject import W_NoneObject class W_LongObject(W_Object): """This is a non-reimplementation of longs. 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 Sat Jun 12 17:44:59 2004 @@ -1,7 +1,7 @@ from pypy.objspace.std.stdtypedef import * def descr__new__(space, w_longtype, w_value=None): - from longobject import W_LongObject + from pypy.objspace.std.longobject import W_LongObject if w_value is None: value = 0L elif space.is_true(space.isinstance(w_value, space.w_str)): Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Sat Jun 12 17:44:59 2004 @@ -23,7 +23,7 @@ def descr__new__(space, w_type, *args_w, **kwds_w): # XXX 2.2 behavior: ignoring all arguments - from objectobject import W_ObjectObject + from pypy.objspace.std.objectobject import W_ObjectObject w_obj = space.allocate_instance(W_ObjectObject, w_type) w_obj.__init__(space) return w_obj 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 Sat Jun 12 17:44:59 2004 @@ -53,17 +53,17 @@ class result: "Import here the types you want to have appear in __builtin__." - from objecttype import object_typedef - from booltype import bool_typedef - from inttype import int_typedef - from floattype import float_typedef - from tupletype import tuple_typedef - from listtype import list_typedef - from dicttype import dict_typedef - from stringtype import str_typedef - from typetype import type_typedef - from slicetype import slice_typedef - from longtype import long_typedef + from pypy.objspace.std.objecttype import object_typedef + from pypy.objspace.std.booltype import bool_typedef + from pypy.objspace.std.inttype import int_typedef + from pypy.objspace.std.floattype import float_typedef + 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.stringtype import str_typedef + from pypy.objspace.std.typetype import type_typedef + from pypy.objspace.std.slicetype import slice_typedef + from pypy.objspace.std.longtype import long_typedef return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look @@ -139,19 +139,19 @@ # 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. - import objectobject - import boolobject - import intobject - import floatobject - import tupleobject - import listobject - import dictobject - import stringobject - import typeobject - import sliceobject - import longobject - import noneobject - import cpythonobject + from pypy.objspace.std import objectobject + from pypy.objspace.std import boolobject + from pypy.objspace.std import intobject + from pypy.objspace.std import floatobject + from pypy.objspace.std import tupleobject + from pypy.objspace.std import listobject + from pypy.objspace.std import dictobject + from pypy.objspace.std import stringobject + from pypy.objspace.std import typeobject + from pypy.objspace.std import sliceobject + from pypy.objspace.std import longobject + from pypy.objspace.std import noneobject + 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 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 Sat Jun 12 17:44:59 2004 @@ -73,19 +73,19 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from intobject import W_IntObject -from sliceobject import W_SliceObject -import slicetype -from listobject import W_ListObject -from noneobject import W_NoneObject -from tupleobject import W_TupleObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std import slicetype +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.tupleobject import W_TupleObject # XXX consider reimplementing _value to be a list of characters # instead of a plain string class W_StringObject(W_Object): - from stringtype import str_typedef as typedef + from pypy.objspace.std.stringtype import str_typedef as typedef def __init__(w_self, space, str): W_Object.__init__(w_self, space) @@ -933,7 +933,7 @@ def iter__String(space, w_list): - import iterobject + from pypy.objspace.std import iterobject return iterobject.W_SeqIterObject(space, w_list) Modified: pypy/trunk/src/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/tupleobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/tupleobject.py Sat Jun 12 17:44:59 2004 @@ -1,7 +1,7 @@ from pypy.objspace.std.objspace import * -from intobject import W_IntObject -from sliceobject import W_SliceObject -import slicetype +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std import slicetype class W_TupleObject(W_Object): @@ -49,7 +49,7 @@ return W_TupleObject(space, subitems) def iter__Tuple(space, w_tuple): - import iterobject + from pypy.objspace.std import iterobject return iterobject.W_SeqIterObject(space, w_tuple) def add__Tuple_Tuple(space, w_tuple1, w_tuple2): From arigo at codespeak.net Sat Jun 12 17:54:42 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 17:54:42 +0200 (MEST) Subject: [pypy-svn] r5078 - pypy/trunk/src/pypy/appspace Message-ID: <20040612155442.E83C45C0C2@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 17:54:42 2004 New Revision: 5078 Added: pypy/trunk/src/pypy/appspace/imp.py Log: Draft 'imp' module at app-level. Added: pypy/trunk/src/pypy/appspace/imp.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/appspace/imp.py Sat Jun 12 17:54:42 2004 @@ -0,0 +1,69 @@ +""" +This module provides the components needed to build your own +__import__ function. Undocumented functions are obsolete. +""" + +# XXX partial implementation + +# XXX to be reviewed + +import sys, os + +PY_SOURCE = 1 +PKG_DIRECTORY = 5 +C_BUILTIN = 6 + +def get_suffixes(): + return [('.py', 'U', PY_SOURCE)] + +new_module = type(sys) + + +def find_module(name, path=None): + if path is None: + if name in sys.builtin_module_names: + return (None, name, ('', '', C_BUILTIN)) + path = sys.path + for base in path: + filename = os.path.join(base, name) + if os.path.isdir(filename): + return (None, filename, ('', '', PKG_DIRECTORY)) + filename += '.py' + if os.path.exists(filename): + return (file(filename, 'U'), filename, ('.py', 'U', PY_SOURCE)) + raise ImportError, 'No module named %s' % (name,) + + +def load_module(name, file, filename, description): + suffix, mode, type = description + module = sys.modules.get(name) + + if type == PY_SOURCE: + source = file.read() + co = compile(source, filename, 'exec') + if module is None: + sys.modules[name] = module = new_module(name) + module.__dict__.clear() + module.__name__ = name + module.__doc__ = None + module.__file__ = filename + exec co in module.__dict__ + return module + + if type == PKG_DIRECTORY: + initfilename = os.path.join(filename, '__init__.py') + if module is None: + sys.modules[name] = module = new_module(name) + module.__dict__.clear() + module.__name__ = name + module.__doc__ = None + module.__file__ = initfilename + module.__path__ = [filename] + execfile(initfilename, module.__dict__) + return module + + if type == C_BUILTIN: + module = __import__(name, {}, {}, None) + return module + + raise ValueError, 'invalid description argument: %r' % (description,) From mwh at codespeak.net Sat Jun 12 18:01:54 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 12 Jun 2004 18:01:54 +0200 (MEST) Subject: [pypy-svn] r5079 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040612160154.1580F5C0C2@thoth.codespeak.net> Author: mwh Date: Sat Jun 12 18:01:53 2004 New Revision: 5079 Modified: pypy/trunk/src/pypy/objspace/std/objspace.py Log: kill a few hard tabs in objspace.py 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 Sat Jun 12 18:01:53 2004 @@ -64,7 +64,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 - return [value for key, value in result.__dict__.items() + return [value for key, value in result.__dict__.items() if not key.startswith('_')] # don't look def clone_exception_hierarchy(self): @@ -151,26 +151,26 @@ from pypy.objspace.std import sliceobject from pypy.objspace.std import longobject from pypy.objspace.std import noneobject - from pypy.objspace.std import cpythonobject - # hack to avoid imports in the time-critical functions below + 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_CPythonObject, W_BuiltinFunctionObject - W_ObjectObject = objectobject.W_ObjectObject - W_BoolObject = boolobject.W_BoolObject - W_IntObject = intobject.W_IntObject - W_FloatObject = floatobject.W_FloatObject - W_TupleObject = tupleobject.W_TupleObject - W_ListObject = listobject.W_ListObject + global W_TupleObject, W_ListObject, W_DictObject, W_StringObject + global W_TypeObject, W_SliceObject, W_LongObject, W_NoneObject + global W_CPythonObject, W_BuiltinFunctionObject + W_ObjectObject = objectobject.W_ObjectObject + W_BoolObject = boolobject.W_BoolObject + W_IntObject = intobject.W_IntObject + W_FloatObject = floatobject.W_FloatObject + W_TupleObject = tupleobject.W_TupleObject + W_ListObject = listobject.W_ListObject W_DictObject = dictobject.W_DictObject - W_StringObject = stringobject.W_StringObject - W_TypeObject = typeobject.W_TypeObject - W_SliceObject = sliceobject.W_SliceObject - W_LongObject = longobject.W_LongObject + W_StringObject = stringobject.W_StringObject + W_TypeObject = typeobject.W_TypeObject + W_SliceObject = sliceobject.W_SliceObject + W_LongObject = longobject.W_LongObject W_NoneObject = noneobject.W_NoneObject - W_CPythonObject = cpythonobject.W_CPythonObject - W_BuiltinFunctionObject = cpythonobject.W_BuiltinFunctionObject + W_CPythonObject = cpythonobject.W_CPythonObject + W_BuiltinFunctionObject = cpythonobject.W_BuiltinFunctionObject # end of hacks # singletons @@ -372,7 +372,7 @@ try: return space.newint(hash(w_obj.cpyobj)) except: - from pypy.objspace.std import cpythonobject + from pypy.objspace.std import cpythonobject cpythonobject.wrap_exception(space) else: w = space.wrap From arigo at codespeak.net Sat Jun 12 18:04:23 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 18:04:23 +0200 (MEST) Subject: [pypy-svn] r5080 - pypy/trunk/src/pypy/interpreter Message-ID: <20040612160423.04C6B5C0C2@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 18:04:23 2004 New Revision: 5080 Modified: pypy/trunk/src/pypy/interpreter/error.py pypy/trunk/src/pypy/interpreter/py.py Log: Removed our custom sys.excepthook and replaced it with an except catching OperationErrors in py.py. Modified: pypy/trunk/src/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/error.py (original) +++ pypy/trunk/src/pypy/interpreter/error.py Sat Jun 12 18:04:23 2004 @@ -95,8 +95,9 @@ interpr_file = LinePrefixer(file, '||') print >> interpr_file, "Traceback (interpreter-level):" traceback.print_tb(self.debug_excs[i][2], file=interpr_file) - from pypy.tool import tb_server - tb_server.publish_exc(self.debug_excs[-1]) + if self.debug_excs: + from pypy.tool import tb_server + tb_server.publish_exc(self.debug_excs[-1]) self.print_app_tb_only(file) if space is None: exc_typename = str(self.w_type) @@ -148,15 +149,15 @@ if self.linestart: self.file.write('\n') -# installing the excepthook for OperationErrors -def operr_excepthook(exctype, value, traceback): - if issubclass(exctype, OperationError): - value.debug_excs.append((exctype, value, traceback)) - value.print_detailed_traceback() - else: - old_excepthook(exctype, value, traceback) - from pypy.tool import tb_server - tb_server.publish_exc((exctype, value, traceback)) +### installing the excepthook for OperationErrors +##def operr_excepthook(exctype, value, traceback): +## if issubclass(exctype, OperationError): +## value.debug_excs.append((exctype, value, traceback)) +## value.print_detailed_traceback() +## else: +## old_excepthook(exctype, value, traceback) +## from pypy.tool import tb_server +## tb_server.publish_exc((exctype, value, traceback)) -old_excepthook = sys.excepthook -sys.excepthook = operr_excepthook +##old_excepthook = sys.excepthook +##sys.excepthook = operr_excepthook Modified: pypy/trunk/src/pypy/interpreter/py.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/py.py (original) +++ pypy/trunk/src/pypy/interpreter/py.py Sat Jun 12 18:04:23 2004 @@ -34,6 +34,7 @@ def main_(argv=None): from pypy.tool import tb_server args = option.process_options(get_main_options(), Options, argv[1:]) + space = None try: space = option.objspace() go_interactive = Options.interactive @@ -63,13 +64,14 @@ con.interact(banner) except: exc_type, value, tb = sys.exc_info() - if (isinstance(exc_type, type(SystemExit)) and - issubclass(exc_type, SystemExit)): + sys.last_type = exc_type + sys.last_value = value + sys.last_traceback = tb + if issubclass(exc_type, SystemExit): pass # don't print tracebacks for SystemExit + elif isinstance(value, error.OperationError): + value.print_detailed_traceback(space=space) else: - sys.last_type = exc_type - sys.last_value = value - sys.last_traceback = tb sys.excepthook(exc_type, value, tb) tb_server.wait_until_interrupt() From arigo at codespeak.net Sat Jun 12 18:32:58 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 18:32:58 +0200 (MEST) Subject: [pypy-svn] r5081 - in pypy/trunk/src/pypy/interpreter: . test Message-ID: <20040612163258.220D15C0C2@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 18:32:58 2004 New Revision: 5081 Modified: pypy/trunk/src/pypy/interpreter/pycode.py pypy/trunk/src/pypy/interpreter/test/test_code.py pypy/trunk/src/pypy/interpreter/typedef.py Log: new.code(). Modified: pypy/trunk/src/pypy/interpreter/pycode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pycode.py (original) +++ pypy/trunk/src/pypy/interpreter/pycode.py Sat Jun 12 18:32:58 2004 @@ -98,6 +98,32 @@ # first approximation return dis.findlabels(self.co_code) + def descr_code__new__(space, w_subtype, + w_argcount, w_nlocals, w_stacksize, w_flags, + w_codestring, w_constants, w_names, + w_varnames, w_filename, w_name, w_firstlineno, + w_lnotab, w_freevars=None, w_cellvars=None): + code = space.allocate_instance(PyCode, w_subtype) + code.__init__() + # XXX typechecking everywhere! + code.co_argcount = space.unwrap(w_argcount) + code.co_nlocals = space.unwrap(w_nlocals) + code.co_stacksize = space.unwrap(w_stacksize) + code.co_flags = space.unwrap(w_flags) + code.co_code = space.unwrap(w_codestring) + code.co_consts = space.unwrap(w_constants) + code.co_names = space.unwrap(w_names) + code.co_varnames = space.unwrap(w_varnames) + code.co_filename = space.unwrap(w_filename) + code.co_name = space.unwrap(w_name) + code.co_firstlineno= space.unwrap(w_firstlineno) + code.co_lnotab = space.unwrap(w_lnotab) + if w_freevars is not None: + code.co_freevars = space.unwrap(w_freevars) + if w_cellvars is not None: + code.co_cellvars = space.unwrap(w_cellvars) + return space.wrap(code) + def enhanceclass(baseclass, newclass, cache={}): # this is a bit too dynamic for RPython, but it looks nice Modified: pypy/trunk/src/pypy/interpreter/test/test_code.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_code.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_code.py Sat Jun 12 18:32:58 2004 @@ -15,6 +15,43 @@ self.assertEquals(code.co_names,()) self.assertEquals(code.co_varnames,()) self.assertEquals(code.co_argcount,0) + def test_code(self): + import new + codestr = "global c\na = 1\nb = 2\nc = a + b\n" + ccode = compile(codestr, '', 'exec') + co = new.code(ccode.co_argcount, + ccode.co_nlocals, + ccode.co_stacksize, + ccode.co_flags, + ccode.co_code, + ccode.co_consts, + ccode.co_names, + ccode.co_varnames, + ccode.co_filename, + ccode.co_name, + ccode.co_firstlineno, + ccode.co_lnotab, + ccode.co_freevars, + ccode.co_cellvars) + d = {} + exec co in d + self.assertEquals(d['c'], 3) + # test backwards-compatibility version with no freevars or cellvars + co = new.code(ccode.co_argcount, + ccode.co_nlocals, + ccode.co_stacksize, + ccode.co_flags, + ccode.co_code, + ccode.co_consts, + ccode.co_names, + ccode.co_varnames, + ccode.co_filename, + ccode.co_name, + ccode.co_firstlineno, + ccode.co_lnotab) + d = {} + exec co in d + self.assertEquals(d['c'], 3) 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 Sat Jun 12 18:32:58 2004 @@ -162,6 +162,7 @@ ) PyCode.typedef = TypeDef('code', + __new__ = interp2app(PyCode.descr_code__new__.im_func), co_argcount = attrproperty('co_argcount'), co_nlocals = attrproperty('co_nlocals'), co_stacksize = attrproperty('co_stacksize'), From arigo at codespeak.net Sat Jun 12 18:34:34 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 12 Jun 2004 18:34:34 +0200 (MEST) Subject: [pypy-svn] r5082 - in pypy/trunk/src/pypy: appspace module Message-ID: <20040612163434.300015C0C2@thoth.codespeak.net> Author: arigo Date: Sat Jun 12 18:34:33 2004 New Revision: 5082 Modified: pypy/trunk/src/pypy/appspace/imp.py pypy/trunk/src/pypy/module/sysinterp.py Log: Steps towards running utest at app-level. Modified: pypy/trunk/src/pypy/appspace/imp.py ============================================================================== --- pypy/trunk/src/pypy/appspace/imp.py (original) +++ pypy/trunk/src/pypy/appspace/imp.py Sat Jun 12 18:34:33 2004 @@ -13,6 +13,9 @@ PKG_DIRECTORY = 5 C_BUILTIN = 6 +def get_magic(): + return '\x3b\xf2\x0d\x0a' + def get_suffixes(): return [('.py', 'U', PY_SOURCE)] Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Sat Jun 12 18:34:33 2004 @@ -40,7 +40,7 @@ for fn in ['posix', 'nt', 'os2', 'mac', 'ce', 'riscos', 'cStringIO', 'itertools', 'math', '_random', '_sre', 'time', '_socket', 'errno', - 'marshal', 'struct', 'binascii']: + 'marshal', 'struct', 'binascii', 'parser']: if fn not in builtin_modules: try: builtin_modules[fn] = hack_cpython_module(fn) From lac at codespeak.net Sun Jun 13 09:01:31 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 13 Jun 2004 09:01:31 +0200 (MEST) Subject: [pypy-svn] r5083 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040613070131.9523F5BE07@thoth.codespeak.net> Author: lac Date: Sun Jun 13 09:01:29 2004 New Revision: 5083 Added: pypy/branch/src-new-utest/pypy/tool/testconverter.py Log: First check in for the test converter. Now to make it handle multi-line expressions properly. Added: pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- (empty file) +++ pypy/branch/src-new-utest/pypy/tool/testconverter.py Sun Jun 13 09:01:29 2004 @@ -0,0 +1,76 @@ +import re +import unittest + +def parse(string): + i = parser(string, 0) + #print 'Returning ', (string[0:i], string[i+1:]) + return (string[0:i], string[i+1:]) + +def parser(string, i): + #print string[i:] + inDoubleQuotes = False + inSingleQuotes = False + for c in string[i:]: + if string[i] == '(' and not (inSingleQuotes or inDoubleQuotes): + #print "Calling", i+1 + i = parser(string, i+1) + if string[i] == ')' and not (inSingleQuotes or inDoubleQuotes): + #print "Returning", i+1 + return i+1 + if string[i] == '"' and not inSingleQuotes: + if not inDoubleQuotes or not (string[i-1] == '\\' and string[i-2] != + '\\'): + inDoubleQuotes = not inDoubleQuotes + if string[i] == "'" and not inDoubleQuotes: + if not inSingleQuotes or not (string[i-1] == '\\' and string[i-2] != + '\\'): + inSingleQuotes = not inSingleQuotes + + if string[i] == ',' and not inDoubleQuotes and not inSingleQuotes: + return i + i += 1 + raise IndexError + +pattern = re.compile(r'^(\s*)self\.assertEquals\((.*)') + +def parseFile(filename): + fp = file(filename, 'r') + saved = '' + for line in fp: + line = saved + line + match = pattern.search(line) + if match: + s = match.group(2) + try: + a,b = parse(s) + b = b.rstrip() + b = b[:-1] + print '%sassert %s == %s' % (match.group(1), a, b) + saved = '' + except IndexError: + saved = line.rstrip() + #print "Saved: ", saved + else: + print line + +class Testit(unittest.TestCase): + def test(self): + self.assertEquals(parse('111,9'), ('111','9')) + self.assertEquals(parse('x","xx,yyy'), ('x","xx', 'yyy')) + self.assertEquals(parse('xx' + "+\"z'z\"+" + 'x,yyy'),("xx+\"z'z\"+x", " +yyy")) + self.assertEquals(parse("x','xx,yyy"), ("x','xx", "yyy")) + self.assertEquals(parse(r'''x"\","xx,yyy'''), (r'''x"\","xx''', 'yyy')) + self.assertEquals(parse(r'''x'\','xx,yyy'''), (r'''x'\','xx''', 'yyy')) + self.assertEquals(parse(r'''x",\\"xx,yyy'''), (r'''x",\\"xx''', 'yyy')) + self.assertEquals(parse(r'''x',\\'xx,yyy'''), (r'''x',\\'xx''', 'yyy')) + self.assertEquals(parse("(),7"), ("()", "7")) + self.assertEquals(parse("(1+(3*2)),7"), ("(1+(3*2))", "7")) + self.assertEquals(parse("('apa'+(3*2)),7"), ("('apa'+(3*2))", "7")) + self.assertEquals(parse("('ap)a'+(3*2)),7"), ("('ap)a'+(3*2))", "7")) + self.assertRaises(IndexError, parse, "('apa'+(3*2))7") + self.assertRaises(IndexError, parse, "3 +") + +if __name__ == '__main__': + #unittest.main() + parseFile('apa.py') From lac at codespeak.net Sun Jun 13 09:10:37 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 13 Jun 2004 09:10:37 +0200 (MEST) Subject: [pypy-svn] r5084 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040613071037.D96A75BE07@thoth.codespeak.net> Author: lac Date: Sun Jun 13 09:10:37 2004 New Revision: 5084 Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py Log: People who paste in copies of their files because they are too lazy to read the man page for scp deserve it when their long lines don't continue properly Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/testconverter.py (original) +++ pypy/branch/src-new-utest/pypy/tool/testconverter.py Sun Jun 13 09:10:37 2004 @@ -57,8 +57,7 @@ def test(self): self.assertEquals(parse('111,9'), ('111','9')) self.assertEquals(parse('x","xx,yyy'), ('x","xx', 'yyy')) - self.assertEquals(parse('xx' + "+\"z'z\"+" + 'x,yyy'),("xx+\"z'z\"+x", " -yyy")) + self.assertEquals(parse('xx' + "+\"z'z\"+" + 'x,yyy'),("xx+\"z'z\"+x", "yyy")) self.assertEquals(parse("x','xx,yyy"), ("x','xx", "yyy")) self.assertEquals(parse(r'''x"\","xx,yyy'''), (r'''x"\","xx''', 'yyy')) self.assertEquals(parse(r'''x'\','xx,yyy'''), (r'''x'\','xx''', 'yyy')) From mwh at codespeak.net Sun Jun 13 17:33:14 2004 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 13 Jun 2004 17:33:14 +0200 (MEST) Subject: [pypy-svn] r5085 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040613153314.261FB5BE07@thoth.codespeak.net> Author: mwh Date: Sun Jun 13 17:33:13 2004 New Revision: 5085 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py Log: Courtesy of wireless internet at Copenhagen, a first cut at field widths and precision in string formatting. Still more to do, but enough to get dis-goal.py working (only 500 times slower than CPython!) 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 Sun Jun 13 17:33:13 2004 @@ -986,6 +986,25 @@ if c=='%': pieces.append('%') else: + width = None + prec = None + if c in '-0123456789': + j = i + while format[j] in '-0123456789': + 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) @@ -1028,6 +1047,17 @@ else: raise ValueError, "unsupported format character '%s' (%x) at index %d" % ( c, ord(c), i) + 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 = ' '*d + p + pieces[-1] = p state = 0 start = i+1 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 Sun Jun 13 17:33:13 2004 @@ -87,5 +87,24 @@ def test_format_wrong_char(self): self.assertRaises(ValueError, 'a%Zb'.__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 ') + + def test_prec_string(self): + 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 ') + + if __name__ == '__main__': testit.main() From arigo at codespeak.net Tue Jun 15 19:06:35 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 15 Jun 2004 19:06:35 +0200 (MEST) Subject: [pypy-svn] r5088 - in pypy/trunk/src/pypy: appspace appspace/test interpreter module/test/impsubdir module/test/impsubdir/pkg module/test/impsubdir/pkg_r module/test/impsubdir/pkg_r/x module/test/impsubdir/pkg_relative_a module/test/impsubdir/x objspace objspace/std objspace/std/test tool tool/tb_server translator/test Message-ID: <20040615170635.14BA35BE90@thoth.codespeak.net> Author: arigo Date: Tue Jun 15 19:06:29 2004 New Revision: 5088 Modified: pypy/trunk/src/pypy/appspace/exceptions.py (props changed) pypy/trunk/src/pypy/appspace/imp.py (props changed) pypy/trunk/src/pypy/appspace/operator.py (props changed) pypy/trunk/src/pypy/appspace/random.py (props changed) pypy/trunk/src/pypy/appspace/test/test_exceptions.py (props changed) pypy/trunk/src/pypy/interpreter/pytraceback.py (props changed) pypy/trunk/src/pypy/interpreter/typedef.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/b.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_b.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg/abs_x_y.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/ (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/__init__.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/inpkg.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/ (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_r/x/__init__.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/ (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/__init__.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/pkg_relative_a/a.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/x/ (props changed) pypy/trunk/src/pypy/module/test/impsubdir/x/__init__.py (props changed) pypy/trunk/src/pypy/module/test/impsubdir/x/y.py (props changed) pypy/trunk/src/pypy/objspace/descroperation.py (props changed) pypy/trunk/src/pypy/objspace/std/longobject.py (props changed) pypy/trunk/src/pypy/objspace/std/longtype.py (props changed) pypy/trunk/src/pypy/objspace/std/stdtypedef.py (props changed) pypy/trunk/src/pypy/objspace/std/test/test_stringformat.py (props changed) pypy/trunk/src/pypy/tool/bltinchecker.py (props changed) pypy/trunk/src/pypy/tool/stdprofile.py (props changed) pypy/trunk/src/pypy/tool/tb_server/render.py (props changed) pypy/trunk/src/pypy/translator/test/run_snippet.py (contents, props changed) Log: fixeol. Modified: pypy/trunk/src/pypy/translator/test/run_snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/run_snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/run_snippet.py Tue Jun 15 19:06:29 2004 @@ -1,107 +1,107 @@ -""" - - Use all functions in snippet to test translation to pyrex - -""" -import autopath -import traceback -import sys -from pypy.tool import testit -from pypy.translator.translator import Translator - -from pypy.translator.test import snippet - -class Result: - def __init__(self, func, argtypes): - self.func = func - self.argtypes = argtypes - self.r_flow = self.r_annotate = self.r_compile = None - for name in 'flow', 'annotate', 'compile': - method = getattr(self, name) - resname = 'r_' + name - try: - method() - except (KeyboardInterrupt, SystemExit): - raise - except: - self.excinfo = sys.exc_info() - setattr(self, resname, False) - else: - setattr(self, resname, True) - - def flow(self): - self.translator = Translator(func) - self.translator.simplify() - - def annotate(self): - self.translator.annotate(self.argtypes) - - def compile(self): - compiled_function = self.translator.compile() - return compiled_function - -def collect_functions(module, specnamelist): - l = [] - for funcname, value in vars(module).items(): - if not hasattr(value, 'func_code'): - continue - for specname in specnamelist: - if funcname.startswith(specname): - l.append(value) - break - if not specnamelist: - l.append(value) - return l - - -def combine(lists): - if not lists: - yield [] - else: - head = lists[0] - if not isinstance(head, tuple): - head = (head,) - tail = lists[1:] - for item in head: - for com in combine(tail): - yield [item] + com - -def get_arg_types(func): - # func_defaults e.g.: ([int, float], [str, int], int) - if func.func_defaults: - for argtypeslist in combine(func.func_defaults): - yield argtypeslist - else: - yield [] - -# format string for result-lines -format_str = "%-30s %10s %10s %10s" - -def repr_result(res): - name = res.func.func_name - argtypes = res.argtypes - funccall = "%s(%s)" % (name, ", ".join([x.__name__ for x in argtypes])) - flow = res.r_flow and 'ok' or 'fail' - ann = res.r_annotate and 'ok' or 'fail' - comp = res.r_compile and 'ok' or 'fail' - return format_str %(funccall, flow, ann, comp) - -if __name__=='__main__': - specnamelist = sys.argv[1:] - funcs = collect_functions(snippet, specnamelist) - results = [] - print format_str %("functioncall", "flowed", "annotated", "compiled") - for func in funcs: - for argtypeslist in get_arg_types(func): - #print "trying %s %s" %(func, argtypeslist) - result = Result(func, argtypeslist) - results.append(result) - print repr_result(result) - if specnamelist and getattr(result, 'excinfo', None): - traceback.print_exception(*result.excinfo) - raise SystemExit, 1 - - #for res in results: - # print repr_result(res) - - +""" + + Use all functions in snippet to test translation to pyrex + +""" +import autopath +import traceback +import sys +from pypy.tool import testit +from pypy.translator.translator import Translator + +from pypy.translator.test import snippet + +class Result: + def __init__(self, func, argtypes): + self.func = func + self.argtypes = argtypes + self.r_flow = self.r_annotate = self.r_compile = None + for name in 'flow', 'annotate', 'compile': + method = getattr(self, name) + resname = 'r_' + name + try: + method() + except (KeyboardInterrupt, SystemExit): + raise + except: + self.excinfo = sys.exc_info() + setattr(self, resname, False) + else: + setattr(self, resname, True) + + def flow(self): + self.translator = Translator(func) + self.translator.simplify() + + def annotate(self): + self.translator.annotate(self.argtypes) + + def compile(self): + compiled_function = self.translator.compile() + return compiled_function + +def collect_functions(module, specnamelist): + l = [] + for funcname, value in vars(module).items(): + if not hasattr(value, 'func_code'): + continue + for specname in specnamelist: + if funcname.startswith(specname): + l.append(value) + break + if not specnamelist: + l.append(value) + return l + + +def combine(lists): + if not lists: + yield [] + else: + head = lists[0] + if not isinstance(head, tuple): + head = (head,) + tail = lists[1:] + for item in head: + for com in combine(tail): + yield [item] + com + +def get_arg_types(func): + # func_defaults e.g.: ([int, float], [str, int], int) + if func.func_defaults: + for argtypeslist in combine(func.func_defaults): + yield argtypeslist + else: + yield [] + +# format string for result-lines +format_str = "%-30s %10s %10s %10s" + +def repr_result(res): + name = res.func.func_name + argtypes = res.argtypes + funccall = "%s(%s)" % (name, ", ".join([x.__name__ for x in argtypes])) + flow = res.r_flow and 'ok' or 'fail' + ann = res.r_annotate and 'ok' or 'fail' + comp = res.r_compile and 'ok' or 'fail' + return format_str %(funccall, flow, ann, comp) + +if __name__=='__main__': + specnamelist = sys.argv[1:] + funcs = collect_functions(snippet, specnamelist) + results = [] + print format_str %("functioncall", "flowed", "annotated", "compiled") + for func in funcs: + for argtypeslist in get_arg_types(func): + #print "trying %s %s" %(func, argtypeslist) + result = Result(func, argtypeslist) + results.append(result) + print repr_result(result) + if specnamelist and getattr(result, 'excinfo', None): + traceback.print_exception(*result.excinfo) + raise SystemExit, 1 + + #for res in results: + # print repr_result(res) + + From hpk at codespeak.net Tue Jun 15 21:57:04 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 15 Jun 2004 21:57:04 +0200 (MEST) Subject: [pypy-svn] r5089 - pypy/trunk/src/pypy Message-ID: <20040615195704.E1B565BDFC@thoth.codespeak.net> Author: hpk Date: Tue Jun 15 21:57:02 2004 New Revision: 5089 Modified: pypy/trunk/src/pypy/TODO Log: some more nice tasks Modified: pypy/trunk/src/pypy/TODO ============================================================================== --- pypy/trunk/src/pypy/TODO (original) +++ pypy/trunk/src/pypy/TODO Tue Jun 15 21:57:02 2004 @@ -3,6 +3,13 @@ * not all of CPython's exceptions use the same __init__! +* refactor the cmdline-entrypoints to PyPy aka py.py main.py + interactive.py and traceinteractive.py towards a unified + cmdline tool (py.py) possibly including translator-related + things too. + +* cleanup the contents of the tool directory + StdObjSpace =========== From arigo at codespeak.net Tue Jun 15 22:00:18 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 15 Jun 2004 22:00:18 +0200 (MEST) Subject: [pypy-svn] r5090 - pypy/trunk/src/pypy/interpreter Message-ID: <20040615200018.C5F3B5BDFC@thoth.codespeak.net> Author: arigo Date: Tue Jun 15 22:00:11 2004 New Revision: 5090 Modified: pypy/trunk/src/pypy/interpreter/main.py Log: Pseudo-random hacking at the main.py + py.py + interactive.py mess until the '-i' option works even in the case of exceptions. Modified: pypy/trunk/src/pypy/interpreter/main.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/main.py (original) +++ pypy/trunk/src/pypy/interpreter/main.py Tue Jun 15 22:00:11 2004 @@ -24,18 +24,18 @@ mainmodule = module.Module(space, space.wrap("__main__")) w_globals = mainmodule.w_dict - - except OperationError, operationerr: - operationerr.record_interpreter_traceback() - raise PyPyError(space, operationerr) - else: + pycode = space.unwrap(w_code) retval = pycode.exec_code(space, w_globals, w_globals) if eval: return retval else: return - + + except OperationError, operationerr: + operationerr.record_interpreter_traceback() + raise PyPyError(space, operationerr) + def run_string(source, filename='', space=None): _run_eval_string(source, filename, space, False) From arigo at codespeak.net Tue Jun 15 22:00:49 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 15 Jun 2004 22:00:49 +0200 (MEST) Subject: [pypy-svn] r5091 - pypy/trunk/src/pypy/objspace/std/attic Message-ID: <20040615200049.4621B5BDFC@thoth.codespeak.net> Author: arigo Date: Tue Jun 15 22:00:46 2004 New Revision: 5091 Removed: pypy/trunk/src/pypy/objspace/std/attic/ Log: Deleted attic. From arigo at codespeak.net Tue Jun 15 22:17:44 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 15 Jun 2004 22:17:44 +0200 (MEST) Subject: [pypy-svn] r5092 - pypy/trunk/src/pypy/module Message-ID: <20040615201744.644DB5BDFC@thoth.codespeak.net> Author: arigo Date: Tue Jun 15 22:17:43 2004 New Revision: 5092 Modified: pypy/trunk/src/pypy/module/sysmodule.py Log: Added sys.ps1 and sys.ps2, with an extra character as a help to distinguish between levels. Modified: pypy/trunk/src/pypy/module/sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/sysmodule.py (original) +++ pypy/trunk/src/pypy/module/sysmodule.py Tue Jun 15 22:17:43 2004 @@ -19,7 +19,9 @@ # Dummy executable = '' prefix = '' -version = '0.0.0 (not released yet)' +version = '0.5.0 (not released yet)' +ps1 = '>>>> ' +ps2 = '.... ' # XXX not called by the core yet def excepthook(exctype, value, traceback): From lac at codespeak.net Tue Jun 15 22:59:44 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Tue, 15 Jun 2004 22:59:44 +0200 (MEST) Subject: [pypy-svn] r5093 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040615205944.DE0015BDFC@thoth.codespeak.net> Author: lac Date: Tue Jun 15 22:59:41 2004 New Revision: 5093 Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py Log: Ok gang, where am I checking in? not working file, give me a few ... Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/testconverter.py (original) +++ pypy/branch/src-new-utest/pypy/tool/testconverter.py Tue Jun 15 22:59:41 2004 @@ -1,75 +1,99 @@ import re import unittest -def parse(string): - i = parser(string, 0) - #print 'Returning ', (string[0:i], string[i+1:]) - return (string[0:i], string[i+1:]) - -def parser(string, i): - #print string[i:] - inDoubleQuotes = False - inSingleQuotes = False - for c in string[i:]: - if string[i] == '(' and not (inSingleQuotes or inDoubleQuotes): - #print "Calling", i+1 - i = parser(string, i+1) - if string[i] == ')' and not (inSingleQuotes or inDoubleQuotes): - #print "Returning", i+1 - return i+1 - if string[i] == '"' and not inSingleQuotes: - if not inDoubleQuotes or not (string[i-1] == '\\' and string[i-2] != - '\\'): - inDoubleQuotes = not inDoubleQuotes - if string[i] == "'" and not inDoubleQuotes: - if not inSingleQuotes or not (string[i-1] == '\\' and string[i-2] != - '\\'): - inSingleQuotes = not inSingleQuotes - - if string[i] == ',' and not inDoubleQuotes and not inSingleQuotes: - return i - i += 1 - raise IndexError +old_fname = 'self.assertEquals' +new_fname = 'assert' +old_function = re.compile(r'^(\s*)' + old_fname + r'\((.*)') +leading_spaces = re.compile(r'^(\s*)') + +def strip_trailing(line, char=')'): + last = line[len(line)-1] + lastchar = last[-1] + + if lastchar != char : + print "Stripping trailing '%s' from buf '%s', got '%s' instead!" % ( + char, line, lastchar) + return line + else: + """ + buf = s.splitlines() + for l in buf: + if not l.startswith(indentation): + print 'Expected %s but got %s instead' % (indentation, l) + return s + else: + buf[0] = buf[0].replace + print 'hi' + buf[0] + """ + return last[0:-1] + +def process_block(s, interesting, indentation, old, new): + if not interesting: + return s + else: + + import parser + body = s.replace(old, '', 1) + return 'ASSERT' + body + +def blocksplitter(filename): -pattern = re.compile(r'^(\s*)self\.assertEquals\((.*)') - -def parseFile(filename): fp = file(filename, 'r') - saved = '' + blockstring = '' + filestring = '' + current_indent = 0 + was_interesting = False + n_l_s = '' + for line in fp: - line = saved + line - match = pattern.search(line) - if match: - s = match.group(2) - try: - a,b = parse(s) - b = b.rstrip() - b = b[:-1] - print '%sassert %s == %s' % (match.group(1), a, b) - saved = '' - except IndexError: - saved = line.rstrip() - #print "Saved: ", saved - else: - print line -class Testit(unittest.TestCase): - def test(self): - self.assertEquals(parse('111,9'), ('111','9')) - self.assertEquals(parse('x","xx,yyy'), ('x","xx', 'yyy')) - self.assertEquals(parse('xx' + "+\"z'z\"+" + 'x,yyy'),("xx+\"z'z\"+x", "yyy")) - self.assertEquals(parse("x','xx,yyy"), ("x','xx", "yyy")) - self.assertEquals(parse(r'''x"\","xx,yyy'''), (r'''x"\","xx''', 'yyy')) - self.assertEquals(parse(r'''x'\','xx,yyy'''), (r'''x'\','xx''', 'yyy')) - self.assertEquals(parse(r'''x",\\"xx,yyy'''), (r'''x",\\"xx''', 'yyy')) - self.assertEquals(parse(r'''x',\\'xx,yyy'''), (r'''x',\\'xx''', 'yyy')) - self.assertEquals(parse("(),7"), ("()", "7")) - self.assertEquals(parse("(1+(3*2)),7"), ("(1+(3*2))", "7")) - self.assertEquals(parse("('apa'+(3*2)),7"), ("('apa'+(3*2))", "7")) - self.assertEquals(parse("('ap)a'+(3*2)),7"), ("('ap)a'+(3*2))", "7")) - self.assertRaises(IndexError, parse, "('apa'+(3*2))7") - self.assertRaises(IndexError, parse, "3 +") + ls = leading_spaces.search(line) # this will never fail + l_spaces = ls.group(1) + new_indent = len(l_spaces) + + interesting = old_function.search(line) + + if interesting : + # we have found the beginning of a new interesting block. + # finish up your business with your last block, and + # reset everything + + filestring += process_block(blockstring, was_interesting, + n_l_s, old_fname, new_fname) + + blockstring = line # reset the block + current_indent = new_indent + n_l_s = ls.group(1) + was_interesting = True + + elif not was_interesting and not interesting : + # the last line was not interesting and this one isn't either + # just add it to the block + + blockstring += line + + else: + # the slightly-hard case: + # is this line a continuation of the current interesting block? + # or is it just another uninteresting line that follows it? + + if new_indent > current_indent: # continuation + blockstring += line + + # XXXX FIXME: check for comments? line continuations with \? + # Will we ever need it? + + else: # boring follower + filestring += process_block(blockstring, was_interesting, + n_l_s, old_fname, new_fname) + blockstring = line + was_interesting = False + + filestring += process_block(blockstring, was_interesting, n_l_s, + old_fname, new_fname) + + print filestring if __name__ == '__main__': #unittest.main() - parseFile('apa.py') + blocksplitter('xxx.py') From hpk at codespeak.net Wed Jun 16 00:19:25 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 16 Jun 2004 00:19:25 +0200 (MEST) Subject: [pypy-svn] r5094 - in pypy/trunk/src/pypy: interpreter interpreter/test objspace/std Message-ID: <20040615221925.DA3CF5BDFC@thoth.codespeak.net> Author: hpk Date: Wed Jun 16 00:18:41 2004 New Revision: 5094 Added: pypy/trunk/src/pypy/interpreter/special.py pypy/trunk/src/pypy/interpreter/test/test_special.py Modified: pypy/trunk/src/pypy/interpreter/typedef.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: a go at eliminating cpythonobject-wrapping for Ellipsis and NotImplemented. would be nice to put the "Wrappable/BaseWrappable" classes into their own file to reduce import dependencies. Added: pypy/trunk/src/pypy/interpreter/special.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/interpreter/special.py Wed Jun 16 00:18:41 2004 @@ -0,0 +1,15 @@ + +from pypy.interpreter.baseobjspace import Wrappable + +class Ellipsis(Wrappable): + def __init__(self, space): + self.space = space + def descr__repr__(self): + return self.space.wrap('Ellipsis') + +class NotImplemented(Wrappable): + def __init__(self, space): + self.space = space + def descr__repr__(self): + return self.space.wrap('NotImplemented') + Added: pypy/trunk/src/pypy/interpreter/test/test_special.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/interpreter/test/test_special.py Wed Jun 16 00:18:41 2004 @@ -0,0 +1,18 @@ + +import autopath +from pypy.tool import testit + +class SpecialTestCase(testit.AppTestCase): + def test_Ellipsis(self): + self.assertEquals(Ellipsis, Ellipsis) + self.assertEquals(repr(Ellipsis), 'Ellipsis') + + def test_NotImplemented(self): + def f(): + return NotImplemented + self.assertEquals(f(), NotImplemented) + self.assertEquals(repr(NotImplemented), 'NotImplemented') + +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 Jun 16 00:18:41 2004 @@ -135,6 +135,7 @@ from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell +from pypy.interpreter.special import NotImplemented, Ellipsis def descr_get_dict(space, w_obj): obj = space.unwrap_builtin(w_obj) @@ -237,4 +238,12 @@ Cell.typedef = TypeDef("Cell") +Ellipsis.typedef = TypeDef("Ellipsis", + __repr__ = interp2app(Ellipsis.descr__repr__.im_func), +) + +NotImplemented.typedef = TypeDef("NotImplemented", + __repr__ = interp2app(NotImplemented.descr__repr__.im_func), +) + ControlFlowException.typedef = TypeDef("ControlFlowException") 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 Jun 16 00:18:41 2004 @@ -177,8 +177,9 @@ self.w_None = W_NoneObject(self) self.w_False = W_BoolObject(self, False) self.w_True = W_BoolObject(self, True) - self.w_NotImplemented = self.wrap(NotImplemented) # XXX do me - self.w_Ellipsis = self.wrap(Ellipsis) # XXX do me too + from pypy.interpreter.special import NotImplemented, Ellipsis + self.w_NotImplemented = self.wrap(NotImplemented(self)) + self.w_Ellipsis = self.wrap(Ellipsis(self)) for_builtins = {"False": self.w_False, "True" : self.w_True, From lac at codespeak.net Wed Jun 16 10:37:05 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 16 Jun 2004 10:37:05 +0200 (MEST) Subject: [pypy-svn] r5095 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040616083705.3FA675BE06@thoth.codespeak.net> Author: lac Date: Wed Jun 16 10:36:59 2004 New Revision: 5095 Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py Log: uses parser.expr now. after lunch I will put the 'in comment' back in, so that it can tell when to produce 'assert something == something_else' and when to produce 'assert (something more complicated == something else more complicated)' Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/testconverter.py (original) +++ pypy/branch/src-new-utest/pypy/tool/testconverter.py Wed Jun 16 10:36:59 2004 @@ -6,35 +6,59 @@ old_function = re.compile(r'^(\s*)' + old_fname + r'\((.*)') leading_spaces = re.compile(r'^(\s*)') -def strip_trailing(line, char=')'): - last = line[len(line)-1] - lastchar = last[-1] - - if lastchar != char : - print "Stripping trailing '%s' from buf '%s', got '%s' instead!" % ( - char, line, lastchar) - return line - else: - """ - buf = s.splitlines() - for l in buf: - if not l.startswith(indentation): - print 'Expected %s but got %s instead' % (indentation, l) - return s - else: - buf[0] = buf[0].replace - print 'hi' + buf[0] - """ - return last[0:-1] def process_block(s, interesting, indentation, old, new): if not interesting: return s else: + body = s.replace(old, '', 1).lstrip() + + if body.rstrip() == '(,)': # catch this special case early. + print 'malformed block %s cannot be converted' % s.rstrip() + return s + + plist = pos_finder(body, ',') + if plist == []: + print "Could not find a ',' in %s" % body + return s + else: + arglist = [] + for p in plist: + left, right = body[:p], body[p+1:] + arglist.append((left, right)) + r = find_comma(arglist) + + if r is None: + print 'malformed block %s cannot be converted' % s + return s + else: + return indentation + new + r[0] + ') == (' + r[1] + + +def find_comma(tuplelist): + import parser - import parser - body = s.replace(old, '', 1) - return 'ASSERT' + body + # make the python parser do the hard work of deciding which comma + # splits the string into two expressions + + for l, r in tuplelist: + try: + left = l + ')' + right = '(' + r + parser.expr(left) + parser.expr(right) + return l , r # Great! Both sides are expressions! + except SyntaxError: # It wasn't that comma + pass + return None + +def pos_finder(s, char=','): + # returns the list of string positions where the char 'char' was found + pos=[] + for i in range(len(s)): + if s[i] == char: + pos.append(i) + return pos def blocksplitter(filename): From arigo at codespeak.net Wed Jun 16 11:57:06 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 11:57:06 +0200 (MEST) Subject: [pypy-svn] r5096 - in pypy/trunk/src/pypy/objspace: . std std/test Message-ID: <20040616095706.120465BE08@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 11:57:06 2004 New Revision: 5096 Removed: pypy/trunk/src/pypy/objspace/std/test/test_moduleobject.py Modified: pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/std/listobject.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/std/test/test_iterobject.py pypy/trunk/src/pypy/objspace/std/test/test_listobject.py pypy/trunk/src/pypy/objspace/std/test/test_stringobject.py pypy/trunk/src/pypy/objspace/std/test/test_tupleobject.py pypy/trunk/src/pypy/objspace/trivial.py Log: - three test files didn't import and where silently ignored by unittest (!) - implemented iter(sequence-like-instance) -- test_iterobject - implemented list += iterable, which was previously equivalent to list = list + iterable, thus causing subtle trouble -- test_listobject - deleted obsolete test_moduleobject Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Wed Jun 16 11:57:06 2004 @@ -177,8 +177,11 @@ def iter(space,w_obj): w_descr = space.lookup(w_obj,'__iter__') if w_descr is None: - raise OperationError(space.w_TypeError, - space.wrap("object is not iter()-able")) + w_descr = space.lookup(w_obj,'__getitem__') + if w_descr is None: + raise OperationError(space.w_TypeError, + space.wrap("object is not iter()-able")) + return space.newseqiter(w_obj) return space.get_and_call_function(w_descr,w_obj) def next(space,w_obj): Modified: pypy/trunk/src/pypy/objspace/std/listobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/listobject.py Wed Jun 16 11:57:06 2004 @@ -110,6 +110,10 @@ w_res.ob_size = p return w_res +def inplace_add__List_ANY(space, w_list1, w_iterable2): + list_extend__List_ANY(space, w_list1, w_iterable2) + return w_list1 + def mul__List_Int(space, w_list, w_int): w_res = W_ListObject(space, []) times = w_int.intval 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 Jun 16 11:57:06 2004 @@ -151,11 +151,13 @@ from pypy.objspace.std import sliceobject 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 W_ObjectObject = objectobject.W_ObjectObject W_BoolObject = boolobject.W_BoolObject @@ -169,6 +171,7 @@ W_SliceObject = sliceobject.W_SliceObject 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 @@ -287,6 +290,9 @@ self.wrap("character code not in range(256)")) return W_StringObject(self, ''.join(chars)) + def newseqiter(self, w_obj): + return W_SeqIterObject(self, w_obj) + def type(self, w_obj): if isinstance(w_obj, UserSubclass): return w_obj.getclass() Modified: pypy/trunk/src/pypy/objspace/std/test/test_iterobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_iterobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_iterobject.py Wed Jun 16 11:57:06 2004 @@ -1,6 +1,6 @@ import autopath from pypy.objspace.std.iterobject import W_SeqIterObject -from pypy.objspace.std.objspace import NoValue +from pypy.interpreter.error import OperationError from pypy.tool import testit class TestW_IterObject(testit.TestCase): @@ -19,8 +19,8 @@ self.body0(w_iter) def body0(self, w_iter): - self.assertRaises(NoValue, self.space.next, w_iter) - self.assertRaises(NoValue, self.space.next, w_iter) + self.assertRaises(OperationError, self.space.next, w_iter) + self.assertRaises(OperationError, self.space.next, w_iter) def test_iter(self): w = self.space.wrap Modified: pypy/trunk/src/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_listobject.py Wed Jun 16 11:57:06 2004 @@ -1,7 +1,7 @@ #from __future__ import nested_scopes import autopath from pypy.objspace.std.listobject import W_ListObject -from pypy.objspace.std.objspace import NoValue +from pypy.interpreter.error import OperationError from pypy.tool import testit @@ -52,8 +52,8 @@ self.assertEqual_w(self.space.next(w_iter), w(5)) self.assertEqual_w(self.space.next(w_iter), w(3)) self.assertEqual_w(self.space.next(w_iter), w(99)) - self.assertRaises(NoValue, self.space.next, w_iter) - self.assertRaises(NoValue, self.space.next, w_iter) + self.assertRaises(OperationError, self.space.next, w_iter) + self.assertRaises(OperationError, self.space.next, w_iter) def test_contains(self): w = self.space.wrap @@ -276,31 +276,38 @@ self.space = testit.objspace('std') def test_explicit_new_init(self): - l = list.__new__(list) + l = l0 = list.__new__(list) l.__init__([1,2]) + self.assert_(l is l0) self.assertEquals(l,[1,2]) list.__init__(l,[1,2,3]) + self.assert_(l is l0) self.assertEquals(l,[1,2,3]) def test_extend_list(self): - l = [1] + l = l0 = [1] l.extend([2]) + self.assert_(l is l0) self.assertEquals(l, [1,2]) def test_extend_tuple(self): - l = [1] + l = l0 = [1] l.extend((2,)) + self.assert_(l is l0) self.assertEquals(l, [1,2]) def test_sort(self): - l = [1, 5, 3, 0] + l = l0 = [1, 5, 3, 0] l.sort() + self.assert_(l is l0) self.assertEquals(l, [0, 1, 3, 5]) - l = [] + l = l0 = [] l.sort() + self.assert_(l is l0) self.assertEquals(l, []) - l = [1] + l = l0 = [1] l.sort() + self.assert_(l is l0) self.assertEquals(l, [1]) def test_sort_cmp(self): @@ -325,6 +332,18 @@ self.assertEquals(l,[7,5,3]) del l[:2] self.assertEquals(l,[3]) - + + def test_delall(self): + l = l0 = [1,2,3] + del l[:] + self.assert_(l is l0) + self.assertEquals(l, []) + + def test_iadd(self): + l = l0 = [1,2,3] + l += [4,5] + self.assert_(l is l0) + self.assertEquals(l, [1,2,3,4,5]) + if __name__ == '__main__': testit.main() Deleted: /pypy/trunk/src/pypy/objspace/std/test/test_moduleobject.py ============================================================================== --- /pypy/trunk/src/pypy/objspace/std/test/test_moduleobject.py Wed Jun 16 11:57:06 2004 +++ (empty file) @@ -1,34 +0,0 @@ -import autopath -from pypy.objspace.std.moduleobject import W_ModuleObject -from pypy.tool import testit - -class TestW_ModuleObject(testit.TestCase): - - def setUp(self): - self.space = testit.objspace('std') - - def tearDown(self): - pass - - def test_name(self): - space = self.space - w_m = W_ModuleObject(space, space.wrap('somename')) - self.assertEqual_w(space.getattr(w_m, space.wrap('__name__')), - space.wrap('somename')) - - def test_setgetdel(self): - space = self.space - w_x = space.wrap(123) - w_yy = space.w_True - w_m = W_ModuleObject(space, space.wrap('somename')) - space.setattr(w_m, space.wrap('x'), w_x) - space.setattr(w_m, space.wrap('yy'), w_yy) - self.assertEqual_w(space.getattr(w_m, space.wrap('x')), w_x) - self.assertEqual_w(space.getattr(w_m, space.wrap('yy')), w_yy) - space.delattr(w_m, space.wrap('x')) - self.assertRaises_w(space.w_AttributeError, space.getattr, - w_m, space.wrap('x')) - self.assertEqual_w(space.getattr(w_m, space.wrap('yy')), w_yy) - -if __name__ == '__main__': - testit.main() 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 Wed Jun 16 11:57:06 2004 @@ -1,8 +1,7 @@ import autopath from pypy.tool import testit from pypy.objspace.std import stringobject -from pypy.objspace.std.stringobject import \ - string_richcompare, W_StringObject, EQ, LT, GT, NE, LE, GE +from pypy.objspace.std.stringobject import W_StringObject class TestW_StringObject(testit.TestCase): @@ -13,32 +12,32 @@ def tearDown(self): pass - def test_order_rich(self): - space = self.space - def w(txt): - return W_StringObject(space, txt) - strs = ['ala', 'bla', 'ala', 'alaaa', '', 'b'] - ops = [ 'EQ', 'LT', 'GT', 'NE', 'LE', 'GE' ] - - while strs[1:]: - str1 = strs.pop() - for op in ops: - #original python function - orf = getattr(str1, '__%s__' % op.lower()) - pypyconst = getattr(stringobject, op) - for str2 in strs: - if orf(str2): - self.failUnless_w( - string_richcompare(space, - w(str1), - w(str2), - pypyconst)) - else: - self.failIf_w( - string_richcompare(space, - w(str1), - w(str2), - pypyconst)) +## def test_order_rich(self): +## space = self.space +## def w(txt): +## return W_StringObject(space, txt) +## strs = ['ala', 'bla', 'ala', 'alaaa', '', 'b'] +## ops = [ 'EQ', 'LT', 'GT', 'NE', 'LE', 'GE' ] + +## while strs[1:]: +## str1 = strs.pop() +## for op in ops: +## #original python function +## orf = getattr(str1, '__%s__' % op.lower()) +## pypyconst = getattr(stringobject, op) +## for str2 in strs: +## if orf(str2): +## self.failUnless_w( +## string_richcompare(space, +## w(str1), +## w(str2), +## pypyconst)) +## else: +## self.failIf_w( +## string_richcompare(space, +## w(str1), +## w(str2), +## pypyconst)) def test_equality(self): w = self.space.wrap Modified: pypy/trunk/src/pypy/objspace/std/test/test_tupleobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_tupleobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_tupleobject.py Wed Jun 16 11:57:06 2004 @@ -2,7 +2,7 @@ import autopath from pypy.tool import testit from pypy.objspace.std.tupleobject import W_TupleObject -from pypy.objspace.std.objspace import NoValue +from pypy.interpreter.error import OperationError class TestW_TupleObject(testit.TestCase): @@ -52,8 +52,8 @@ self.assertEqual_w(self.space.next(w_iter), w(5)) self.assertEqual_w(self.space.next(w_iter), w(3)) self.assertEqual_w(self.space.next(w_iter), w(99)) - self.assertRaises(NoValue, self.space.next, w_iter) - self.assertRaises(NoValue, self.space.next, w_iter) + self.assertRaises(OperationError, self.space.next, w_iter) + self.assertRaises(OperationError, self.space.next, w_iter) def test_contains(self): w = self.space.wrap Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Wed Jun 16 11:57:06 2004 @@ -397,6 +397,12 @@ except: self.reraise() + def newseqiter(self, w_obj): + try: + return iter(w_obj) + except: + self.reraise() + #def call(self, callable, args, kwds): # if isinstance(callable, types.ClassType): # import new From jum at codespeak.net Wed Jun 16 12:40:40 2004 From: jum at codespeak.net (jum at codespeak.net) Date: Wed, 16 Jun 2004 12:40:40 +0200 (MEST) Subject: [pypy-svn] r5097 - pypy/trunk/doc/devel Message-ID: <20040616104040.154AF5BE11@thoth.codespeak.net> Author: jum Date: Wed Jun 16 12:40:39 2004 New Revision: 5097 Modified: pypy/trunk/doc/devel/howtosvn.txt Log: Updated OS X version. Modified: pypy/trunk/doc/devel/howtosvn.txt ============================================================================== --- pypy/trunk/doc/devel/howtosvn.txt (original) +++ pypy/trunk/doc/devel/howtosvn.txt Wed Jun 16 12:40:39 2004 @@ -140,7 +140,7 @@ .. _website: http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B259403 .. _GUI: http://tortoisesvn.tigris.org/servlets/ProjectDocumentList?folderID=616 -.. _MacOS: http://codespeak.net/~jum/svn-1.0.4-darwin-ppc.tar.gz +.. _MacOS: http://codespeak.net/~jum/svn-1.0.5-darwin-ppc.tar.gz .. _versions: http://subversion.tigris.org/project_packages.html .. _Win: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=4B6140F9-2D36-4977-8FA1-6F8A0F5DCA8F From arigo at codespeak.net Wed Jun 16 13:34:09 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 13:34:09 +0200 (MEST) Subject: [pypy-svn] r5099 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040616113409.745E85C1B7@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 13:34:08 2004 New Revision: 5099 Modified: pypy/trunk/src/pypy/objspace/std/longobject.py Log: long-to-int delegation allows expression like 'somelist[5L]' to succeed. 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 Wed Jun 16 13:34:08 2004 @@ -25,6 +25,16 @@ delegate__Int.result_class = W_LongObject delegate__Int.priority = PRIORITY_CHANGE_TYPE +# long-to-int delegation +def delegate__Long(space, w_longobj): + if -sys.maxint-1 <= w_longobj.longval <= sys.maxint: + return W_IntObject(space, int(w_longobj.longval)) + else: + raise OperationError(space.w_OverflowError, + space.wrap("long too large to convert to int")) +delegate__Long.result_class = W_IntObject +delegate__Long.priority = PRIORITY_CHANGE_TYPE + def long__Long(space, w_value): return w_value From arigo at codespeak.net Wed Jun 16 13:49:30 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 13:49:30 +0200 (MEST) Subject: [pypy-svn] r5101 - pypy/trunk/src/pypy/tool Message-ID: <20040616114930.079DE5C1B8@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 13:49:29 2004 New Revision: 5101 Added: pypy/trunk/src/pypy/tool/pypyutest.py Log: Demo for re-interpreting app-level tests. Added: pypy/trunk/src/pypy/tool/pypyutest.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/tool/pypyutest.py Wed Jun 16 13:49:29 2004 @@ -0,0 +1,39 @@ +from std.__impl__.magic import exprinfo +from pypy.objspace.std import StdObjSpace + +class AppRunnerFrame: + + def __init__(self, space, w_globals, w_locals): + self.space = space + self.w_globals = w_globals + self.w_locals = w_locals + + def eval(self, code, **vars): + space = self.space + for key, w_value in vars.items(): + space.setitem(self.w_locals, space.wrap(key), w_value) + return space.eval(code, self.w_globals, self.w_locals) + + def exec_(self, code, **vars): + space = self.space + for key, w_value in vars.items(): + space.setitem(self.w_locals, space.wrap(key), w_value) + space.exec_(code, self.w_globals, self.w_locals) + + def repr(self, w_value): + return self.space.unwrap(self.space.repr(w_value)) + + def is_true(self, w_value): + return self.space.is_true(w_value) + + +def test(): + space = StdObjSpace() + w_glob = space.newdict([]) + w_loc = space.newdict([]) + runner = AppRunnerFrame(space, w_glob, w_loc) + exprinfo.run("f = lambda x: x+1", runner) + exprinfo.check("isinstance(f(2), float)", runner) + +if __name__ == '__main__': + test() From arigo at codespeak.net Wed Jun 16 14:17:12 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 14:17:12 +0200 (MEST) Subject: [pypy-svn] r5102 - in pypy/trunk/src/pypy/objspace/std: . test Message-ID: <20040616121712.C94645C1BA@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 14:17:12 2004 New Revision: 5102 Modified: pypy/trunk/src/pypy/objspace/std/intobject.py pypy/trunk/src/pypy/objspace/std/longtype.py pypy/trunk/src/pypy/objspace/std/multimethod.py pypy/trunk/src/pypy/objspace/std/test/test_intobject.py Log: - 'int/int' gives a float if true division - added a hack to include the long.__xyz__ methods within the int.__xyz__ methods, so that ints are automatically coerced into longs in case of overflow - added an overflow-gives-long test 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 Wed Jun 16 14:17:12 2004 @@ -166,9 +166,19 @@ return W_IntObject(space, z) def _truediv(space, w_int1, w_int2): - # cannot implement, since it gives floats - raise FailedToImplement(space.w_OverflowError, - space.wrap("integer division")) + x = w_int1.intval + y = w_int2.intval + try: + z = x // y + t = x % y + except ZeroDivisionError: + raise OperationError(space.w_ZeroDivisionError, + space.wrap("integer division by zero")) + except OverflowError: + return space.div(space.newfloat(x), w_int2) + if t != 0: # gives a float + return space.div(space.newfloat(x), w_int2) + return W_IntObject(space, z) def mod__Int_Int(space, w_int1, w_int2): x = w_int1.intval 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 Wed Jun 16 14:17:12 2004 @@ -1,4 +1,5 @@ from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.inttype import int_typedef def descr__new__(space, w_longtype, w_value=None): from pypy.objspace.std.longobject import W_LongObject @@ -31,3 +32,6 @@ long_typedef = StdTypeDef("long", __new__ = newmethod(descr__new__), ) +# hack to allow automatic int to long conversion: the int.__xyz__ methods +# will fall back to their long.__xyz__ counterparts if they fail +long_typedef.could_also_match = int_typedef 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 Wed Jun 16 14:17:12 2004 @@ -365,7 +365,8 @@ # Only accept an exact match; having merely subclass should # be taken care of by the general look-up rules. t = types[self.bound_position].typedef - return t is self.typeclass + return t is self.typeclass or ( + getattr(t, 'could_also_match', None) is self.typeclass) def __get__(self, space, cls=None): if space is None: 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 Jun 16 14:17:12 2004 @@ -316,5 +316,10 @@ assert (1 << 0) == 1 assert (1 >> 0) == 1 + def test_overflow(self): + import sys + n = sys.maxint + 1 + self.assert_(isinstance(n, long)) + if __name__ == '__main__': testit.main() From arigo at codespeak.net Wed Jun 16 14:57:05 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 14:57:05 +0200 (MEST) Subject: [pypy-svn] r5104 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040616125705.21B725C1BC@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 14:57:04 2004 New Revision: 5104 Modified: pypy/trunk/src/pypy/objspace/std/longobject.py pypy/trunk/src/pypy/objspace/std/multimethod.py Log: Darker and darker hacks to multimethod.py to cope with int-to-long coercion rules. At some point we need to rethink all this. 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 Wed Jun 16 14:57:04 2004 @@ -30,10 +30,13 @@ if -sys.maxint-1 <= w_longobj.longval <= sys.maxint: return W_IntObject(space, int(w_longobj.longval)) else: - raise OperationError(space.w_OverflowError, - space.wrap("long too large to convert to int")) + # note the 'return' here -- hack + return FailedToImplement( + OperationError(space.w_OverflowError, + space.wrap("long too large to convert to int"))) delegate__Long.result_class = W_IntObject delegate__Long.priority = PRIORITY_CHANGE_TYPE +delegate__Long.can_fail = True def long__Long(space, w_value): 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 Wed Jun 16 14:57:04 2004 @@ -84,28 +84,45 @@ # t.__name__ for t in argclasses] arglist = ['a%d'%i for i in range(len(argclasses))] + ['*extraargs'] source = ['def do(space,%s):' % ','.join(arglist)] - converted = [{(): 'a%d'%i} for i in range(len(argclasses))] + converted = [{(): ('a%d'%i, False)} for i in range(len(argclasses))] def make_conversion(argi, convlist): if tuple(convlist) in converted[argi]: return converted[argi][tuple(convlist)] else: - prev = make_conversion(argi, convlist[:-1]) + prev, can_fail = make_conversion(argi, convlist[:-1]) new = '%s_%d' % (prev, len(converted[argi])) fname = all_functions.setdefault(convlist[-1], 'd%d' % len(all_functions)) - source.append(' %s = %s(space,%s)' % (new, fname, prev)) - converted[argi][tuple(convlist)] = new - return new + if can_fail: + source.append(' if isinstance(%s, FailedToImplement):' % prev) + source.append(' %s = %s' % (new, prev)) + source.append(' else:') + indent = ' ' + else: + indent = ' ' + source.append('%s%s = %s(space,%s)' % (indent, new, fname, prev)) + can_fail = can_fail or getattr(convlist[-1], 'can_fail', False) + converted[argi][tuple(convlist)] = new, can_fail + return new, can_fail all_functions = {} has_firstfailure = False for fn, conversions in calllist: # make the required conversions fname = all_functions.setdefault(fn, 'f%d' % len(all_functions)) - arglist = [make_conversion(i, conversions[i]) - for i in range(len(argclasses))] + ['*extraargs'] + arglist = [] + failcheck = [] + for i in range(len(argclasses)): + argname, can_fail = make_conversion(i, conversions[i]) + arglist.append(argname) + if can_fail: + failcheck.append(argname) + arglist.append('*extraargs') source.append( ' try:') + for argname in failcheck: + source.append(' if isinstance(%s, FailedToImplement):' % argname) + source.append(' raise %s' % argname) source.append( ' return %s(space,%s)' % ( fname, ','.join(arglist))) if has_firstfailure: From lac at codespeak.net Wed Jun 16 15:29:25 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 16 Jun 2004 15:29:25 +0200 (MEST) Subject: [pypy-svn] r5111 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040616132925.12A485BDAB@thoth.codespeak.net> Author: lac Date: Wed Jun 16 15:29:24 2004 New Revision: 5111 Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py Log: had another idea, it's getting shorter. intermediate checkin in case I make a mess later. Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/testconverter.py (original) +++ pypy/branch/src-new-utest/pypy/tool/testconverter.py Wed Jun 16 15:29:24 2004 @@ -7,34 +7,31 @@ leading_spaces = re.compile(r'^(\s*)') -def process_block(s, interesting, indentation, old, new): - if not interesting: - return s - else: - body = s.replace(old, '', 1).lstrip() +def process_block(s, old, new): + body = s.replace(old, '', 1).lstrip() - if body.rstrip() == '(,)': # catch this special case early. - print 'malformed block %s cannot be converted' % s.rstrip() - return s + if body.rstrip() == '(,)': # catch this special case early. + print 'malformed block %s cannot be converted' % s.rstrip() + return s - plist = pos_finder(body, ',') - if plist == []: - print "Could not find a ',' in %s" % body + plist = pos_finder(body, ',') + if plist == []: + print "Could not find a ',' in %s" % body + return s + else: + arglist = [] + for p in plist: + left, right = body[:p], body[p+1:] + arglist.append((left, right)) + + r = find_comma(arglist) + + if r is None: + print 'malformed block %s cannot be converted' % s return s else: - arglist = [] - for p in plist: - left, right = body[:p], body[p+1:] - arglist.append((left, right)) - r = find_comma(arglist) - - if r is None: - print 'malformed block %s cannot be converted' % s - return s - else: - return indentation + new + r[0] + ') == (' + r[1] + return new + r[0] + ') == (' + r[1] - def find_comma(tuplelist): import parser @@ -65,15 +62,13 @@ fp = file(filename, 'r') blockstring = '' filestring = '' - current_indent = 0 was_interesting = False - n_l_s = '' + indentation = '' for line in fp: ls = leading_spaces.search(line) # this will never fail l_spaces = ls.group(1) - new_indent = len(l_spaces) interesting = old_function.search(line) @@ -82,39 +77,42 @@ # finish up your business with your last block, and # reset everything - filestring += process_block(blockstring, was_interesting, - n_l_s, old_fname, new_fname) + if was_interesting: + filestring += indentation + process_block(blockstring, + old_fname, new_fname) + else: + filestring += line blockstring = line # reset the block - current_indent = new_indent - n_l_s = ls.group(1) + indentation = ls.group(1) was_interesting = True elif not was_interesting and not interesting : - # the last line was not interesting and this one isn't either - # just add it to the block + # the last line was not interesting and this one isn't either. + # just copy it out. - blockstring += line + filestring += line else: # the slightly-hard case: # is this line a continuation of the current interesting block? # or is it just another uninteresting line that follows it? - if new_indent > current_indent: # continuation - blockstring += line - - # XXXX FIXME: check for comments? line continuations with \? - # Will we ever need it? + try: + compile(blockstring.lstrip(), '', 'exec') + # We were done. This is a boring old follower - else: # boring follower - filestring += process_block(blockstring, was_interesting, - n_l_s, old_fname, new_fname) + filestring += indentation + process_block(blockstring, old_fname, new_fname) blockstring = line was_interesting = False - - filestring += process_block(blockstring, was_interesting, n_l_s, - old_fname, new_fname) + + except SyntaxError: # we haven't got enough yet. + blockstring += line + + if was_interesting : + filestring += indentation + process_block(blockstring, old_fname, new_fname) + else: + filestring += line print filestring From arigo at codespeak.net Wed Jun 16 16:56:40 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 16:56:40 +0200 (MEST) Subject: [pypy-svn] r5117 - in pypy/trunk/src/pypy: interpreter/test objspace/std Message-ID: <20040616145640.115165BE74@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 16:56:39 2004 New Revision: 5117 Modified: pypy/trunk/src/pypy/interpreter/test/test_class.py pypy/trunk/src/pypy/objspace/std/intobject.py Log: int(x) should not return the object x if it is of a subclass of int. Added a test and fixed. 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 Jun 16 16:56:39 2004 @@ -86,5 +86,14 @@ self.assert_(isinstance(object.__new__(A), A)) self.assert_(isinstance(A.__new__(A), A)) + def test_int_subclass(self): + class R(int): + pass + x = R(5) + self.assertEquals(type(x), R) + self.assertEquals(x, 5) + self.assertEquals(type(int(x)), int) + self.assertEquals(int(x), 5) + if __name__ == '__main__': testit.main() 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 Wed Jun 16 16:56:39 2004 @@ -287,10 +287,7 @@ # a derived integer object, where it should return # an exact one. def pos__Int(space, w_int1): - if space.is_true(space.is_(space.type(w_int1), space.w_int)): - return w_int1 - a = w_int1.intval - return W_IntObject(space, a) + return int__Int(space, w_int1) def abs__Int(space, w_int1): if w_int1.intval >= 0: @@ -313,7 +310,7 @@ raise OperationError(space.w_ValueError, space.wrap("negative shift count")) if a == 0 or b == 0: - return pos__Int(space, w_int1) + return int__Int(space, w_int1) if b >= LONG_BIT: raise FailedToImplement(space.w_OverflowError, space.wrap("integer left shift")) @@ -343,7 +340,7 @@ raise OperationError(space.w_ValueError, space.wrap("negative shift count")) if a == 0 or b == 0: - return pos__Int(space, w_int1) + return int__Int(space, w_int1) if b >= LONG_BIT: if a < 0: a = -1 @@ -386,8 +383,14 @@ ## return 1; /* Can't do it */ ##} +# int__Int is supposed to do nothing, unless it has +# a derived integer object, where it should return +# an exact one. def int__Int(space, w_int1): - return w_int1 + if space.is_true(space.is_(space.type(w_int1), space.w_int)): + return w_int1 + a = w_int1.intval + return W_IntObject(space, a) """ # Not registered From arigo at codespeak.net Wed Jun 16 17:28:43 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 17:28:43 +0200 (MEST) Subject: [pypy-svn] r5119 - in pypy/trunk/src/pypy: interpreter/test objspace/std Message-ID: <20040616152843.C5A975C1C1@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 17:28:43 2004 New Revision: 5119 Modified: pypy/trunk/src/pypy/interpreter/test/test_class.py pypy/trunk/src/pypy/objspace/std/floatobject.py pypy/trunk/src/pypy/objspace/std/intobject.py pypy/trunk/src/pypy/objspace/std/longobject.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: + fixed signature of space.newfloat() + long and float subclasses had the same problem as int subclasses + added missing long.__eq__() 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 Jun 16 17:28:43 2004 @@ -95,5 +95,23 @@ self.assertEquals(type(int(x)), int) self.assertEquals(int(x), 5) + def test_long_subclass(self): + class R(long): + pass + x = R(5L) + self.assertEquals(type(x), R) + self.assertEquals(x, 5L) + self.assertEquals(type(long(x)), long) + self.assertEquals(long(x), 5L) + + def test_float_subclass(self): + class R(float): + pass + x = R(5.5) + self.assertEquals(type(x), R) + self.assertEquals(x, 5.5) + self.assertEquals(type(float(x)), float) + self.assertEquals(float(x), 5.5) + if __name__ == '__main__': testit.main() 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 Wed Jun 16 17:28:43 2004 @@ -30,8 +30,14 @@ delegate__Int.priority = PRIORITY_CHANGE_TYPE -def float__Float(space, w_value): - return w_value +# float__Float is supposed to do nothing, unless it has +# a derived float object, where it should return +# an exact one. +def float__Float(space, w_float1): + if space.is_true(space.is_(space.type(w_float1), space.w_float)): + return w_float1 + a = w_float1.floatval + return W_FloatObject(space, a) def int__Float(space, w_value): return space.newint(int(w_value.floatval)) @@ -231,10 +237,7 @@ return W_FloatObject(space, -w_float1.floatval) def pos__Float(space, w_float): - if w_float.__class__ == W_FloatObject: - return w_float - else: - return W_FloatObject(space, w_float.floatval) + return float__Float(space, w_float) def abs__Float(space, w_float): return W_FloatObject(space, abs(w_float.floatval)) 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 Wed Jun 16 17:28:43 2004 @@ -175,9 +175,9 @@ raise OperationError(space.w_ZeroDivisionError, space.wrap("integer division by zero")) except OverflowError: - return space.div(space.newfloat(x), w_int2) + return space.div(space.newfloat(float(x)), w_int2) if t != 0: # gives a float - return space.div(space.newfloat(x), w_int2) + return space.div(space.newfloat(float(x)), w_int2) return W_IntObject(space, z) def mod__Int_Int(space, w_int1, w_int2): 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 Wed Jun 16 17:28:43 2004 @@ -39,8 +39,14 @@ delegate__Long.can_fail = True -def long__Long(space, w_value): - return w_value +# long__Long is supposed to do nothing, unless it has +# a derived long object, where it should return +# an exact one. +def long__Long(space, w_long1): + if space.is_true(space.is_(space.type(w_long1), space.w_long)): + return w_long1 + a = w_long1.longval + return W_LongObject(space, a) def long__Int(space, w_intobj): return W_LongObject(space, long(w_intobj.intval)) @@ -66,6 +72,11 @@ def str__Long(space, w_long): return space.wrap(str(w_long.longval)) +def eq__Long_Long(space, w_long1, w_long2): + i = w_long1.longval + j = w_long2.longval + return space.newbool( i == j ) + def lt__Long_Long(space, w_long1, w_long2): i = w_long1.longval j = w_long2.longval @@ -148,10 +159,7 @@ return W_LongObject(space, -w_long1.longval) def pos__Long(space, w_long): - if space.is_true(space.is_(space.type(w_long), space.w_long)): - return w_long - else: - return W_LongObject(space, w_long.longval) + return long__Long(space, w_long) def abs__Long(space, w_long): return W_LongObject(space, abs(w_long.longval)) 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 Jun 16 17:28:43 2004 @@ -259,11 +259,11 @@ #raise TypeError, "cannot wrap classes" return W_CPythonObject(self, x) - def newint(self, int_w): - return W_IntObject(self, int_w) + def newint(self, intval): + return W_IntObject(self, intval) - def newfloat(self, int_w): - return W_FloatObject(self, int_w) + def newfloat(self, floatval): + return W_FloatObject(self, floatval) def newtuple(self, list_w): assert isinstance(list_w, list) From arigo at codespeak.net Wed Jun 16 17:38:23 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 17:38:23 +0200 (MEST) Subject: [pypy-svn] r5120 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040616153823.BFF715C1C2@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 17:38:23 2004 New Revision: 5120 Modified: pypy/trunk/src/pypy/objspace/std/floattype.py Log: Missing import. Modified: pypy/trunk/src/pypy/objspace/std/floattype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/floattype.py (original) +++ pypy/trunk/src/pypy/objspace/std/floattype.py Wed Jun 16 17:38:23 2004 @@ -1,4 +1,5 @@ from pypy.objspace.std.stdtypedef import * +from pypy.interpreter.error import OperationError def descr__new__(space, w_floattype, w_value=None): from pypy.objspace.std.floatobject import W_FloatObject From arigo at codespeak.net Wed Jun 16 17:45:19 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 17:45:19 +0200 (MEST) Subject: [pypy-svn] r5121 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040616154519.4EB755C1C3@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 17:45:18 2004 New Revision: 5121 Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py Log: Added 'int * str'. 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 Jun 16 17:45:18 2004 @@ -902,6 +902,9 @@ return space.wrap("".join(buffer)) +def mul__Int_String(space, w_mul, w_str): + return mul__String_Int(space, w_str, w_mul) + def add__String_String(space, w_left, w_right): u = space.unwrap right = u(w_right) From arigo at codespeak.net Wed Jun 16 18:07:57 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 18:07:57 +0200 (MEST) Subject: [pypy-svn] r5123 - in pypy/trunk/src/pypy: appspace objspace/std Message-ID: <20040616160757.86D6E5C1C4@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 18:07:56 2004 New Revision: 5123 Modified: pypy/trunk/src/pypy/appspace/builtin_types_test.py pypy/trunk/src/pypy/objspace/std/listobject.py pypy/trunk/src/pypy/objspace/std/longobject.py Log: - Bug fix in longobject.py - lst.index(x, long, long) support in listobject.py - re-enabled most tests in builtin_types_test.py, as they pass successfully now Modified: pypy/trunk/src/pypy/appspace/builtin_types_test.py ============================================================================== --- pypy/trunk/src/pypy/appspace/builtin_types_test.py (original) +++ pypy/trunk/src/pypy/appspace/builtin_types_test.py Wed Jun 16 18:07:56 2004 @@ -210,9 +210,7 @@ vereq(a[3::-2], '31') vereq(a[-100:100:], a) vereq(a[100:-100:-1], a[::-1]) -''' TODO Reenable when longs work better XXX vereq(a[-100L:100L:2L], '02468') -''' if have_unicode: a = unicode('0123456789', 'ascii') @@ -267,10 +265,12 @@ vereq(list(tuple(f())), range(1000)) # Verify that __getitem__ overrides are not recognized by __iter__ -class T(tuple): - def __getitem__(self, key): - return str(key) + '!!!' -vereq(iter(T((1,2))).next(), 1) +# XXX TODO: this fails with PyPy because overriding __getitem__ will +# really override what the sequence iterator returns +#class T(tuple): +# def __getitem__(self, key): +# return str(key) + '!!!' +#vereq(iter(T((1,2))).next(), 1) print '6.5.3 Lists' # calling built-in types without argument must return empty @@ -328,18 +328,17 @@ print '6.5.3a Additional list operations' a = [0,1,2,3,4] -''' TODO: Fix long indices XXX ''' -#a[0L] = 1 -#a[1L] = 2 -#a[2L] = 3 -#if a != [1,2,3,3,4]: raise TestFailed, 'list item assignment [0L], [1L], [2L]' +a[0L] = 1 +a[1L] = 2 +a[2L] = 3 +if a != [1,2,3,3,4]: raise TestFailed, 'list item assignment [0L], [1L], [2L]' a[0] = 5 a[1] = 6 a[2] = 7 if a != [5,6,7,3,4]: raise TestFailed, 'list item assignment [0], [1], [2]' -#a[-2L] = 88 -#a[-1L] = 99 -#if a != [5,6,7,88,99]: raise TestFailed, 'list item assignment [-2L], [-1L]' +a[-2L] = 88 +a[-1L] = 99 +if a != [5,6,7,88,99]: raise TestFailed, 'list item assignment [-2L], [-1L]' a[-2] = 8 a[-1] = 9 if a != [5,6,7,8,9]: raise TestFailed, 'list item assignment [-2], [-1]' @@ -347,21 +346,21 @@ a[-3:] = [] a[1:1] = [1,2,3] if a != [0,1,2,3,4]: raise TestFailed, 'list slice assignment' -#a[ 1L : 4L] = [7,8,9] -#if a != [0,7,8,9,4]: raise TestFailed, 'list slice assignment using long ints' +a[ 1L : 4L] = [7,8,9] +if a != [0,7,8,9,4]: raise TestFailed, 'list slice assignment using long ints' del a[1:4] if a != [0,4]: raise TestFailed, 'list slice deletion' del a[0] if a != [4]: raise TestFailed, 'list item deletion [0]' del a[-1] if a != []: raise TestFailed, 'list item deletion [-1]' -#a=range(0,5) -#del a[1L:4L] -#if a != [0,4]: raise TestFailed, 'list slice deletion' -#del a[0L] -#if a != [4]: raise TestFailed, 'list item deletion [0]' -#del a[-1L] -#if a != []: raise TestFailed, 'list item deletion [-1]' +a=range(0,5) +del a[1L:4L] +if a != [0,4]: raise TestFailed, 'list slice deletion' +del a[0L] +if a != [4]: raise TestFailed, 'list item deletion [0]' +del a[-1L] +if a != []: raise TestFailed, 'list item deletion [-1]' a=[] a.append(0) a.append(1) @@ -386,7 +385,6 @@ if a.index(0,-3) != 3: raise TestFailed, 'list index, -start argument' if a.index(0,3,4) != 3: raise TestFailed, 'list index, stop argument' if a.index(0,-3,-2) != 3: raise TestFailed, 'list index, -stop argument' -''' TODO: Fix long indices XXX if a.index(0,-4*sys.maxint,4*sys.maxint) != 2: raise TestFailed, 'list index, -maxint, maxint argument' try: @@ -395,7 +393,6 @@ pass else: raise TestFailed, 'list index, maxint,-maxint argument' -''' try: a.index(2,0,-10) @@ -498,10 +495,11 @@ vereq(a, [0, 1, 1, 3, 2, 5, 3, 7, 4, 9]) # Verify that __getitem__ overrides are not recognized by __iter__ -class L(list): - def __getitem__(self, key): - return str(key) + '!!!' -vereq(iter(L([1,2])).next(), 1) +# XXX TODO same as class T(tuple) above +#class L(list): +# def __getitem__(self, key): +# return str(key) + '!!!' +#vereq(iter(L([1,2])).next(), 1) print '6.6 Mappings == Dictionaries' @@ -608,7 +606,6 @@ except ValueError: pass else: raise TestFailed, 'dict.update(), __getitem__ expected ValueError' print '6.6.3 dict.fromkeys' -''' TODO: Need classmethods for built-in types # dict.fromkeys() if dict.fromkeys('abc') != {'a':None, 'b':None, 'c':None}: raise TestFailed, 'dict.fromkeys did not work as a class method' @@ -645,7 +642,6 @@ ud = mydict.fromkeys('ab') if ud != {'a':None, 'b':None} or not isinstance(ud,UserDict): raise TestFailed, 'fromkeys did not instantiate using __new__' -''' print '6.6.4 dict copy, get, setdefault' @@ -788,4 +784,4 @@ except TypeError: pass else: raise TestFailed, "buffer slice assignment should raise TypeError" ''' -print '6.99999999... All tests ran to completion' \ No newline at end of file +print '6.99999999... All tests ran to completion' Modified: pypy/trunk/src/pypy/objspace/std/listobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/listobject.py Wed Jun 16 18:07:56 2004 @@ -402,15 +402,15 @@ raise OperationError(space.w_ValueError, space.wrap("list.remove(x): x not in list")) -def list_index__List_ANY_Int_Int(space, w_list, w_any, w_start, w_stop): +def list_index__List_ANY_ANY_ANY(space, w_list, w_any, w_start, w_stop): eq = space.eq items = w_list.ob_item size = w_list.ob_size - start = space.unwrap(w_start) + start = space.unwrap(w_start) # XXX type check: int or clamped long if start < 0: start += size start = min(max(0,start),size) - stop = space.unwrap(w_stop) + stop = space.unwrap(w_stop) # XXX type check: int or clamped long if stop < 0: stop += size stop = min(max(start,stop),size) 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 Wed Jun 16 18:07:56 2004 @@ -31,9 +31,8 @@ return W_IntObject(space, int(w_longobj.longval)) else: # note the 'return' here -- hack - return FailedToImplement( - OperationError(space.w_OverflowError, - space.wrap("long too large to convert to int"))) + return FailedToImplement(space.w_OverflowError, + space.wrap("long int too large to convert to int")) delegate__Long.result_class = W_IntObject delegate__Long.priority = PRIORITY_CHANGE_TYPE delegate__Long.can_fail = True From arigo at codespeak.net Wed Jun 16 18:16:54 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 18:16:54 +0200 (MEST) Subject: [pypy-svn] r5124 - pypy/trunk/src/pypy/interpreter Message-ID: <20040616161654.2FC7D5C1C5@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 18:16:53 2004 New Revision: 5124 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py Log: Added CPython's strange 'print >> None' exception. Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Wed Jun 16 18:16:53 2004 @@ -824,6 +824,8 @@ raise RuntimeError("lost sys.stdout") def app_print_item_to(x, stream): + if stream is None: + return if file_softspace(stream, False): stream.write(" ") stream.write(str(x)) @@ -835,6 +837,8 @@ file_softspace(stream, True) def app_print_newline_to(stream): + if stream is None: + return stream.write("\n") file_softspace(stream, False) From arigo at codespeak.net Wed Jun 16 18:19:23 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 18:19:23 +0200 (MEST) Subject: [pypy-svn] r5125 - pypy/trunk/src/pypy/module Message-ID: <20040616161923.E5FD25C1C6@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 18:19:23 2004 New Revision: 5125 Modified: pypy/trunk/src/pypy/module/__builtin__module.py Log: basestring = str until we have unicode. 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 Jun 16 18:19:23 2004 @@ -10,6 +10,7 @@ __builtins__['__debug__'] = True object = __interplevel__eval('space.w_object') +basestring = str # XXX until we have unicode # TODO Fix this later to show Ctrl-D on Unix From lac at codespeak.net Wed Jun 16 18:43:24 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 16 Jun 2004 18:43:24 +0200 (MEST) Subject: [pypy-svn] r5126 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040616164324.6DDC55C1C7@thoth.codespeak.net> Author: lac Date: Wed Jun 16 18:43:23 2004 New Revision: 5126 Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py Log: Much smaller now. But I am not done yet with shrinking this ... Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/testconverter.py (original) +++ pypy/branch/src-new-utest/pypy/tool/testconverter.py Wed Jun 16 18:43:23 2004 @@ -24,13 +24,26 @@ left, right = body[:p], body[p+1:] arglist.append((left, right)) - r = find_comma(arglist) + try: + r = find_comma(arglist) + left, right = find_comma(arglist) + + if right.rstrip()[-1] != ')': + # if the last printing char of the string is not ')', + # keep the parens for now. + return new + left + ') == (' + right + else: # see if we can drop one set of parens + #stripped = right.rstrip()[0:-1] + l = new + ' ' + left[1:] + ' == ' + right.rstrip()[0:-1] + '\n' + try: + compile(l, '', 'exec') + return l + except SyntaxError: # too bad, needed them + return new + left + ') == (' + right - if r is None: - print 'malformed block %s cannot be converted' % s + except SyntaxError: + print 'malformed block %s cannot be converted' % s.rstrip() return s - else: - return new + r[0] + ') == (' + r[1] def find_comma(tuplelist): import parser @@ -40,14 +53,13 @@ for l, r in tuplelist: try: - left = l + ')' - right = '(' + r - parser.expr(left) - parser.expr(right) - return l , r # Great! Both sides are expressions! + + parser.expr(l + ')') + parser.expr('(' + r) + return l , r # Great! Both sides are expressions! except SyntaxError: # It wasn't that comma pass - return None + raise SyntaxError # We never found anything that worked. def pos_finder(s, char=','): # returns the list of string positions where the char 'char' was found @@ -63,7 +75,7 @@ blockstring = '' filestring = '' was_interesting = False - indentation = '' + indent = '' for line in fp: @@ -74,23 +86,19 @@ if interesting : # we have found the beginning of a new interesting block. - # finish up your business with your last block, and - # reset everything + # finish up your business with your last block, if + # necessary and reset everything if was_interesting: - filestring += indentation + process_block(blockstring, - old_fname, new_fname) - else: - filestring += line - + filestring += indent + process_block(blockstring, + old_fname, new_fname) blockstring = line # reset the block - indentation = ls.group(1) + indent = ls.group(1) was_interesting = True elif not was_interesting and not interesting : # the last line was not interesting and this one isn't either. # just copy it out. - filestring += line else: @@ -101,18 +109,17 @@ try: compile(blockstring.lstrip(), '', 'exec') # We were done. This is a boring old follower - - filestring += indentation + process_block(blockstring, old_fname, new_fname) - blockstring = line + + filestring += indent + process_block(blockstring, old_fname, new_fname) + filestring += line + #blockstring = '' was_interesting = False except SyntaxError: # we haven't got enough yet. blockstring += line if was_interesting : - filestring += indentation + process_block(blockstring, old_fname, new_fname) - else: - filestring += line + filestring += indent + process_block(blockstring, old_fname, new_fname) print filestring From arigo at codespeak.net Wed Jun 16 19:20:24 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 19:20:24 +0200 (MEST) Subject: [pypy-svn] r5129 - pypy/trunk/src/pypy/interpreter Message-ID: <20040616172024.DF0EB5C1C8@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 19:20:14 2004 New Revision: 5129 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/error.py pypy/trunk/src/pypy/interpreter/pyopcode.py Log: Try to allow raising any object as an exception. The syntax 'raise x' is largely ambiguous, though. There are some sanity checks. The syntax 'raise type,x' is not ambiguous, so I guess it should be preferred. Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Wed Jun 16 19:20:14 2004 @@ -166,7 +166,12 @@ except OperationError: # Assume that this is a TypeError: w_item not a type, # and assume that w_item is then actually a tuple. - exclst = self.unpackiterable(w_item) + try: + exclst = self.unpackiterable(w_item) + except OperationError: + # hum, maybe it is not a tuple after all, and w_exc_type + # was not a type at all (string exceptions). Give up. + continue check_list.extend(exclst) return False Modified: pypy/trunk/src/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/error.py (original) +++ pypy/trunk/src/pypy/interpreter/error.py Wed Jun 16 19:20:14 2004 @@ -104,11 +104,17 @@ exc_value = self.w_value else: w = space.wrap - exc_typename = space.unwrap( - space.getattr(self.w_type, w('__name__'))) - exc_value = space.unwrap(space.str(self.w_value)) + if space.is_true(space.is_(space.type(self.w_type), space.w_str)): + exc_typename = space.unwrap(self.w_type) + else: + exc_typename = space.unwrap( + space.getattr(self.w_type, w('__name__'))) + if self.w_value == space.w_None: + exc_value = None + else: + exc_value = space.unwrap(space.str(self.w_value)) print >> file, '(application-level)', - if exc_value is None: + if not exc_value: print >> file, exc_typename else: print >> file, exc_typename+':', exc_value Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Wed Jun 16 19:20:14 2004 @@ -853,29 +853,37 @@ # which is not the case in CPython, but well import sys etype, value, traceback = sys.exc_info() + #XXX re-enable the following check #if not isinstance(traceback, (types.NoneType, types.TracebackType)): # raise TypeError, "raise: arg 3 must be traceback or None" while isinstance(etype, tuple): etype = etype[0] - if type(etype) is str: - # XXX warn - pass - elif isinstance(etype, Exception): + if isinstance(etype, type): + if isinstance(value, etype): + # raise Type, Instance: everything is fine + pass + elif value is None: + # raise Type: we assume we have to instantiate Type + value = etype() + else: + # raise Type, X: assume X is the constructor argument + value = etype(value) + elif type(etype) is str: + # XXX warn -- deprecated + if value is not None and type(value) is not str: + raise TypeError("string exceptions can only have a string value") + else: + # raise X: we assume that X is an already-built instance if value is not None: raise TypeError("instance exception may not have a separate value") value = etype etype = value.__class__ - elif isinstance(etype, type) and issubclass(etype, Exception): - if not isinstance(value,etype): - if value is None: - value = () - elif not isinstance(value, tuple): - value = (value,) - value = etype(*value) - else: - raise TypeError("exceptions must be instances or subclasses of " - "Exception or strings (deprecated), not %s" % - (type(etype).__name__,)) + # for the sake of language consistency we should not allow + # things like 'raise 1', but it's probably fine (i.e. + # not ambiguous) to allow them in the explicit form 'raise int, 1' + if not hasattr(value, '__dict__') and not hasattr(value, '__slots__'): + raise TypeError("raising built-in objects can be ambiguous, " + "use 'raise type, value' instead") return etype, value, traceback def app_find_metaclass(bases, namespace, globals): From arigo at codespeak.net Wed Jun 16 19:32:38 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 19:32:38 +0200 (MEST) Subject: [pypy-svn] r5132 - in pypy/trunk/src/pypy: interpreter objspace/std Message-ID: <20040616173238.DD2175C1C9@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 19:32:37 2004 New Revision: 5132 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/std/typeobject.py Log: * raise Type, InstanceOfSubType was broken * object.__new__() now complains if given arguments unless object.__init__() is overridden, as per Python 2.3 behavior Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Wed Jun 16 19:32:37 2004 @@ -860,8 +860,8 @@ etype = etype[0] if isinstance(etype, type): if isinstance(value, etype): - # raise Type, Instance: everything is fine - pass + # raise Type, Instance: let etype be the exact type of value + etype = value.__class__ elif value is None: # raise Type: we assume we have to instantiate Type value = etype() Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Wed Jun 16 19:32:37 2004 @@ -22,14 +22,19 @@ return space.type(w_obj) def descr__new__(space, w_type, *args_w, **kwds_w): - # XXX 2.2 behavior: ignoring all arguments from pypy.objspace.std.objectobject import W_ObjectObject + # don't allow arguments if the default object.__init__() is about + # to be called + w_parentinit, w_ignored = w_type.lookup_where('__init__') + if w_parentinit is space.w_object and (args_w or kwds_w): + raise OperationError(space.w_TypeError, + space.wrap("default __new__ takes no parameters")) w_obj = space.allocate_instance(W_ObjectObject, w_type) w_obj.__init__(space) return w_obj def descr__init__(space, *args_w, **kwds_w): - pass # XXX 2.2. behavior: ignoring all arguments + pass # ____________________________________________________________ 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 Wed Jun 16 19:32:37 2004 @@ -41,8 +41,6 @@ def lookup(w_self, key): # note that this doesn't call __get__ on the result at all - # XXX this should probably also return the (parent) class in which - # the attribute was found space = w_self.space for w_class in w_self.mro_w: try: @@ -51,6 +49,17 @@ pass return None + def lookup_where(w_self, key): + # like lookup() but also returns the parent class in which the + # attribute was found + space = w_self.space + for w_class in w_self.mro_w: + try: + return w_class, w_class.dict_w[key] + except KeyError: + pass + return None, None + def check_user_subclass(w_self, w_subtype): space = w_self.space if not space.is_true(space.isinstance(w_subtype, space.w_type)): @@ -94,8 +103,7 @@ # maybe invoke the __init__ of the type if space.is_true(space.isinstance(w_newobject, w_type)): w_descr = space.lookup(w_newobject, '__init__') - if w_descr is not None: - space.get_and_call(w_descr, w_newobject, w_args, w_kwds) + space.get_and_call(w_descr, w_newobject, w_args, w_kwds) return w_newobject def issubtype__Type_Type(space, w_type1, w_type2): From lac at codespeak.net Wed Jun 16 20:51:49 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 16 Jun 2004 20:51:49 +0200 (MEST) Subject: [pypy-svn] r5136 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040616185149.725C35C1CA@thoth.codespeak.net> Author: lac Date: Wed Jun 16 20:51:48 2004 New Revision: 5136 Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py Log: functionality works. Modified: pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/testconverter.py (original) +++ pypy/branch/src-new-utest/pypy/tool/testconverter.py Wed Jun 16 20:51:48 2004 @@ -1,51 +1,45 @@ import re import unittest -old_fname = 'self.assertEquals' -new_fname = 'assert' -old_function = re.compile(r'^(\s*)' + old_fname + r'\((.*)') +old= 'self.assertEquals' +new= 'assert' +old_function = re.compile(r'^(\s*)' + old + r'\((.*)') leading_spaces = re.compile(r'^(\s*)') -def process_block(s, old, new): +def convert(s, old, new): + + compile(s.lstrip(), '', 'exec') body = s.replace(old, '', 1).lstrip() - - if body.rstrip() == '(,)': # catch this special case early. - print 'malformed block %s cannot be converted' % s.rstrip() - return s - plist = pos_finder(body, ',') + if plist == []: - print "Could not find a ',' in %s" % body - return s + raise SyntaxError , "Could not find a ',' in %s" % body else: arglist = [] for p in plist: - left, right = body[:p], body[p+1:] - arglist.append((left, right)) + l, r = body[:p], body[p+1:] + arglist.append((l, r)) - try: - r = find_comma(arglist) - left, right = find_comma(arglist) + l, r = which_comma(arglist) - if right.rstrip()[-1] != ')': - # if the last printing char of the string is not ')', - # keep the parens for now. - return new + left + ') == (' + right - else: # see if we can drop one set of parens - #stripped = right.rstrip()[0:-1] - l = new + ' ' + left[1:] + ' == ' + right.rstrip()[0:-1] + '\n' - try: - compile(l, '', 'exec') - return l - except SyntaxError: # too bad, needed them - return new + left + ') == (' + right + if r.rstrip()[-1] != ')': + # if the last printing char of the string is not ')', + # keep the parens for now. This could be refined. + return new + l + ') == (' + r - except SyntaxError: - print 'malformed block %s cannot be converted' % s.rstrip() - return s + else: # see if we can drop one set of parens + + stripped = r.rstrip() + line_ends = r[len(stripped):] + block = new + ' ' + l[1:] + ' == ' + stripped[0:-1] + line_ends + try: + compile(block, '', 'exec') + return block + except SyntaxError: # too bad, needed them + return new + l + ') == (' + r -def find_comma(tuplelist): +def which_comma(tuplelist): import parser # make the python parser do the hard work of deciding which comma @@ -90,15 +84,19 @@ # necessary and reset everything if was_interesting: - filestring += indent + process_block(blockstring, - old_fname, new_fname) + try: + backstring = convert(blockstring, old, new) + filestring += indent + backstring + except SyntaxError: + filestring += blockstring # malformed, copy as written + blockstring = line # reset the block indent = ls.group(1) was_interesting = True elif not was_interesting and not interesting : # the last line was not interesting and this one isn't either. - # just copy it out. + filestring += line else: @@ -107,19 +105,21 @@ # or is it just another uninteresting line that follows it? try: - compile(blockstring.lstrip(), '', 'exec') + filestring += indent + convert(blockstring, old, new) # We were done. This is a boring old follower - - filestring += indent + process_block(blockstring, old_fname, new_fname) + filestring += line - #blockstring = '' was_interesting = False except SyntaxError: # we haven't got enough yet. blockstring += line if was_interesting : - filestring += indent + process_block(blockstring, old_fname, new_fname) + try: + filestring += indent + convert(blockstring, old, new) + except SyntaxError: + print 'last block %s was malformed' % blockstring.rstrip() + filestring += blockstring print filestring From arigo at codespeak.net Wed Jun 16 21:40:19 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 16 Jun 2004 21:40:19 +0200 (MEST) Subject: [pypy-svn] r5139 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040616194019.E26DA5C1CB@thoth.codespeak.net> Author: arigo Date: Wed Jun 16 21:40:19 2004 New Revision: 5139 Modified: pypy/trunk/src/pypy/objspace/std/intobject.py Log: Grumble. A minor fix: '%ld'%n isn't very RPython-ic and the 'l' isn't supported by PyPy itself now. Now I have to restart the whole PyPy-over-PyPy test -- takes 1-2 hours to start up :-) 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 Wed Jun 16 21:40:19 2004 @@ -45,7 +45,7 @@ def repr__Int(space, w_int1): a = w_int1.intval - res = "%ld" % a + res = str(a) return space.wrap(res) str__Int = repr__Int From hpk at codespeak.net Thu Jun 17 00:50:36 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 17 Jun 2004 00:50:36 +0200 (MEST) Subject: [pypy-svn] r5140 - pypy/trunk/src/pypy/interpreter Message-ID: <20040616225036.997525BDFD@thoth.codespeak.net> Author: hpk Date: Thu Jun 17 00:50:36 2004 New Revision: 5140 Modified: pypy/trunk/src/pypy/interpreter/py.py Log: small hack to raise the recursionlimit to make Armins posting to pypy-dev actually work :-) Modified: pypy/trunk/src/pypy/interpreter/py.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/py.py (original) +++ pypy/trunk/src/pypy/interpreter/py.py Thu Jun 17 00:50:36 2004 @@ -82,4 +82,7 @@ import readline except: pass + if hasattr(sys, 'setrecursionlimit'): + # for running "python -i py.py -Si -- py.py -Si" + sys.setrecursionlimit(3000) main_(sys.argv) From arigo at codespeak.net Thu Jun 17 11:00:05 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 17 Jun 2004 11:00:05 +0200 (MEST) Subject: [pypy-svn] r5141 - pypy/trunk/src/pypy/interpreter Message-ID: <20040617090005.81C525BDAB@thoth.codespeak.net> Author: arigo Date: Thu Jun 17 11:00:04 2004 New Revision: 5141 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py Log: print >> None actually means print >> sys.stdout. Thanks mwh. Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Thu Jun 17 11:00:04 2004 @@ -274,6 +274,8 @@ def PRINT_ITEM_TO(f): w_stream = f.valuestack.pop() w_item = f.valuestack.pop() + if w_stream == f.space.w_None: + w_stream = sys_stdout(f.space) # grumble grumble special cases print_item_to(f.space, w_item, w_stream) def PRINT_ITEM(f): @@ -282,6 +284,8 @@ def PRINT_NEWLINE_TO(f): w_stream = f.valuestack.pop() + if w_stream == f.space.w_None: + w_stream = sys_stdout(f.space) # grumble grumble special cases print_newline_to(f.space, w_stream) def PRINT_NEWLINE(f): @@ -824,8 +828,6 @@ raise RuntimeError("lost sys.stdout") def app_print_item_to(x, stream): - if stream is None: - return if file_softspace(stream, False): stream.write(" ") stream.write(str(x)) @@ -837,8 +839,6 @@ file_softspace(stream, True) def app_print_newline_to(stream): - if stream is None: - return stream.write("\n") file_softspace(stream, False) From arigo at codespeak.net Thu Jun 17 19:44:51 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 17 Jun 2004 19:44:51 +0200 (MEST) Subject: [pypy-svn] r5153 - in pypy/trunk/src: Pyrex/Compiler pypy/translator pypy/translator/test Message-ID: <20040617174451.704BC5BDAB@thoth.codespeak.net> Author: arigo Date: Thu Jun 17 19:44:50 2004 New Revision: 5153 Modified: pypy/trunk/src/Pyrex/Compiler/ExprNodes.py pypy/trunk/src/Pyrex/Compiler/Lexicon.pickle pypy/trunk/src/Pyrex/Compiler/Lexicon.py pypy/trunk/src/Pyrex/Compiler/Parsing.py pypy/trunk/src/pypy/translator/genpyrex.py pypy/trunk/src/pypy/translator/test/test_pyrextrans.py Log: Implemented in-place operators in Pyrex, but only the 'name += expr' syntax. For the more involved syntaxes like 'expr1[expr2] = expr3' we would have to precompute expr1 and expr2 and store them in temporary variables. Not sure how to do this. But 'v12 += v34' is probably all we need for PyPy. Fixed genpyrex.py to use this extension. Remember that in-place operators are actually binary operators returning a result: an in-place operator SpaceOperation() still has two args and a new result variable, and corresponds to the C API call 'result = PyNumber_InPlaceXxx(arg1, arg2)'. To emulate this, genpyrex.py now generates code like 'result = arg1; result += arg2'. Modified: pypy/trunk/src/Pyrex/Compiler/ExprNodes.py ============================================================================== --- pypy/trunk/src/Pyrex/Compiler/ExprNodes.py (original) +++ pypy/trunk/src/Pyrex/Compiler/ExprNodes.py Thu Jun 17 19:44:50 2004 @@ -2268,7 +2268,7 @@ def generate_result_code(self, code): if self.operand1.type.is_pyobject: function = self.py_operation_function() - if function == "PyNumber_Power": + if self.operator == "**": extra_args = ", Py_None" else: extra_args = "" @@ -2296,6 +2296,7 @@ class NumBinopNode(BinopNode): # Binary operation taking numeric arguments. + inplace = 0 def analyse_c_operation(self, env): type1 = self.operand1.type @@ -2320,7 +2321,10 @@ self.operand2.result) def py_operation_function(self): - return self.py_functions[self.operator] + function = self.py_functions[self.operator] + if self.inplace: + function = function.replace("PyNumber_", "PyNumber_InPlace") + return function py_functions = { "|": "PyNumber_Or", Modified: pypy/trunk/src/Pyrex/Compiler/Lexicon.pickle ============================================================================== Binary files. No diff available. Modified: pypy/trunk/src/Pyrex/Compiler/Lexicon.py ============================================================================== --- pypy/trunk/src/Pyrex/Compiler/Lexicon.py (original) +++ pypy/trunk/src/Pyrex/Compiler/Lexicon.py Thu Jun 17 19:44:50 2004 @@ -66,7 +66,9 @@ bra = Any("([{") ket = Any(")]}") punct = Any(":,;+-*/|&<>=.%`~^?") - diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**") + diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**", + "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", + "<<=", ">>=", "**=") spaces = Rep1(Any(" \t\f")) comment = Str("#") + Rep(AnyBut("\n")) escaped_newline = Str("\\\n") Modified: pypy/trunk/src/Pyrex/Compiler/Parsing.py ============================================================================== --- pypy/trunk/src/Pyrex/Compiler/Parsing.py (original) +++ pypy/trunk/src/Pyrex/Compiler/Parsing.py Thu Jun 17 19:44:50 2004 @@ -637,6 +637,23 @@ def p_expression_or_assignment(s): expr_list = [p_expr(s)] + if s.sy in augassign_ops: + n1 = expr_list[0] + op = s.sy[:-1] + pos = s.position() + s.next() + n2 = p_expr(s) + # Parse a limited form of augmented assignment: + # 'name += expr' --> 'name = name + y' + # with a specially marked binop node. + # Augmented assignment to more complex expressions isn't supported yet. + if isinstance(n1, ExprNodes.NameNode): + n1copy = ExprNodes.NameNode(n1.pos, name = n1.name) + else: + s.error("not implemented: augmented assignment to an expression more complex than a variable name") + binop = ExprNodes.binop_node(pos, op, n1, n2) + binop.inplace = 1 + return Nodes.SingleAssignmentNode(pos, lhs = n1copy, rhs = binop) while s.sy == '=': s.next() expr_list.append(p_expr(s)) @@ -663,6 +680,11 @@ #return Nodes.StatListNode(nodes[0].pos, stats = nodes) return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes) +augassign_ops = ( + '+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=', + '<<=', '>>=', '**=' +) + def flatten_parallel_assignments(input, output): # The input is a list of expression nodes, representing # the LHSs and RHS of one (possibly cascaded) assignment Modified: pypy/trunk/src/pypy/translator/genpyrex.py ============================================================================== --- pypy/trunk/src/pypy/translator/genpyrex.py (original) +++ pypy/trunk/src/pypy/translator/genpyrex.py Thu Jun 17 19:44:50 2004 @@ -26,12 +26,11 @@ return "%s = %s %s" % (self.resultname, operator) + args elif len(args) == 2: #Inplace operators - inp=['+=','-=','*=','/=','%=','^=','//=','div=','**=','<<=','>>=','!=','&='] + inp=['+=','-=','*=','/=','%=','&=','|=','^=','//=', + '<<=','>>=','**='] if operator in inp: - temp_str="temp_xx12=%s %s %s\n"%(args[0], operator[:-1], args[1]) - temp_str+="%s=temp_xx12\n"%args[0] - temp_str+="%s=temp_xx12"%self.resultname - return temp_str + return "%s = %s; %s %s %s" % (self.resultname, args[0], + self.resultname, operator, args[1]) else: return "%s = %s %s %s" % (self.resultname, args[0], operator, args[1]) elif len(args) == 3 and operator == "**": #special case, have to handle it manually Modified: pypy/trunk/src/pypy/translator/test/test_pyrextrans.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_pyrextrans.py (original) +++ pypy/trunk/src/pypy/translator/test/test_pyrextrans.py Thu Jun 17 19:44:50 2004 @@ -41,6 +41,10 @@ poor_man_range = self.build_cfunc(snippet.poor_man_range) self.assertEquals(poor_man_range(10), range(10)) + def poor_man_rev_range(self): + poor_man_rev_range = self.build_cfunc(snippet.poor_man_rev_range) + self.assertEquals(poor_man_rev_range(10), range(9,-1,-1)) + def test_simple_id(self): #we just want to see, if renaming of parameter works correctly #if the first branch is the end branch From arigo at codespeak.net Thu Jun 17 19:48:33 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 17 Jun 2004 19:48:33 +0200 (MEST) Subject: [pypy-svn] r5155 - in pypy/trunk/src: goal pypy/interpreter pypy/interpreter/test pypy/tool Message-ID: <20040617174833.B6D075BDAB@thoth.codespeak.net> Author: arigo Date: Thu Jun 17 19:48:33 2004 New Revision: 5155 Modified: pypy/trunk/src/goal/objectspace-reconstruct.py (props changed) pypy/trunk/src/pypy/interpreter/special.py (props changed) pypy/trunk/src/pypy/interpreter/test/test_special.py (props changed) pypy/trunk/src/pypy/tool/pypyutest.py (props changed) Log: fixeol. From lac at codespeak.net Fri Jun 18 22:31:42 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Fri, 18 Jun 2004 22:31:42 +0200 (MEST) Subject: [pypy-svn] r5166 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040618203142.8AE295C06B@thoth.codespeak.net> Author: lac Date: Fri Jun 18 22:31:41 2004 New Revision: 5166 Added: pypy/branch/src-new-utest/pypy/tool/tiny.py Log: I had better check this in before my laptop is struck by lightning and I lose all my work. It isn't that tiny any more, is it? Added: pypy/branch/src-new-utest/pypy/tool/tiny.py ============================================================================== --- (empty file) +++ pypy/branch/src-new-utest/pypy/tool/tiny.py Fri Jun 18 22:31:41 2004 @@ -0,0 +1,189 @@ +import re +import unittest + + +# 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 type'] is one of the following functions +# namechange_only e.g. assertRaises becomes raises +# 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. + +# First define the functions you want to dispatch + +def namechange_only(old, new, block): + # this is the simplest of changes. + return re.sub('self.'+old, new, block) + +def strip_parens(old, new, block): + return re.sub('self.'+old, new, block) + +d={} + +#def assertRaises(self, excClass, callableObj, *args, **kwargs) + +d['assertRaises'] = {'new': 'raises', + 'change type': namechange_only, + 'op': None} + +d['failUnlessRaises'] = d['assertRaises'] + +d['assert_'] = {'new': 'assert', + 'change type': strip_parens, + 'op': None} + +""" +d['failUnless'] = {'old':'failUnless', + 'new': 'assert', + 'change type': 'strip_parens', + 'op': None} + +d['failUnlessEqual'] = {'old': 'failUnlessEqual', + 'new': 'assert not', + 'change type': 'comma to op', + 'op': '!='} + +d['failIfEqual'] = {'old': 'failIfEqual', + 'new': 'assert not', + 'change type': 'comma to op', + 'op': '=='} + +d['assertEquals'] = {'old': 'assertEquals', + 'new': 'assert', + 'change type': 'comma to op', + 'op': '=='} + +d['assertNotEqual'] = {'old': 'assertNotEqual', + 'new': 'assert', + 'change type': 'comma to op', + 'op': '!='} + +d['assertNotAlmostEqual'] = {'old': 'assertNotAlmostEqual', + 'new': 'assert round', + 'change type': 'rounding', + 'op': '!='} + +d['assertNotAlmostEquals'] = {'old': 'assertNotAlmostEquals', + 'new': 'assert round', + 'change type': 'rounding', + 'op': '!='} + +d['failUnlessAlmostEqual'] = {'old': 'failUnlessAlmostEqual', + 'new': 'assert not round', + 'change type': 'rounding', + 'op': '=='} + +d['assertNotEquals'] = {'old': 'assertNotEquals', + 'new': 'assert', + 'change type': + 'comma to op', + 'op': '!='} + +d['failIf'] = {'old': 'failIf', + 'new': 'assert not', + 'change type': 'strip_parens', + 'op': None} + +d['fail'] = {'old': 'fail', + 'new': 'raise AssertionError ', + 'change type': 'strip_parens', + 'op': None} + +d['assertEqual'] = {'old': 'assertEqual', + 'new': 'assert', + 'change type': 'comma to op', + 'op': '=='} + +d['assertUnlessAlmostEquals'] = {'old': 'assertUnlessAlmostEquals', + 'new': 'assert round', + 'change type': 'rounding', + 'op': '=='} + +d['assertAlmostEqual'] = {'old': 'assertAlmostEqual', + 'new': 'assert round', + 'change type': 'rounding', + 'op': '=='} +""" +leading_spaces = re.compile(r'^(\s*)') + +pat = '' +for k in d.keys(): + pat += '|' + r'^(\s*)' + 'self.' + k + r'\(' # \tself.whatever( + +old_names = re.compile(pat[1:]) # strip the extra '|' from front + +def blocksplitter(filename): + + fp = file(filename, 'r') + blocklist = [] + blockstring = '' + + for line in fp: + + interesting = old_names.match(line) + + if interesting : + if blockstring: + blocklist.append(blockstring) + blockstring = line # reset the block + else: + blockstring += line + + blocklist.append(blockstring) + return blocklist + +def process_block(s): + #print 'found the block ', block + f = old_names.match(s) + if f: + key = f.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' + return d[key]['change type'](key, d[key]['new'], s) + else: + return s + +class Testit(unittest.TestCase): + def test(self): + self.assertEquals(process_block("badger badger badger"), + "badger badger badger") + + self.assertEquals(process_block( + "self.assertRaises(excClass, callableObj, *args, **kwargs)" + ), + "raises(excClass, callableObj, *args, **kwargs)" + ) + + self.assertEquals(process_block( + """ + self.assertRaises(TypeError, func, 42, {'arg1': 23}) + """ + ), + """ + raises(TypeError, func, 42, {'arg1': 23}) + """ + ) + self.assertEquals(process_block( + """ + self.assertRaises(TypeError, + func, + mushroom) + """ + ), + """ + raises(TypeError, + func, + mushroom) + """ + ) + self.assertEquals(process_block("self.assert_(x)"), + "assert x") + + + +if __name__ == '__main__': + unittest.main() + #for block in blocksplitter('xxx.py'): print process_block(block) + + From lac at codespeak.net Sat Jun 19 15:59:39 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 19 Jun 2004 15:59:39 +0200 (MEST) Subject: [pypy-svn] r5168 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040619135939.E950E5C06B@thoth.codespeak.net> Author: lac Date: Sat Jun 19 15:59:38 2004 New Revision: 5168 Modified: pypy/branch/src-new-utest/pypy/tool/tiny.py Log: Most of the special cases handled now. Still working on it. Modified: pypy/branch/src-new-utest/pypy/tool/tiny.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/tiny.py (original) +++ pypy/branch/src-new-utest/pypy/tool/tiny.py Sat Jun 19 15:59:38 2004 @@ -1,5 +1,6 @@ import re import unittest +import parser # d is the dictionary of unittest changes, keyed to the old name @@ -7,6 +8,7 @@ # d['change type'] is one of the following functions # namechange_only e.g. assertRaises becomes raises # strip_parens e.g. assert_(expr) becomes assert expr +# fail_special e.g. fail() becomes raise AssertionError # 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 @@ -15,11 +17,95 @@ # First define the functions you want to dispatch def namechange_only(old, new, block): + # dictionary dispatch function. # this is the simplest of changes. return re.sub('self.'+old, new, block) def strip_parens(old, new, block): + # dictionary dispatch function. + + pat = re.search(r'^(\s*)', block) + indent = pat.group() + pat = re.search('self.' + old + r'\(', block) + rest = block[pat.end():] + + expr, trailer = get_expr(rest, ')') + + try: + parser.expr(expr) # the parens came off easily + return indent + new + ' ' + expr + trailer + + except SyntaxError: + + # now we have to go to work. It would be nice if we could + # just keep the parens, since the original author probably + # used them to group things nicely in a complicated multi-line + # expression. + # + # There is one hitch. + # + # self.assertx_(0, string) prints the string, as does + # assert 0, string . But not only does assert(0, string) not + # print the string, it also doesn't print the AssertionError + # either. So nothing for it, we have to paste continuation + # backslashes on our multiline constructs. + + try: + realexpr, s = get_expr(expr, ',') + + # aha. we found an expr followed by a ', something_else' + # we should probably test to make sure that something_else + # is a string, and not, say, another expr. But the whole + # question of what to do when your input is bogus requires + # more thought than I want to do at this hour ... + # Given that assert 0, range(10) is legal, and prints + # AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], is it + # even true that s has to be a string? + + expr_w_slash = re.sub(r'\n', r'\\\n', realexpr) + + if s[0] == '\n': # that needs a slash too ... + return indent + new + ' ' + expr_w_slash + ',\\' + s + trailer + else: + return indent + new + ' ' + expr_w_slash + ',' + s + trailer + + except SyntaxError: + # we couldn't find a 'expr, string' so it is + # probably just a regular old multiline expression + # t.ex. self.assertx(0 + # +f(x) + # +g(x)) + + expr_w_slash = re.sub(r'\n', r'\\\n', expr) + return indent + new + ' ' + expr_w_slash + trailer + +def fail_special(old, new, block): + # dictionary dispatch function. + # while assert_() is an error, fail() and + # fail('message') are just fine. return re.sub('self.'+old, new, block) + + +def get_expr(s, char): + # read from the beginning of the string until you get an expression. + # return it, and the stuff left over, minus the char you separated on + pos = pos_finder(s, char) + + for p in pos: + try: + parser.expr('(' + s[:p] + ')') + return s[:p], s[p+1:] + except SyntaxError: # It's not an expression yet + pass + raise SyntaxError # We never found anything that worked. + +def pos_finder(s, char=','): + # returns the list of string positions where the char 'char' was found + pos=[] + for i in range(len(s)): + if s[i] == char: + pos.append(i) + return pos d={} @@ -35,11 +121,19 @@ 'change type': strip_parens, 'op': None} +d['failUnless'] = d['assert_'] + + +d['failIf'] = {'new': 'assert not', + 'change type': fail_special, + 'op': None} + +d['fail'] = {'old': 'fail', + 'new': 'raise AssertionError ', + 'change type': strip_parens, + 'op': None} + """ -d['failUnless'] = {'old':'failUnless', - 'new': 'assert', - 'change type': 'strip_parens', - 'op': None} d['failUnlessEqual'] = {'old': 'failUnlessEqual', 'new': 'assert not', @@ -82,16 +176,6 @@ 'comma to op', 'op': '!='} -d['failIf'] = {'old': 'failIf', - 'new': 'assert not', - 'change type': 'strip_parens', - 'op': None} - -d['fail'] = {'old': 'fail', - 'new': 'raise AssertionError ', - 'change type': 'strip_parens', - 'op': None} - d['assertEqual'] = {'old': 'assertEqual', 'new': 'assert', 'change type': 'comma to op', @@ -136,18 +220,34 @@ return blocklist def process_block(s): - #print 'found the block ', block f = old_names.match(s) if f: key = f.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' + # now do the dictionary dispatch. return d[key]['change type'](key, d[key]['new'], s) else: return s +def which_comma(tuplelist): + import parser + + # make the python parser do the hard work of deciding which comma + # splits the string into two expressions + + for l, r in tuplelist: + try: + + parser.expr(l + ')') + parser.expr('(' + r) + return l , r # Great! Both sides are expressions! + except SyntaxError: # It wasn't that comma + pass + raise SyntaxError # We never found anything that worked. + class Testit(unittest.TestCase): def test(self): self.assertEquals(process_block("badger badger badger"), - "badger badger badger") + "badger badger badger") self.assertEquals(process_block( "self.assertRaises(excClass, callableObj, *args, **kwargs)" @@ -157,11 +257,11 @@ self.assertEquals(process_block( """ - self.assertRaises(TypeError, func, 42, {'arg1': 23}) + self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) """ ), """ - raises(TypeError, func, 42, {'arg1': 23}) + raises(TypeError, func, 42, **{'arg1': 23}) """ ) self.assertEquals(process_block( @@ -179,8 +279,56 @@ ) self.assertEquals(process_block("self.assert_(x)"), "assert x") - + self.assertEquals(process_block("self.failUnless(func(x)) # XXX"), + "assert func(x) # XXX") + self.assertEquals(process_block( + """ + self.assert_(1 + f(y) + + z) # multiline, add continuation backslash + """ + ), + r""" + assert 1 + f(y)\ + + z # multiline, add continuation backslash + """ + ) + + self.assertEquals(process_block("self.assert_(0, 'badger badger')"), + "assert 0, 'badger badger'") + + self.assertEquals(process_block( + r""" + self.assert_(0, + 'Meet the badger.\n') + """ + ), + r""" + assert 0,\ + 'Meet the badger.\n' + """ + ) + + + self.assertEquals(process_block( + r""" + self.assert_(0 + 0 + + len('badger\n') + + 0, '''badger badger badger badger + mushroom mushroom + Snake! It's a snake! + ''') # multiline, must remove the parens + """ + ), + r""" + assert 0 + 0\ + + len('badger\n')\ + + 0, '''badger badger badger badger + mushroom mushroom + Snake! It's a snake! + ''' # multiline, must remove the parens + """ + ) if __name__ == '__main__': unittest.main() From lac at codespeak.net Sat Jun 19 16:02:58 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 19 Jun 2004 16:02:58 +0200 (MEST) Subject: [pypy-svn] r5169 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040619140258.4BC605C06B@thoth.codespeak.net> Author: lac Date: Sat Jun 19 16:02:57 2004 New Revision: 5169 Modified: pypy/branch/src-new-utest/pypy/tool/tiny.py Log: Ooops, edited wrong line there .... Modified: pypy/branch/src-new-utest/pypy/tool/tiny.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/tiny.py (original) +++ pypy/branch/src-new-utest/pypy/tool/tiny.py Sat Jun 19 16:02:57 2004 @@ -125,12 +125,12 @@ d['failIf'] = {'new': 'assert not', - 'change type': fail_special, + 'change type': strip_parens, 'op': None} d['fail'] = {'old': 'fail', 'new': 'raise AssertionError ', - 'change type': strip_parens, + 'change type': fail_special, 'op': None} """ @@ -312,7 +312,7 @@ self.assertEquals(process_block( r""" - self.assert_(0 + 0 + self.failIf(0 + 0 + len('badger\n') + 0, '''badger badger badger badger mushroom mushroom @@ -321,7 +321,7 @@ """ ), r""" - assert 0 + 0\ + assert not 0 + 0\ + len('badger\n')\ + 0, '''badger badger badger badger mushroom mushroom From lac at codespeak.net Sat Jun 19 21:32:54 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 19 Jun 2004 21:32:54 +0200 (MEST) Subject: [pypy-svn] r5170 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040619193254.522CE5C06B@thoth.codespeak.net> Author: lac Date: Sat Jun 19 21:32:53 2004 New Revision: 5170 Removed: pypy/branch/src-new-utest/pypy/tool/testconverter.py Modified: pypy/branch/src-new-utest/pypy/tool/tiny.py Log: All but rounding ones done now. time for dinner. Deleted: /pypy/branch/src-new-utest/pypy/tool/testconverter.py ============================================================================== --- /pypy/branch/src-new-utest/pypy/tool/testconverter.py Sat Jun 19 21:32:53 2004 +++ (empty file) @@ -1,128 +0,0 @@ -import re -import unittest - -old= 'self.assertEquals' -new= 'assert' -old_function = re.compile(r'^(\s*)' + old + r'\((.*)') -leading_spaces = re.compile(r'^(\s*)') - - -def convert(s, old, new): - - compile(s.lstrip(), '', 'exec') - body = s.replace(old, '', 1).lstrip() - plist = pos_finder(body, ',') - - if plist == []: - raise SyntaxError , "Could not find a ',' in %s" % body - else: - arglist = [] - for p in plist: - l, r = body[:p], body[p+1:] - arglist.append((l, r)) - - l, r = which_comma(arglist) - - if r.rstrip()[-1] != ')': - # if the last printing char of the string is not ')', - # keep the parens for now. This could be refined. - return new + l + ') == (' + r - - else: # see if we can drop one set of parens - - stripped = r.rstrip() - line_ends = r[len(stripped):] - block = new + ' ' + l[1:] + ' == ' + stripped[0:-1] + line_ends - try: - compile(block, '', 'exec') - return block - except SyntaxError: # too bad, needed them - return new + l + ') == (' + r - -def which_comma(tuplelist): - import parser - - # make the python parser do the hard work of deciding which comma - # splits the string into two expressions - - for l, r in tuplelist: - try: - - parser.expr(l + ')') - parser.expr('(' + r) - return l , r # Great! Both sides are expressions! - except SyntaxError: # It wasn't that comma - pass - raise SyntaxError # We never found anything that worked. - -def pos_finder(s, char=','): - # returns the list of string positions where the char 'char' was found - pos=[] - for i in range(len(s)): - if s[i] == char: - pos.append(i) - return pos - -def blocksplitter(filename): - - fp = file(filename, 'r') - blockstring = '' - filestring = '' - was_interesting = False - indent = '' - - for line in fp: - - ls = leading_spaces.search(line) # this will never fail - l_spaces = ls.group(1) - - interesting = old_function.search(line) - - if interesting : - # we have found the beginning of a new interesting block. - # finish up your business with your last block, if - # necessary and reset everything - - if was_interesting: - try: - backstring = convert(blockstring, old, new) - filestring += indent + backstring - except SyntaxError: - filestring += blockstring # malformed, copy as written - - blockstring = line # reset the block - indent = ls.group(1) - was_interesting = True - - elif not was_interesting and not interesting : - # the last line was not interesting and this one isn't either. - - filestring += line - - else: - # the slightly-hard case: - # is this line a continuation of the current interesting block? - # or is it just another uninteresting line that follows it? - - try: - filestring += indent + convert(blockstring, old, new) - # We were done. This is a boring old follower - - filestring += line - was_interesting = False - - except SyntaxError: # we haven't got enough yet. - blockstring += line - - if was_interesting : - try: - filestring += indent + convert(blockstring, old, new) - except SyntaxError: - print 'last block %s was malformed' % blockstring.rstrip() - filestring += blockstring - - print filestring - -if __name__ == '__main__': - #unittest.main() - blocksplitter('xxx.py') Modified: pypy/branch/src-new-utest/pypy/tool/tiny.py ============================================================================== --- pypy/branch/src-new-utest/pypy/tool/tiny.py (original) +++ pypy/branch/src-new-utest/pypy/tool/tiny.py Sat Jun 19 21:32:53 2004 @@ -6,52 +6,57 @@ # 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 type'] is one of the following functions -# namechange_only e.g. assertRaises becomes raises -# strip_parens e.g. assert_(expr) becomes assert expr +# namechange_only e.g. assertRaises becomes raises # fail_special e.g. fail() becomes raise AssertionError -# comma to op e.g. assertEquals(l, r) becomes assert l == r +# 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. # First define the functions you want to dispatch -def namechange_only(old, new, block): +def namechange_only(old, new, block, op): # dictionary dispatch function. # this is the simplest of changes. return re.sub('self.'+old, new, block) -def strip_parens(old, new, block): +def fail_special(old, new, block, op): # dictionary dispatch function. + pat = re.search(r'^(\s*)', block) + indent = pat.group() + pat = re.search('self.' + old + r'\(', block) + rest = block[pat.end():] + expr, trailer = get_expr(rest, ')') + + if expr == '': # fail() --> raise AssertionError + return indent + new + trailer + else: # fail('Problem') --> raise AssertionError, 'Problem' + return indent + new + ', ' + expr + trailer + +def strip_parens(old, new, block, op): + # dictionary dispatch function. + return_dict={} pat = re.search(r'^(\s*)', block) indent = pat.group() pat = re.search('self.' + old + r'\(', block) rest = block[pat.end():] expr, trailer = get_expr(rest, ')') + extra = '' try: parser.expr(expr) # the parens came off easily - return indent + new + ' ' + expr + trailer except SyntaxError: - - # now we have to go to work. It would be nice if we could - # just keep the parens, since the original author probably - # used them to group things nicely in a complicated multi-line - # expression. - # - # There is one hitch. - # # self.assertx_(0, string) prints the string, as does - # assert 0, string . But not only does assert(0, string) not - # print the string, it also doesn't print the AssertionError - # either. So nothing for it, we have to paste continuation - # backslashes on our multiline constructs. + # assert 0, string . But assert(0, string) prints + # neither the string, nor the AssertionError ! So we have + # to paste continuation backslashes on our multiline constructs. try: - realexpr, s = get_expr(expr, ',') + left, right = get_expr(expr, ',') # aha. we found an expr followed by a ', something_else' # we should probably test to make sure that something_else @@ -60,38 +65,64 @@ # more thought than I want to do at this hour ... # Given that assert 0, range(10) is legal, and prints # AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], is it - # even true that s has to be a string? + # even true that right has to be a string? - expr_w_slash = re.sub(r'\n', r'\\\n', realexpr) - - if s[0] == '\n': # that needs a slash too ... - return indent + new + ' ' + expr_w_slash + ',\\' + s + trailer + expr = re.sub(r'\n', r'\\\n', left) + + if right[0] == '\n': # that needs a slash too ... + extra = ',\\' + right else: - return indent + new + ' ' + expr_w_slash + ',' + s + trailer + extra = ',' + right except SyntaxError: # we couldn't find a 'expr, string' so it is # probably just a regular old multiline expression - # t.ex. self.assertx(0 + # e.g self.assertx(0 # +f(x) # +g(x)) - expr_w_slash = re.sub(r'\n', r'\\\n', expr) - return indent + new + ' ' + expr_w_slash + trailer + expr = re.sub(r'\n', r'\\\n', expr) -def fail_special(old, new, block): - # dictionary dispatch function. - # while assert_() is an error, fail() and - # fail('message') are just fine. - return re.sub('self.'+old, new, block) - + return indent + new + ' ' + expr + extra + trailer + +def comma_to_op(old, new, block, op): + # dictionary dispatch function. get_expr does all the work. + + pat = re.search(r'^(\s*)', block) + indent = pat.group() + pat = re.search('self.' + old + r'\(', block) + rest = block[pat.end():] + + expr, trailer = get_expr(rest, ')') + left, right = get_expr(expr, ',') + #print 'left is <%s>, right is <%s>' % (left, right) + + try: + parser.expr(left) # that paren came off easily + left = left + ' ' + op + except SyntaxError: + left = re.sub(r'\n', r'\\\n', left + ' ' + op) + #if right[0] == '\n': # that needs a slash too ... + # left += '\\' + try: + parser.expr(right) # that paren came off easily + except SyntaxError: + right = re.sub(r'\n', r'\\\n', right) + + return indent + new + ' ' + left + right + trailer def get_expr(s, char): + # used by fail_special, real_strip_parens, comma_to_op # read from the beginning of the string until you get an expression. # return it, and the stuff left over, minus the char you separated on pos = pos_finder(s, char) + + if pos == []: + raise SyntaxError # we didn't find the expected char. Ick. for p in pos: + # make the python parser do the hard work of deciding which comma + # splits the string into two expressions try: parser.expr('(' + s[:p] + ')') return s[:p], s[p+1:] @@ -100,6 +131,7 @@ raise SyntaxError # We never found anything that worked. def pos_finder(s, char=','): + # used by find_expr # returns the list of string positions where the char 'char' was found pos=[] for i in range(len(s)): @@ -109,51 +141,47 @@ d={} -#def assertRaises(self, excClass, callableObj, *args, **kwargs) - d['assertRaises'] = {'new': 'raises', 'change type': namechange_only, 'op': None} d['failUnlessRaises'] = d['assertRaises'] +d['fail'] = {'new': 'raise AssertionError', + 'change type': fail_special, + 'op': None} + d['assert_'] = {'new': 'assert', 'change type': strip_parens, 'op': None} d['failUnless'] = d['assert_'] - d['failIf'] = {'new': 'assert not', 'change type': strip_parens, 'op': None} -d['fail'] = {'old': 'fail', - 'new': 'raise AssertionError ', - 'change type': fail_special, - 'op': None} +d['assertEqual'] = {'new': 'assert', + 'change type': comma_to_op, + 'op': '=='} + +d['assertEquals'] = d['assertEqual'] -""" -d['failUnlessEqual'] = {'old': 'failUnlessEqual', - 'new': 'assert not', - 'change type': 'comma to op', +d['assertNotEqual'] = {'new': 'assert', + 'change type':comma_to_op, 'op': '!='} -d['failIfEqual'] = {'old': 'failIfEqual', - 'new': 'assert not', - 'change type': 'comma to op', - 'op': '=='} +d['assertNotEquals'] = d['assertNotEqual'] -d['assertEquals'] = {'old': 'assertEquals', - 'new': 'assert', - 'change type': 'comma to op', - 'op': '=='} +d['failUnlessEqual'] = {'new': 'assert not', + 'change type': comma_to_op, + 'op': '!='} +d['failIfEqual'] = {'new': 'assert not', + 'change type': comma_to_op, + 'op': '=='} -d['assertNotEqual'] = {'old': 'assertNotEqual', - 'new': 'assert', - 'change type': 'comma to op', - 'op': '!='} +""" d['assertNotAlmostEqual'] = {'old': 'assertNotAlmostEqual', 'new': 'assert round', @@ -170,17 +198,6 @@ 'change type': 'rounding', 'op': '=='} -d['assertNotEquals'] = {'old': 'assertNotEquals', - 'new': 'assert', - 'change type': - 'comma to op', - 'op': '!='} - -d['assertEqual'] = {'old': 'assertEqual', - 'new': 'assert', - 'change type': 'comma to op', - 'op': '=='} - d['assertUnlessAlmostEquals'] = {'old': 'assertUnlessAlmostEquals', 'new': 'assert round', 'change type': 'rounding', @@ -224,26 +241,10 @@ if f: key = f.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' # now do the dictionary dispatch. - return d[key]['change type'](key, d[key]['new'], s) + return d[key]['change type'](key, d[key]['new'], s, d[key] ['op']) else: return s -def which_comma(tuplelist): - import parser - - # make the python parser do the hard work of deciding which comma - # splits the string into two expressions - - for l, r in tuplelist: - try: - - parser.expr(l + ')') - parser.expr('(' + r) - return l , r # Great! Both sides are expressions! - except SyntaxError: # It wasn't that comma - pass - raise SyntaxError # We never found anything that worked. - class Testit(unittest.TestCase): def test(self): self.assertEquals(process_block("badger badger badger"), @@ -253,7 +254,7 @@ "self.assertRaises(excClass, callableObj, *args, **kwargs)" ), "raises(excClass, callableObj, *args, **kwargs)" - ) + ) self.assertEquals(process_block( """ @@ -263,7 +264,7 @@ """ raises(TypeError, func, 42, **{'arg1': 23}) """ - ) + ) self.assertEquals(process_block( """ self.assertRaises(TypeError, @@ -276,9 +277,11 @@ func, mushroom) """ - ) - self.assertEquals(process_block("self.assert_(x)"), - "assert x") + ) + self.assertEquals(process_block("self.fail()"), "raise AssertionError") + self.assertEquals(process_block("self.fail('mushroom, mushroom')"), + "raise AssertionError, 'mushroom, mushroom'") + self.assertEquals(process_block("self.assert_(x)"), "assert x") self.assertEquals(process_block("self.failUnless(func(x)) # XXX"), "assert func(x) # XXX") @@ -292,7 +295,7 @@ assert 1 + f(y)\ + z # multiline, add continuation backslash """ - ) + ) self.assertEquals(process_block("self.assert_(0, 'badger badger')"), "assert 0, 'badger badger'") @@ -307,31 +310,96 @@ assert 0,\ 'Meet the badger.\n' """ - ) - + ) self.assertEquals(process_block( r""" self.failIf(0 + 0 - + len('badger\n') - + 0, '''badger badger badger badger + + len('badger\n') + + 0, '''badger badger badger badger mushroom mushroom - Snake! It's a snake! + Snake! Ooh a snake! ''') # multiline, must remove the parens """ ), r""" assert not 0 + 0\ - + len('badger\n')\ - + 0, '''badger badger badger badger + + len('badger\n')\ + + 0, '''badger badger badger badger mushroom mushroom - Snake! It's a snake! + Snake! Ooh a snake! ''' # multiline, must remove the parens """ - ) + ) + self.assertEquals(process_block("self.assertEquals(0, 0)"), + "assert 0 == 0") + + self.assertEquals(process_block( + r""" + self.assertEquals(0, + 'Run away from the snake.\n') + """ + ), + r""" + assert 0 ==\ + 'Run away from the snake.\n' + """ + ) + + self.assertEquals(process_block( + r""" + self.assertEquals(badger + 0 + + mushroom + + snake, 0) + """ + ), + r""" + assert badger + 0\ + + mushroom\ + + snake == 0 + """ + ) + + self.assertEquals(process_block( + r""" + self.assertNotEquals(badger + 0 + + mushroom + + snake, + mushroom + - badger) + """ + ), + r""" + assert badger + 0\ + + mushroom\ + + snake !=\ + mushroom\ + - badger + """ + ) + + self.assertEqual(process_block( + r""" + self.assertEquals(badger(), + mushroom() + + snake(mushroom) + - badger()) + """ + ), + r""" + assert badger() ==\ + mushroom()\ + + snake(mushroom)\ + - badger() + """ + ) + self.assertEquals(process_block("self.failIfEqual(0, 0)"), + "assert not 0 == 0") + + self.assertEquals(process_block("self.failUnlessEqual(0, 0)"), + "assert not 0 != 0") + if __name__ == '__main__': unittest.main() #for block in blocksplitter('xxx.py'): print process_block(block) - - From lac at codespeak.net Sat Jun 19 21:37:31 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 19 Jun 2004 21:37:31 +0200 (MEST) Subject: [pypy-svn] r5171 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040619193731.0E97F5C06B@thoth.codespeak.net> Author: lac Date: Sat Jun 19 21:37:31 2004 New Revision: 5171 Added: pypy/branch/src-new-utest/pypy/tool/utestconvert.py - copied unchanged from r5170, pypy/branch/src-new-utest/pypy/tool/tiny.py Removed: pypy/branch/src-new-utest/pypy/tool/tiny.py Log: Give tiny a better name. It handles all utest conversions except the rounding ones, which shouldn't be hard to add. But its dinnertime. Deleted: /pypy/branch/src-new-utest/pypy/tool/tiny.py ============================================================================== --- /pypy/branch/src-new-utest/pypy/tool/tiny.py Sat Jun 19 21:37:31 2004 +++ (empty file) @@ -1,405 +0,0 @@ -import re -import unittest -import parser - - -# 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 type'] 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. - -# First define the functions you want to dispatch - -def namechange_only(old, new, block, op): - # dictionary dispatch function. - # this is the simplest of changes. - return re.sub('self.'+old, new, block) - -def fail_special(old, new, block, op): - # dictionary dispatch function. - pat = re.search(r'^(\s*)', block) - indent = pat.group() - pat = re.search('self.' + old + r'\(', block) - rest = block[pat.end():] - - expr, trailer = get_expr(rest, ')') - - if expr == '': # fail() --> raise AssertionError - return indent + new + trailer - else: # fail('Problem') --> raise AssertionError, 'Problem' - return indent + new + ', ' + expr + trailer - -def strip_parens(old, new, block, op): - # dictionary dispatch function. - return_dict={} - pat = re.search(r'^(\s*)', block) - indent = pat.group() - pat = re.search('self.' + old + r'\(', block) - rest = block[pat.end():] - - expr, trailer = get_expr(rest, ')') - extra = '' - - try: - parser.expr(expr) # the parens came off easily - - except SyntaxError: - # self.assertx_(0, string) prints the string, as does - # assert 0, string . But assert(0, string) prints - # neither the string, nor the AssertionError ! So we have - # to paste continuation backslashes on our multiline constructs. - - try: - left, right = get_expr(expr, ',') - - # aha. we found an expr followed by a ', something_else' - # we should probably test to make sure that something_else - # is a string, and not, say, another expr. But the whole - # question of what to do when your input is bogus requires - # more thought than I want to do at this hour ... - # Given that assert 0, range(10) is legal, and prints - # AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], is it - # even true that right has to be a string? - - expr = re.sub(r'\n', r'\\\n', left) - - if right[0] == '\n': # that needs a slash too ... - extra = ',\\' + right - else: - extra = ',' + right - - except SyntaxError: - # we couldn't find a 'expr, string' so it is - # probably just a regular old multiline expression - # e.g self.assertx(0 - # +f(x) - # +g(x)) - - expr = re.sub(r'\n', r'\\\n', expr) - - return indent + new + ' ' + expr + extra + trailer - -def comma_to_op(old, new, block, op): - # dictionary dispatch function. get_expr does all the work. - - pat = re.search(r'^(\s*)', block) - indent = pat.group() - pat = re.search('self.' + old + r'\(', block) - rest = block[pat.end():] - - expr, trailer = get_expr(rest, ')') - left, right = get_expr(expr, ',') - #print 'left is <%s>, right is <%s>' % (left, right) - - try: - parser.expr(left) # that paren came off easily - left = left + ' ' + op - except SyntaxError: - left = re.sub(r'\n', r'\\\n', left + ' ' + op) - #if right[0] == '\n': # that needs a slash too ... - # left += '\\' - try: - parser.expr(right) # that paren came off easily - except SyntaxError: - right = re.sub(r'\n', r'\\\n', right) - - return indent + new + ' ' + left + right + trailer - -def get_expr(s, char): - # used by fail_special, real_strip_parens, comma_to_op - # read from the beginning of the string until you get an expression. - # return it, and the stuff left over, minus the char you separated on - pos = pos_finder(s, char) - - if pos == []: - raise SyntaxError # we didn't find the expected char. Ick. - - for p in pos: - # make the python parser do the hard work of deciding which comma - # splits the string into two expressions - try: - parser.expr('(' + s[:p] + ')') - return s[:p], s[p+1:] - except SyntaxError: # It's not an expression yet - pass - raise SyntaxError # We never found anything that worked. - -def pos_finder(s, char=','): - # used by find_expr - # returns the list of string positions where the char 'char' was found - pos=[] - for i in range(len(s)): - if s[i] == char: - pos.append(i) - return pos - -d={} - -d['assertRaises'] = {'new': 'raises', - 'change type': namechange_only, - 'op': None} - -d['failUnlessRaises'] = d['assertRaises'] - -d['fail'] = {'new': 'raise AssertionError', - 'change type': fail_special, - 'op': None} - -d['assert_'] = {'new': 'assert', - 'change type': strip_parens, - 'op': None} - -d['failUnless'] = d['assert_'] - -d['failIf'] = {'new': 'assert not', - 'change type': strip_parens, - 'op': None} - -d['assertEqual'] = {'new': 'assert', - 'change type': comma_to_op, - 'op': '=='} - -d['assertEquals'] = d['assertEqual'] - - -d['assertNotEqual'] = {'new': 'assert', - 'change type':comma_to_op, - 'op': '!='} - -d['assertNotEquals'] = d['assertNotEqual'] - -d['failUnlessEqual'] = {'new': 'assert not', - 'change type': comma_to_op, - 'op': '!='} -d['failIfEqual'] = {'new': 'assert not', - 'change type': comma_to_op, - 'op': '=='} - -""" - -d['assertNotAlmostEqual'] = {'old': 'assertNotAlmostEqual', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '!='} - -d['assertNotAlmostEquals'] = {'old': 'assertNotAlmostEquals', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '!='} - -d['failUnlessAlmostEqual'] = {'old': 'failUnlessAlmostEqual', - 'new': 'assert not round', - 'change type': 'rounding', - 'op': '=='} - -d['assertUnlessAlmostEquals'] = {'old': 'assertUnlessAlmostEquals', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '=='} - -d['assertAlmostEqual'] = {'old': 'assertAlmostEqual', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '=='} -""" -leading_spaces = re.compile(r'^(\s*)') - -pat = '' -for k in d.keys(): - pat += '|' + r'^(\s*)' + 'self.' + k + r'\(' # \tself.whatever( - -old_names = re.compile(pat[1:]) # strip the extra '|' from front - -def blocksplitter(filename): - - fp = file(filename, 'r') - blocklist = [] - blockstring = '' - - for line in fp: - - interesting = old_names.match(line) - - if interesting : - if blockstring: - blocklist.append(blockstring) - blockstring = line # reset the block - else: - blockstring += line - - blocklist.append(blockstring) - return blocklist - -def process_block(s): - f = old_names.match(s) - if f: - key = f.group(0).lstrip()[5:-1] # '\tself.blah(' -> 'blah' - # now do the dictionary dispatch. - return d[key]['change type'](key, d[key]['new'], s, d[key] ['op']) - else: - return s - -class Testit(unittest.TestCase): - def test(self): - self.assertEquals(process_block("badger badger badger"), - "badger badger badger") - - self.assertEquals(process_block( - "self.assertRaises(excClass, callableObj, *args, **kwargs)" - ), - "raises(excClass, callableObj, *args, **kwargs)" - ) - - self.assertEquals(process_block( - """ - self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) - """ - ), - """ - raises(TypeError, func, 42, **{'arg1': 23}) - """ - ) - self.assertEquals(process_block( - """ - self.assertRaises(TypeError, - func, - mushroom) - """ - ), - """ - raises(TypeError, - func, - mushroom) - """ - ) - self.assertEquals(process_block("self.fail()"), "raise AssertionError") - self.assertEquals(process_block("self.fail('mushroom, mushroom')"), - "raise AssertionError, 'mushroom, mushroom'") - self.assertEquals(process_block("self.assert_(x)"), "assert x") - self.assertEquals(process_block("self.failUnless(func(x)) # XXX"), - "assert func(x) # XXX") - - self.assertEquals(process_block( - """ - self.assert_(1 + f(y) - + z) # multiline, add continuation backslash - """ - ), - r""" - assert 1 + f(y)\ - + z # multiline, add continuation backslash - """ - ) - - self.assertEquals(process_block("self.assert_(0, 'badger badger')"), - "assert 0, 'badger badger'") - - self.assertEquals(process_block( - r""" - self.assert_(0, - 'Meet the badger.\n') - """ - ), - r""" - assert 0,\ - 'Meet the badger.\n' - """ - ) - - self.assertEquals(process_block( - r""" - self.failIf(0 + 0 - + len('badger\n') - + 0, '''badger badger badger badger - mushroom mushroom - Snake! Ooh a snake! - ''') # multiline, must remove the parens - """ - ), - r""" - assert not 0 + 0\ - + len('badger\n')\ - + 0, '''badger badger badger badger - mushroom mushroom - Snake! Ooh a snake! - ''' # multiline, must remove the parens - """ - ) - - self.assertEquals(process_block("self.assertEquals(0, 0)"), - "assert 0 == 0") - - self.assertEquals(process_block( - r""" - self.assertEquals(0, - 'Run away from the snake.\n') - """ - ), - r""" - assert 0 ==\ - 'Run away from the snake.\n' - """ - ) - - self.assertEquals(process_block( - r""" - self.assertEquals(badger + 0 - + mushroom - + snake, 0) - """ - ), - r""" - assert badger + 0\ - + mushroom\ - + snake == 0 - """ - ) - - self.assertEquals(process_block( - r""" - self.assertNotEquals(badger + 0 - + mushroom - + snake, - mushroom - - badger) - """ - ), - r""" - assert badger + 0\ - + mushroom\ - + snake !=\ - mushroom\ - - badger - """ - ) - - self.assertEqual(process_block( - r""" - self.assertEquals(badger(), - mushroom() - + snake(mushroom) - - badger()) - """ - ), - r""" - assert badger() ==\ - mushroom()\ - + snake(mushroom)\ - - badger() - """ - ) - self.assertEquals(process_block("self.failIfEqual(0, 0)"), - "assert not 0 == 0") - - self.assertEquals(process_block("self.failUnlessEqual(0, 0)"), - "assert not 0 != 0") - -if __name__ == '__main__': - unittest.main() - #for block in blocksplitter('xxx.py'): print process_block(block) From lac at codespeak.net Sun Jun 20 08:59:26 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 20 Jun 2004 08:59:26 +0200 (MEST) Subject: [pypy-svn] r5178 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040620065926.071D35BDAC@thoth.codespeak.net> Author: lac Date: Sun Jun 20 08:59:25 2004 New Revision: 5178 Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py Log: Don't you love it when you wake up in the morning full of plans for shortening your code .... and they work? And now I see a bug, off to squash it ... 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 Sun Jun 20 08:59:25 2004 @@ -23,13 +23,8 @@ def fail_special(old, new, block, op): # dictionary dispatch function. - pat = re.search(r'^(\s*)', block) - indent = pat.group() - pat = re.search('self.' + old + r'\(', block) - rest = block[pat.end():] - - expr, trailer = get_expr(rest, ')') - + indent, expr, trailer = common_setup(old, block) + if expr == '': # fail() --> raise AssertionError return indent + new + trailer else: # fail('Problem') --> raise AssertionError, 'Problem' @@ -37,42 +32,32 @@ def strip_parens(old, new, block, op): # dictionary dispatch function. - return_dict={} - pat = re.search(r'^(\s*)', block) - indent = pat.group() - pat = re.search('self.' + old + r'\(', block) - rest = block[pat.end():] - - expr, trailer = get_expr(rest, ')') - extra = '' + indent, expr, trailer = common_setup(old, block) + new = new + ' ' try: parser.expr(expr) # the parens came off easily + return indent + new + expr + trailer except SyntaxError: - # self.assertx_(0, string) prints the string, as does - # assert 0, string . But assert(0, string) prints - # neither the string, nor the AssertionError ! So we have - # to paste continuation backslashes on our multiline constructs. - + # paste continuation backslashes on our multiline constructs. try: + # is the input expr, string? left, right = get_expr(expr, ',') + # ok, paste continuation backslashes on our left, + # but not on our right hand side, since a multiline + # string is not using the parens to avoid SyntaxError, + # and must already have a working mechanism, existing + # backslashes, or triple quotes .... - # aha. we found an expr followed by a ', something_else' - # we should probably test to make sure that something_else - # is a string, and not, say, another expr. But the whole - # question of what to do when your input is bogus requires - # more thought than I want to do at this hour ... - # Given that assert 0, range(10) is legal, and prints - # AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], is it - # even true that right has to be a string? - - expr = re.sub(r'\n', r'\\\n', left) + left = re.sub(r'\n', r'\\\n', left) if right[0] == '\n': # that needs a slash too ... - extra = ',\\' + right + # do we handle non unix correctly? + between = ',\\' else: - extra = ',' + right + between = ',' + return indent + new + left + between + right + trailer except SyntaxError: # we couldn't find a 'expr, string' so it is @@ -83,17 +68,11 @@ expr = re.sub(r'\n', r'\\\n', expr) - return indent + new + ' ' + expr + extra + trailer + return indent + new + expr + trailer def comma_to_op(old, new, block, op): # dictionary dispatch function. get_expr does all the work. - - pat = re.search(r'^(\s*)', block) - indent = pat.group() - pat = re.search('self.' + old + r'\(', block) - rest = block[pat.end():] - - expr, trailer = get_expr(rest, ')') + indent, expr, trailer = common_setup(old, block) left, right = get_expr(expr, ',') #print 'left is <%s>, right is <%s>' % (left, right) @@ -111,8 +90,15 @@ return indent + new + ' ' + left + right + trailer +def common_setup(old, block): + + 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 get_expr(s, char): - # used by fail_special, real_strip_parens, comma_to_op + # the trick. how to get an expression without really trying :-) # read from the beginning of the string until you get an expression. # return it, and the stuff left over, minus the char you separated on pos = pos_finder(s, char) From lac at codespeak.net Sun Jun 20 11:57:54 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 20 Jun 2004 11:57:54 +0200 (MEST) Subject: [pypy-svn] r5180 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040620095754.CD4485C1AA@thoth.codespeak.net> Author: lac Date: Sun Jun 20 11:57:54 2004 New Revision: 5180 Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py Log: fixed bug where triple quotes comments as right hand side of assert == and friends was getting an erroneous extra backslash 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 Sun Jun 20 11:57:54 2004 @@ -53,7 +53,7 @@ left = re.sub(r'\n', r'\\\n', left) if right[0] == '\n': # that needs a slash too ... - # do we handle non unix correctly? + # do we handle non-unix correctly? between = ',\\' else: between = ',' @@ -71,27 +71,43 @@ return indent + new + expr + trailer def comma_to_op(old, new, block, op): - # dictionary dispatch function. get_expr does all the work. + # dictionary dispatch function. parser.expr does all the work. + indent, expr, trailer = common_setup(old, block) + new = new + ' ' + op = ' ' + op left, right = get_expr(expr, ',') - #print 'left is <%s>, right is <%s>' % (left, right) + print 'left is <%s>, right is <%s>' % (left, right) try: parser.expr(left) # that paren came off easily - left = left + ' ' + op except SyntaxError: - left = re.sub(r'\n', r'\\\n', left + ' ' + op) - #if right[0] == '\n': # that needs a slash too ... - # left += '\\' + left = re.sub(r'\n', r'\\\n', left) + try: - parser.expr(right) # that paren came off easily + parser.expr(right.lstrip()) # that paren came off easily + except SyntaxError: right = re.sub(r'\n', r'\\\n', right) - return indent + new + ' ' + left + right + trailer + if right[0] == '\n': + op = op + '\\' + return indent + new + left + op + right + trailer -def common_setup(old, block): +def right_finder(s): + + for i in range(len(s)): + if s[i] != ' ' and s[i] != '\t': + print i + break + if s[i] == '\n': + return True + else: + return False + +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():], ')') @@ -385,7 +401,28 @@ self.assertEquals(process_block("self.failUnlessEqual(0, 0)"), "assert not 0 != 0") + + self.assertEquals(process_block( + r""" + self.failUnlessEqual(mushroom() + + mushroom() + + mushroom(), '''badger badger badger badger + badger badger badger badger + badger badger badger badger + ''') # multiline, must remove the parens + """ + ), + r""" + assert not mushroom()\ + + mushroom()\ + + mushroom() != '''badger badger badger badger + badger badger badger badger + badger badger badger badger + ''' # multiline, must remove the parens + """ + ) if __name__ == '__main__': unittest.main() #for block in blocksplitter('xxx.py'): print process_block(block) + From lac at codespeak.net Sun Jun 20 13:18:37 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 20 Jun 2004 13:18:37 +0200 (MEST) Subject: [pypy-svn] r5181 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040620111837.C8C995C1AA@thoth.codespeak.net> Author: lac Date: Sun Jun 20 13:18:36 2004 New Revision: 5181 Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py Log: Reorder the function some, to aid in comprehension. Change it to handle other os's line separation character. Still untested on anything but linux. 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 Sun Jun 20 13:18:36 2004 @@ -1,8 +1,9 @@ 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, and # d['change type'] is one of the following functions @@ -13,146 +14,98 @@ # rounding e.g. assertAlmostEqual(l, r) becomes # assert round(l - r, 7) == 0 # Finally, 'op' is the operator you will substitute, if applicable. - -# First define the functions you want to dispatch +# Got to define the dispatch functions first .... def namechange_only(old, new, block, op): - # dictionary dispatch function. - # this is the simplest of changes. + '''rename a function. dictionary dispatched.''' return re.sub('self.'+old, new, block) +d['assertRaises'] = {'new': 'raises', + 'change type': namechange_only, + 'op': None} + +d['failUnlessRaises'] = d['assertRaises'] + def fail_special(old, new, block, op): - # dictionary dispatch function. + '''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 strip_parens(old, new, block, op): - # dictionary dispatch function. - indent, expr, trailer = common_setup(old, block) - new = new + ' ' - - try: - parser.expr(expr) # the parens came off easily - return indent + new + expr + trailer - - except SyntaxError: - # paste continuation backslashes on our multiline constructs. - try: - # is the input expr, string? - left, right = get_expr(expr, ',') - # ok, paste continuation backslashes on our left, - # but not on our right hand side, since a multiline - # string is not using the parens to avoid SyntaxError, - # and must already have a working mechanism, existing - # backslashes, or triple quotes .... - - left = re.sub(r'\n', r'\\\n', left) - - if right[0] == '\n': # that needs a slash too ... - # do we handle non-unix correctly? - between = ',\\' - else: - between = ',' - return indent + new + left + between + right + trailer - - except SyntaxError: - # we couldn't find a 'expr, string' so it is - # probably just a regular old multiline expression - # e.g self.assertx(0 - # +f(x) - # +g(x)) - - expr = re.sub(r'\n', r'\\\n', expr) - - return indent + new + expr + trailer + +d['fail'] = {'new': 'raise AssertionError', + 'change type': fail_special, + 'op': None} def comma_to_op(old, new, block, op): - # dictionary dispatch function. parser.expr does all the work. - + '''change comma to appropriate op. dictionary dispatched. ''' indent, expr, trailer = common_setup(old, block) new = new + ' ' op = ' ' + op left, right = get_expr(expr, ',') - print 'left is <%s>, right is <%s>' % (left, right) try: parser.expr(left) # that paren came off easily except SyntaxError: - left = re.sub(r'\n', r'\\\n', left) + left = re.sub(linesep, '\\'+linesep, left) try: parser.expr(right.lstrip()) # that paren came off easily - except SyntaxError: - right = re.sub(r'\n', r'\\\n', right) + right = re.sub(linesep, '\\'+linesep, right) - if right[0] == '\n': + if right.startswith(linesep): op = op + '\\' return indent + new + left + op + right + trailer -def right_finder(s): - - for i in range(len(s)): - if s[i] != ' ' and s[i] != '\t': - print i - break - - if s[i] == '\n': - return True - else: - return False - -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 get_expr(s, char): - # the trick. how to get an expression without really trying :-) - # read from the beginning of the string until you get an expression. - # return it, and the stuff left over, minus the char you separated on - pos = pos_finder(s, char) +d['assertEqual'] = {'new': 'assert', + 'change type': comma_to_op, + 'op': '=='} - if pos == []: - raise SyntaxError # we didn't find the expected char. Ick. - - for p in pos: - # make the python parser do the hard work of deciding which comma - # splits the string into two expressions - try: - parser.expr('(' + s[:p] + ')') - return s[:p], s[p+1:] - except SyntaxError: # It's not an expression yet - pass - raise SyntaxError # We never found anything that worked. +d['assertEquals'] = d['assertEqual'] -def pos_finder(s, char=','): - # used by find_expr - # returns the list of string positions where the char 'char' was found - pos=[] - for i in range(len(s)): - if s[i] == char: - pos.append(i) - return pos +d['assertNotEqual'] = {'new': 'assert', + 'change type':comma_to_op, + 'op': '!='} -d={} +d['assertNotEquals'] = d['assertNotEqual'] -d['assertRaises'] = {'new': 'raises', - 'change type': namechange_only, - 'op': None} +d['failUnlessEqual'] = {'new': 'assert not', + 'change type': comma_to_op, + 'op': '!='} +d['failIfEqual'] = {'new': 'assert not', + 'change type': comma_to_op, + 'op': '=='} -d['failUnlessRaises'] = d['assertRaises'] +def strip_parens(old, new, block, op): + '''remove one set of parens. dictionary dispatched. ''' + indent, expr, trailer = common_setup(old, block) + new = new + ' ' -d['fail'] = {'new': 'raise AssertionError', - 'change type': fail_special, - 'op': None} + try: + parser.expr(expr) # the parens came off easily + return indent + new + expr + trailer + except SyntaxError: + # paste continuation backslashes on our multiline constructs. + try: + # is the input expr, string? + left, right = get_expr(expr, ',') + left = re.sub(linesep, '\\'+linesep, left) + # since the right is a string, assume it can take care + # of itself even if multiline. + + if right.startswith(linesep):# that needs a slash too ... + between = ',\\' + else: + between = ',' + return indent + new + left + between + right + trailer + except SyntaxError: # just a regular old multiline expression + expr = re.sub(linesep, '\\'+linesep, expr) + return indent + new + expr + trailer + d['assert_'] = {'new': 'assert', 'change type': strip_parens, 'op': None} @@ -162,27 +115,6 @@ d['failIf'] = {'new': 'assert not', 'change type': strip_parens, 'op': None} - -d['assertEqual'] = {'new': 'assert', - 'change type': comma_to_op, - 'op': '=='} - -d['assertEquals'] = d['assertEqual'] - - -d['assertNotEqual'] = {'new': 'assert', - 'change type':comma_to_op, - 'op': '!='} - -d['assertNotEquals'] = d['assertNotEqual'] - -d['failUnlessEqual'] = {'new': 'assert not', - 'change type': comma_to_op, - 'op': '!='} -d['failIfEqual'] = {'new': 'assert not', - 'change type': comma_to_op, - 'op': '=='} - """ d['assertNotAlmostEqual'] = {'old': 'assertNotAlmostEqual', @@ -213,10 +145,11 @@ leading_spaces = re.compile(r'^(\s*)') pat = '' -for k in d.keys(): +for k in d.keys(): # this complicated pattern to match all unittests pat += '|' + r'^(\s*)' + 'self.' + k + r'\(' # \tself.whatever( old_names = re.compile(pat[1:]) # strip the extra '|' from front +linesep=os.linesep def blocksplitter(filename): @@ -247,6 +180,42 @@ else: return s +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 get_expr(s, char): + # the trick. how to get an expression without really trying :-) + # read from the beginning of the string until you get an expression. + # return it, and the stuff left over, minus the char you separated on + pos = pos_finder(s, char) + + if pos == []: + raise SyntaxError # we didn't find the expected char. Ick. + + for p in pos: + # make the python parser do the hard work of deciding which comma + # splits the string into two expressions + try: + parser.expr('(' + s[:p] + ')') + return s[:p], s[p+1:] + except SyntaxError: # It's not an expression yet + pass + raise SyntaxError # We never found anything that worked. + +def pos_finder(s, char=','): + # used by find_expr + # returns the list of string positions where the char 'char' was found + pos=[] + for i in range(len(s)): + if s[i] == char: + pos.append(i) + return pos + class Testit(unittest.TestCase): def test(self): self.assertEquals(process_block("badger badger badger"), From lac at codespeak.net Sun Jun 20 15:46:26 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 20 Jun 2004 15:46:26 +0200 (MEST) Subject: [pypy-svn] r5182 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040620134626.630C95A7AE@thoth.codespeak.net> Author: lac Date: Sun Jun 20 15:46:25 2004 New Revision: 5182 Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py Log: fixed a bug where I forgot that self.assertEquals and friends could have messages too ... 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 Sun Jun 20 15:46:25 2004 @@ -4,15 +4,16 @@ 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, and -# d['change type'] is one of the following functions +# 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 +# assert round(l - r, 7) == 0 # Finally, 'op' is the operator you will substitute, if applicable. # Got to define the dispatch functions first .... @@ -20,12 +21,6 @@ '''rename a function. dictionary dispatched.''' return re.sub('self.'+old, new, block) -d['assertRaises'] = {'new': 'raises', - 'change type': namechange_only, - 'op': None} - -d['failUnlessRaises'] = d['assertRaises'] - def fail_special(old, new, block, op): '''change fail function to raise AssertionError. dictionary dispatched. ''' indent, expr, trailer = common_setup(old, block) @@ -34,10 +29,6 @@ return indent + new + trailer else: # fail('Problem') --> raise AssertionError, 'Problem' return indent + new + ', ' + expr + trailer - -d['fail'] = {'new': 'raise AssertionError', - 'change type': fail_special, - 'op': None} def comma_to_op(old, new, block, op): '''change comma to appropriate op. dictionary dispatched. ''' @@ -54,36 +45,32 @@ try: parser.expr(right.lstrip()) # that paren came off easily except SyntaxError: - right = re.sub(linesep, '\\'+linesep, right) + # paste continuation backslashes on our multiline constructs + try: + # is the input expr, expr, string? + # so right is expr, string? + + expr, string = get_expr(right, ',') + expr = re.sub(linesep, '\\'+linesep, expr) + # since the right1 is a string, assume it can take care + # of itself even if multiline. + + if expr.startswith(linesep):# that needs a slash too ... + between = ',\\' + else: + between = ',' + right = expr + between + string + except SyntaxError: # just a regular old multiline expression + right = re.sub(linesep, '\\'+linesep, right) if right.startswith(linesep): op = op + '\\' return indent + new + left + op + right + trailer -d['assertEqual'] = {'new': 'assert', - 'change type': comma_to_op, - 'op': '=='} - -d['assertEquals'] = d['assertEqual'] - -d['assertNotEqual'] = {'new': 'assert', - 'change type':comma_to_op, - 'op': '!='} - -d['assertNotEquals'] = d['assertNotEqual'] - -d['failUnlessEqual'] = {'new': 'assert not', - 'change type': comma_to_op, - 'op': '!='} -d['failIfEqual'] = {'new': 'assert not', - 'change type': comma_to_op, - 'op': '=='} - def strip_parens(old, new, block, op): '''remove one set of parens. dictionary dispatched. ''' indent, expr, trailer = common_setup(old, block) new = new + ' ' - try: parser.expr(expr) # the parens came off easily return indent + new + expr + trailer @@ -105,62 +92,60 @@ except SyntaxError: # just a regular old multiline expression expr = re.sub(linesep, '\\'+linesep, expr) return indent + new + expr + trailer - -d['assert_'] = {'new': 'assert', - 'change type': strip_parens, - 'op': None} +def rounding(): + pass + +# Now the dictionary of unittests. There sure are enough of them! + +d['assertRaises'] = {'new': 'raises', 'change': namechange_only, 'op': None} +d['failUnlessRaises'] = d['assertRaises'] + +d['fail'] = {'new': 'raise AssertionError', 'change': fail_special, 'op': None} + +d['assertEqual'] = {'new': 'assert', 'change': comma_to_op, 'op': '=='} +d['assertEquals'] = d['assertEqual'] + +d['assertNotEqual'] = {'new': 'assert', 'change':comma_to_op, 'op': '!='} +d['assertNotEquals'] = d['assertNotEqual'] + +d['failUnlessEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '!='} + +d['failIfEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '=='} + +d['assert_'] = {'new': 'assert','change': strip_parens, 'op': None} d['failUnless'] = d['assert_'] -d['failIf'] = {'new': 'assert not', - 'change type': strip_parens, - 'op': None} -""" - -d['assertNotAlmostEqual'] = {'old': 'assertNotAlmostEqual', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '!='} - -d['assertNotAlmostEquals'] = {'old': 'assertNotAlmostEquals', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '!='} - -d['failUnlessAlmostEqual'] = {'old': 'failUnlessAlmostEqual', - 'new': 'assert not round', - 'change type': 'rounding', - 'op': '=='} - -d['assertUnlessAlmostEquals'] = {'old': 'assertUnlessAlmostEquals', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '=='} - -d['assertAlmostEqual'] = {'old': 'assertAlmostEqual', - 'new': 'assert round', - 'change type': 'rounding', - 'op': '=='} -""" -leading_spaces = re.compile(r'^(\s*)') +d['failIf'] = {'new': 'assert not', 'change': strip_parens, 'op': None} + +d['assertAlmostEqual'] = {'new': 'assert round', 'change': rounding, 'op':'=='} +d['assertAlmostEquals'] = d['assertAlmostEqual'] + +d['assertNotAlmostEqual'] = {'new':'assert round','change':rounding, 'op':'!='} +d['assertNotAlmostEquals'] = d['assertNotAlmostEqual'] + +d['failIfAlmostEqual'] = {'new': 'assert not round', + 'change': rounding, 'op': '=='} +d['failUnlessAlmostEquals'] = {'new': 'assert not round', + 'change': rounding, 'op': '!='} + +leading_spaces = re.compile(r'^(\s*)') # this never fails pat = '' for k in d.keys(): # this complicated pattern to match all unittests pat += '|' + r'^(\s*)' + 'self.' + k + r'\(' # \tself.whatever( -old_names = re.compile(pat[1:]) # strip the extra '|' from front +old_names = re.compile(pat[1:]) linesep=os.linesep def blocksplitter(filename): - + '''split a file into blocks that are headed by functions to rename''' fp = file(filename, 'r') blocklist = [] blockstring = '' for line in fp: - interesting = old_names.match(line) - if interesting : if blockstring: blocklist.append(blockstring) @@ -171,13 +156,13 @@ blocklist.append(blockstring) return blocklist -def process_block(s): +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' - # now do the dictionary dispatch. - return d[key]['change type'](key, d[key]['new'], s, d[key] ['op']) - else: + return d[key]['change'](key, d[key]['new'], s, d[key] ['op']) + else: # just copy uninteresting lines return s def common_setup(old, block): @@ -189,11 +174,12 @@ return indent, expr, trailer def get_expr(s, char): - # the trick. how to get an expression without really trying :-) - # read from the beginning of the string until you get an expression. - # return it, and the stuff left over, minus the char you separated on - pos = pos_finder(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: + pos.append(i) if pos == []: raise SyntaxError # we didn't find the expected char. Ick. @@ -207,27 +193,18 @@ pass raise SyntaxError # We never found anything that worked. -def pos_finder(s, char=','): - # used by find_expr - # returns the list of string positions where the char 'char' was found - pos=[] - for i in range(len(s)): - if s[i] == char: - pos.append(i) - return pos - class Testit(unittest.TestCase): def test(self): - self.assertEquals(process_block("badger badger badger"), + self.assertEquals(dispatch("badger badger badger"), "badger badger badger") - self.assertEquals(process_block( + self.assertEquals(dispatch( "self.assertRaises(excClass, callableObj, *args, **kwargs)" ), "raises(excClass, callableObj, *args, **kwargs)" ) - self.assertEquals(process_block( + self.assertEquals(dispatch( """ self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) """ @@ -236,7 +213,7 @@ raises(TypeError, func, 42, **{'arg1': 23}) """ ) - self.assertEquals(process_block( + self.assertEquals(dispatch( """ self.assertRaises(TypeError, func, @@ -249,14 +226,14 @@ mushroom) """ ) - self.assertEquals(process_block("self.fail()"), "raise AssertionError") - self.assertEquals(process_block("self.fail('mushroom, mushroom')"), + self.assertEquals(dispatch("self.fail()"), "raise AssertionError") + self.assertEquals(dispatch("self.fail('mushroom, mushroom')"), "raise AssertionError, 'mushroom, mushroom'") - self.assertEquals(process_block("self.assert_(x)"), "assert x") - self.assertEquals(process_block("self.failUnless(func(x)) # XXX"), + self.assertEquals(dispatch("self.assert_(x)"), "assert x") + self.assertEquals(dispatch("self.failUnless(func(x)) # XXX"), "assert func(x) # XXX") - self.assertEquals(process_block( + self.assertEquals(dispatch( """ self.assert_(1 + f(y) + z) # multiline, add continuation backslash @@ -268,10 +245,10 @@ """ ) - self.assertEquals(process_block("self.assert_(0, 'badger badger')"), + self.assertEquals(dispatch("self.assert_(0, 'badger badger')"), "assert 0, 'badger badger'") - self.assertEquals(process_block( + self.assertEquals(dispatch( r""" self.assert_(0, 'Meet the badger.\n') @@ -283,7 +260,7 @@ """ ) - self.assertEquals(process_block( + self.assertEquals(dispatch( r""" self.failIf(0 + 0 + len('badger\n') @@ -303,10 +280,10 @@ """ ) - self.assertEquals(process_block("self.assertEquals(0, 0)"), + self.assertEquals(dispatch("self.assertEquals(0, 0)"), "assert 0 == 0") - self.assertEquals(process_block( + self.assertEquals(dispatch( r""" self.assertEquals(0, 'Run away from the snake.\n') @@ -318,7 +295,7 @@ """ ) - self.assertEquals(process_block( + self.assertEquals(dispatch( r""" self.assertEquals(badger + 0 + mushroom @@ -332,7 +309,7 @@ """ ) - self.assertEquals(process_block( + self.assertEquals(dispatch( r""" self.assertNotEquals(badger + 0 + mushroom @@ -350,7 +327,7 @@ """ ) - self.assertEqual(process_block( + self.assertEqual(dispatch( r""" self.assertEquals(badger(), mushroom() @@ -365,13 +342,13 @@ - badger() """ ) - self.assertEquals(process_block("self.failIfEqual(0, 0)"), + self.assertEquals(dispatch("self.failIfEqual(0, 0)"), "assert not 0 == 0") - self.assertEquals(process_block("self.failUnlessEqual(0, 0)"), + self.assertEquals(dispatch("self.failUnlessEqual(0, 0)"), "assert not 0 != 0") - self.assertEquals(process_block( + self.assertEquals(dispatch( r""" self.failUnlessEqual(mushroom() + mushroom() @@ -391,7 +368,52 @@ """ ) + self.assertEquals(dispatch( + r""" + self.assertEquals(badger(), + snake(), 'BAD BADGER') + """ + ), + r""" + assert badger() ==\ + snake(), 'BAD BADGER' + """ + ) + self.assertEquals(dispatch( + r""" + self.assertEquals(badger(), + snake(), '''BAD BADGER + BAD BADGER + BAD BADGER''' + ) + """ + ), + r""" + assert badger() ==\ + snake(), '''BAD BADGER + BAD BADGER + BAD BADGER''' + + """ + ) + self.assertEquals(dispatch( + 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!!' + """ + ) + if __name__ == '__main__': unittest.main() - #for block in blocksplitter('xxx.py'): print process_block(block) + #for block in blocksplitter('xxx.py'): print dispatch(block) + From lac at codespeak.net Sun Jun 20 17:25:44 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 20 Jun 2004 17:25:44 +0200 (MEST) Subject: [pypy-svn] r5185 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040620152544.827555A7AE@thoth.codespeak.net> Author: lac Date: Sun Jun 20 17:25:43 2004 New Revision: 5185 Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py Log: stamp out code duplication in a neighbourhood near you! 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 Sun Jun 20 17:25:43 2004 @@ -46,52 +46,38 @@ parser.expr(right.lstrip()) # that paren came off easily except SyntaxError: # paste continuation backslashes on our multiline constructs - try: - # is the input expr, expr, string? - # so right is expr, string? - - expr, string = get_expr(right, ',') - expr = re.sub(linesep, '\\'+linesep, expr) - # since the right1 is a string, assume it can take care - # of itself even if multiline. - - if expr.startswith(linesep):# that needs a slash too ... - between = ',\\' - else: - between = ',' - right = expr + between + string - except SyntaxError: # just a regular old multiline expression - right = re.sub(linesep, '\\'+linesep, right) - + right = handle_multiline(right) + if right.startswith(linesep): op = op + '\\' return indent + new + left + op + right + trailer +def handle_multiline(expr, sep=','): + try: + left, right = get_expr(expr, 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, expr) + def strip_parens(old, new, block, op): '''remove one set of parens. dictionary dispatched. ''' indent, expr, trailer = common_setup(old, block) new = new + ' ' try: parser.expr(expr) # the parens came off easily - return indent + new + expr + trailer except SyntaxError: # paste continuation backslashes on our multiline constructs. - try: - # is the input expr, string? - left, right = get_expr(expr, ',') - left = re.sub(linesep, '\\'+linesep, left) - # since the right is a string, assume it can take care - # of itself even if multiline. - - if right.startswith(linesep):# that needs a slash too ... - between = ',\\' - else: - between = ',' - return indent + new + left + between + right + trailer - - except SyntaxError: # just a regular old multiline expression - expr = re.sub(linesep, '\\'+linesep, expr) - return indent + new + expr + trailer + expr = handle_multiline(expr) + + return indent + new + expr + trailer def rounding(): pass From lac at codespeak.net Sun Jun 20 18:11:38 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Sun, 20 Jun 2004 18:11:38 +0200 (MEST) Subject: [pypy-svn] r5186 - pypy/branch/src-new-utest/pypy/tool Message-ID: <20040620161138.F40105BFF1@thoth.codespeak.net> Author: lac Date: Sun Jun 20 18:11:36 2004 New Revision: 5186 Modified: pypy/branch/src-new-utest/pypy/tool/utestconvert.py Log: The last refactoring out of common code left some functions and variables with poor names, an arglist which was a string, no longer a list, for instance. Fix the names up. 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 Sun Jun 20 18:11:36 2004 @@ -32,52 +32,30 @@ def comma_to_op(old, new, block, op): '''change comma to appropriate op. dictionary dispatched. ''' - indent, expr, trailer = common_setup(old, block) +p indent, expr, trailer = common_setup(old, block) new = new + ' ' op = ' ' + op left, right = get_expr(expr, ',') try: - parser.expr(left) # that paren came off easily + parser.expr(left.lstrip()) # that paren came off easily except SyntaxError: left = re.sub(linesep, '\\'+linesep, left) - try: - parser.expr(right.lstrip()) # that paren came off easily - except SyntaxError: - # paste continuation backslashes on our multiline constructs - right = handle_multiline(right) - + right = process_args(right) + if right.startswith(linesep): op = op + '\\' - return indent + new + left + op + right + trailer - -def handle_multiline(expr, sep=','): - try: - left, right = get_expr(expr, 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, expr) + return indent + new + left + op + right + trailer + def strip_parens(old, new, block, op): '''remove one set of parens. dictionary dispatched. ''' - indent, expr, trailer = common_setup(old, block) + indent, args, trailer = common_setup(old, block) new = new + ' ' - try: - parser.expr(expr) # the parens came off easily - except SyntaxError: - # paste continuation backslashes on our multiline constructs. - expr = handle_multiline(expr) - return indent + new + expr + trailer + args = process_args(args) + return indent + new + args + trailer def rounding(): pass @@ -159,6 +137,35 @@ 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 + +def process_args(args): + 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 + else: + return left + def get_expr(s, char): '''split a string into an expression, and the rest of the string''' From lac at codespeak.net Mon Jun 21 14:43:53 2004 From: lac at codespeak.net (lac at codespeak.net) Date: Mon, 21 Jun 2004 14:43:53 +0200 (MEST) Subject: [pypy-svn] r5194 - pypy/trunk/src/pypy/tool Message-ID: <20040621124353.AF5F95A1B5@thoth.codespeak.net> Author: lac Date: Mon Jun 21 14:43:53 2004 New Revision: 5194 Added: pypy/trunk/src/pypy/tool/utestconvert.py Log: bring this one over here before I go to work so I don't have to check out the branch to get at thisone file. Added: pypy/trunk/src/pypy/tool/utestconvert.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/tool/utestconvert.py Mon Jun 21 14:43:53 2004 @@ -0,0 +1,450 @@ +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, 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, ',') + + 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 + ' ' + + 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['failUnlessRaises'] = d['assertRaises'] + +d['fail'] = {'new': 'raise AssertionError', 'change': fail_special, 'op': None} + +d['assertEqual'] = {'new': 'assert', 'change': comma_to_op, 'op': '=='} +d['assertEquals'] = d['assertEqual'] + +d['assertNotEqual'] = {'new': 'assert', 'change':comma_to_op, 'op': '!='} +d['assertNotEquals'] = d['assertNotEqual'] + +d['failUnlessEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '!='} + +d['failIfEqual'] = {'new': 'assert not', 'change': comma_to_op, 'op': '=='} + +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['assertAlmostEquals'] = d['assertAlmostEqual'] + +d['assertNotAlmostEqual'] = {'new':'assert round','change':rounding, 'op':'!='} +d['assertNotAlmostEquals'] = d['assertNotAlmostEqual'] + +d['failIfAlmostEqual'] = {'new': 'assert not round', + 'change': rounding, 'op': '=='} +d['failUnlessAlmostEqual'] = {'new': 'assert not round', + 'change': rounding, 'op': '!='} + +leading_spaces = re.compile(r'^(\s*)') # this never fails + +pat = '' +for k in d.keys(): # this complicated pattern to match all unittests + pat += '|' + r'^(\s*)' + 'self.' + k + r'\(' # \tself.whatever( + +old_names = re.compile(pat[1:]) +linesep=os.linesep + +def blocksplitter(filename): + '''split a file into blocks that are headed by functions to rename''' + fp = file(filename, 'r') + blocklist = [] + blockstring = '' + + for line in fp: + interesting = old_names.match(line) + if interesting : + if blockstring: + blocklist.append(blockstring) + blockstring = line # reset the block + else: + blockstring += line + + 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']) + else: # just copy uninteresting lines + return s + +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 + +def process_args(args): + '''start the process whereby lines that need backslashes get them''' + 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 + else: + return left + +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: + pos.append(i) + if pos == []: + raise SyntaxError # we didn't find the expected char. Ick. + + for p in pos: + # make the python parser do the hard work of deciding which comma + # splits the string into two expressions + try: + parser.expr('(' + s[:p] + ')') + return s[:p], s[p+1:] + except SyntaxError: # It's not an expression yet + pass + raise SyntaxError # We never found anything that worked. + +class Testit(unittest.TestCase): + def test(self): + self.assertEquals(dispatch("badger badger badger"), + "badger badger badger") + + self.assertEquals(dispatch( + "self.assertRaises(excClass, callableObj, *args, **kwargs)" + ), + "raises(excClass, callableObj, *args, **kwargs)" + ) + + self.assertEquals(dispatch( + """ + self.failUnlessRaises(TypeError, func, 42, **{'arg1': 23}) + """ + ), + """ + raises(TypeError, func, 42, **{'arg1': 23}) + """ + ) + self.assertEquals(dispatch( + """ + self.assertRaises(TypeError, + func, + mushroom) + """ + ), + """ + raises(TypeError, + func, + mushroom) + """ + ) + self.assertEquals(dispatch("self.fail()"), "raise AssertionError") + self.assertEquals(dispatch("self.fail('mushroom, mushroom')"), + "raise AssertionError, 'mushroom, mushroom'") + self.assertEquals(dispatch("self.assert_(x)"), "assert x") + self.assertEquals(dispatch("self.failUnless(func(x)) # XXX"), + "assert func(x) # XXX") + + self.assertEquals(dispatch( + """ + self.assert_(1 + f(y) + + z) # multiline, add continuation backslash + """ + ), + r""" + assert 1 + f(y)\ + + z # multiline, add continuation backslash + """ + ) + + self.assertEquals(dispatch("self.assert_(0, 'badger badger')"), + "assert 0, 'badger badger'") + + self.assertEquals(dispatch( + r""" + self.assert_(0, + 'Meet the badger.\n') + """ + ), + r""" + assert 0,\ + 'Meet the badger.\n' + """ + ) + + self.assertEquals(dispatch( + r""" + self.failIf(0 + 0 + + len('badger\n') + + 0, '''badger badger badger badger + mushroom mushroom + Snake! Ooh a snake! + ''') # multiline, must remove the parens + """ + ), + r""" + assert not 0 + 0\ + + len('badger\n')\ + + 0, '''badger badger badger badger + mushroom mushroom + Snake! Ooh a snake! + ''' # multiline, must remove the parens + """ + ) + + self.assertEquals(dispatch("self.assertEquals(0, 0)"), + "assert 0 == 0") + + self.assertEquals(dispatch( + r""" + self.assertEquals(0, + 'Run away from the snake.\n') + """ + ), + r""" + assert 0 ==\ + 'Run away from the snake.\n' + """ + ) + + self.assertEquals(dispatch( + r""" + self.assertEquals(badger + 0 + + mushroom + + snake, 0) + """ + ), + r""" + assert badger + 0\ + + mushroom\ + + snake == 0 + """ + ) + + self.assertEquals(dispatch( + r""" + self.assertNotEquals(badger + 0 + + mushroom + + snake, + mushroom + - badger) + """ + ), + r""" + assert badger + 0\ + + mushroom\ + + snake !=\ + mushroom\ + - badger + """ + ) + + self.assertEqual(dispatch( + r""" + self.assertEquals(badger(), + mushroom() + + snake(mushroom) + - badger()) + """ + ), + r""" + assert badger() ==\ + mushroom()\ + + snake(mushroom)\ + - badger() + """ + ) + self.assertEquals(dispatch("self.failIfEqual(0, 0)"), + "assert not 0 == 0") + + self.assertEquals(dispatch("self.failUnlessEqual(0, 0)"), + "assert not 0 != 0") + + self.assertEquals(dispatch( + r""" + self.failUnlessEqual(mushroom() + + mushroom() + + mushroom(), '''badger badger badger badger + badger badger badger badger + badger badger badger badger + ''') # multiline, must remove the parens + """ + ), + r""" + assert not mushroom()\ + + mushroom()\ + + mushroom() != '''badger badger badger badger + badger badger badger badger + badger badger badger badger + ''' # multiline, must remove the parens + """ + ) + + self.assertEquals(dispatch( + r""" + self.assertEquals(badger(), + snake(), 'BAD BADGER') + """ + ), + r""" + assert badger() ==\ + snake(), 'BAD BADGER' + """ + ) + self.assertEquals(dispatch( + r""" + self.assertEquals(badger(), + snake(), '''BAD BADGER + BAD BADGER + BAD BADGER''' + ) + """ + ), + r""" + assert badger() ==\ + snake(), '''BAD BADGER + BAD BADGER + BAD BADGER''' + + """ + ) + self.assertEquals(dispatch( + 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(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( + r""" + self.failIfAlmostEqual(badger(), + snake(), + 6, 'POISONOUS SNAKE!\ + Ai! I was bit by a POISONOUS SNAKE!!') + """ + ), + r""" + assert not round(badger() - snake(),\ + 6) == 0, 'POISONOUS SNAKE!\ + Ai! I was bit by a POISONOUS SNAKE!!' + """ + ) + +if __name__ == '__main__': + unittest.main() + #for block in blocksplitter('xxx.py'): print dispatch(block) + From arigo at codespeak.net Wed Jun 23 13:28:43 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 23 Jun 2004 13:28:43 +0200 (MEST) Subject: [pypy-svn] r5254 - pypy/trunk/src/pypy/interpreter Message-ID: <20040623112843.2B68E5AAB5@thoth.codespeak.net> Author: arigo Date: Wed Jun 23 13:28:42 2004 New Revision: 5254 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py Log: New opcode from Python 2.4: NOP. Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Wed Jun 23 13:28:42 2004 @@ -81,6 +81,9 @@ # the 'self' argument of opcode implementations is called 'f' # for historical reasons + def NOP(f): + pass + def LOAD_FAST(f, varindex): # access a local variable directly w_value = f.fastlocals_w[varindex] From arigo at codespeak.net Thu Jun 24 16:44:49 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 16:44:49 +0200 (MEST) Subject: [pypy-svn] r5268 - in pypy/trunk/src/pypy: annotation translator/test Message-ID: <20040624144449.45E975AB48@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 16:44:48 2004 New Revision: 5268 Modified: pypy/trunk/src/pypy/annotation/factory.py pypy/trunk/src/pypy/annotation/model.py pypy/trunk/src/pypy/annotation/unaryop.py pypy/trunk/src/pypy/translator/test/snippet.py pypy/trunk/src/pypy/translator/test/test_annrpython.py Log: Flow annotations inside __init__() constructors. Modified: pypy/trunk/src/pypy/annotation/factory.py ============================================================================== --- pypy/trunk/src/pypy/annotation/factory.py (original) +++ pypy/trunk/src/pypy/annotation/factory.py Thu Jun 24 16:44:48 2004 @@ -132,12 +132,19 @@ return self.bookkeeper.annotator.recursivecall(func, arglist, self) -class InstanceFactory: +class InstanceFactory(FuncCallFactory): - def create(self, cls): + def create(self, cls, arglist): classdef = self.bookkeeper.getclassdef(cls) classdef.instancefactories[self] = True - return SomeInstance(classdef) + s_instance = SomeInstance(classdef) + # flow into __init__() if the class has got one + init = getattr(cls, '__init__', None) + if init is not None and init != object.__init__: + self.pycall(init, [s_instance] + arglist) + else: + assert not arglist, "no __init__ found in %r" % (cls,) + return s_instance class ClassDef: Modified: pypy/trunk/src/pypy/annotation/model.py ============================================================================== --- pypy/trunk/src/pypy/annotation/model.py (original) +++ pypy/trunk/src/pypy/annotation/model.py Thu Jun 24 16:44:48 2004 @@ -162,13 +162,13 @@ def valueoftype(t): "The most precise SomeValue instance that contains all objects of type t." - if isinstance(bool, type) and issubclass(t, bool): + if t is bool: return SomeBool() - elif issubclass(t, int): + elif t is int: return SomeInteger() - elif issubclass(t, str): + elif t is str: return SomeString() - elif issubclass(t, list): + elif t is list: return SomeList(factories={}) else: return SomeObject() Modified: pypy/trunk/src/pypy/annotation/unaryop.py ============================================================================== --- pypy/trunk/src/pypy/annotation/unaryop.py (original) +++ pypy/trunk/src/pypy/annotation/unaryop.py Thu Jun 24 16:44:48 2004 @@ -130,9 +130,10 @@ class __extend__(SomeClass): def call(cls, args, kwds): - # XXX flow into __init__ + arglist = decode_simple_call(args, kwds) + assert arglist is not None factory = getbookkeeper().getfactory(InstanceFactory) - return factory.create(cls.cls) + return factory.create(cls.cls, arglist) class __extend__(SomeFunction): Modified: pypy/trunk/src/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/snippet.py Thu Jun 24 16:44:48 2004 @@ -324,11 +324,19 @@ def my_method(self): return self.my_attribute +class WithInit: + def __init__(self, n): + self.a = n + def simple_method(v=anytype): z = Z() z.my_attribute = v return z.my_method() +def with_init(v=int): + z = WithInit(v) + return z.a + def powerset(setsize=int): """Powerset Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_annrpython.py (original) +++ pypy/trunk/src/pypy/translator/test/test_annrpython.py Thu Jun 24 16:44:48 2004 @@ -211,6 +211,12 @@ # result should be a built-in method self.assert_(isinstance(s, annmodel.SomeBuiltin)) + def test_with_init(self): + a = RPythonAnnotator() + s = a.build_types(snippet.with_init, [int]) + # result should be an integer + self.assertEquals(s.knowntype, int) + def g(n): return [0,1,2,n] From arigo at codespeak.net Thu Jun 24 18:15:03 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 18:15:03 +0200 (MEST) Subject: [pypy-svn] r5269 - in pypy/trunk/src/pypy: annotation objspace/flow translator translator/test Message-ID: <20040624161503.AE19B5AB48@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 18:15:03 2004 New Revision: 5269 Modified: pypy/trunk/src/pypy/annotation/builtin.py pypy/trunk/src/pypy/annotation/model.py pypy/trunk/src/pypy/annotation/unaryop.py pypy/trunk/src/pypy/objspace/flow/flowcontext.py pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/translator/annrpython.py pypy/trunk/src/pypy/translator/test/snippet.py pypy/trunk/src/pypy/translator/test/test_annrpython.py pypy/trunk/src/pypy/translator/translator.py Log: A lot of minor changes to better support annotating methods: * Unbound methods are regarded as functions, for Parent.__init__(). * we can flow with constant arguments; used for the 'self' of constant bound method objects. See test_global_instance(). * int() returns an integer (let's say). Modified: pypy/trunk/src/pypy/annotation/builtin.py ============================================================================== --- pypy/trunk/src/pypy/annotation/builtin.py (original) +++ pypy/trunk/src/pypy/annotation/builtin.py Thu Jun 24 18:15:03 2004 @@ -20,6 +20,12 @@ else: return SomeObject() +def builtin_int(s_obj): # we can consider 'int' as a function + if isinstance(s_obj, SomeInteger): + return s_obj + else: + return SomeInteger() + # collect all functions import __builtin__ Modified: pypy/trunk/src/pypy/annotation/model.py ============================================================================== --- pypy/trunk/src/pypy/annotation/model.py (original) +++ pypy/trunk/src/pypy/annotation/model.py Thu Jun 24 18:15:03 2004 @@ -115,7 +115,8 @@ self.s_self = s_self class SomeFunction(SomeObject): - "Stands for a Python function (or some function out of a list)." + """Stands for a Python function (or some function out of a list). + Alternatively, it can be a constant bound or unbound method.""" knowntype = FunctionType def __init__(self, funcs): self.funcs = funcs # set of functions that this one may be @@ -153,7 +154,7 @@ result = SomeBuiltin(BUILTIN_FUNCTIONS[x]) elif isinstance(x, (type, ClassType)) and x.__module__ != '__builtin__': result = SomeClass(x) - elif isinstance(x, FunctionType): + elif isinstance(x, (FunctionType, MethodType)): result = SomeFunction({x: True}) else: result = SomeObject() Modified: pypy/trunk/src/pypy/annotation/unaryop.py ============================================================================== --- pypy/trunk/src/pypy/annotation/unaryop.py (original) +++ pypy/trunk/src/pypy/annotation/unaryop.py Thu Jun 24 18:15:03 2004 @@ -2,6 +2,7 @@ Unary operations on SomeValues. """ +from types import FunctionType from pypy.annotation.pairtype import pair from pypy.annotation.model import SomeObject, SomeInteger, SomeBool from pypy.annotation.model import SomeString, SomeList, SomeDict @@ -148,6 +149,8 @@ def classattribute(fun, classdef): # function -> unbound method d = {} for func in fun.funcs: + assert isinstance(func, FunctionType), ( + "%r should not be read out of class %r" % (func, classdef)) d[func] = classdef return SomeMethod(d) Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Thu Jun 24 18:15:03 2004 @@ -63,15 +63,17 @@ class FlowExecutionContext(ExecutionContext): - def __init__(self, space, code, globals): + def __init__(self, space, code, globals, constargs={}): ExecutionContext.__init__(self, space) self.code = code self.w_globals = w_globals = space.wrap(globals) frame = self.create_frame() formalargcount = code.getformalargcount() dummy = UndefinedConstant() - arg_list = ([Variable() for i in range(formalargcount)] + - [dummy] * (len(frame.fastlocals_w) - formalargcount)) + arg_list = [Variable() for i in range(formalargcount)] + for position, value in constargs.items(): + arg_list[position] = Constant(value) + arg_list += [dummy] * (len(frame.fastlocals_w) - formalargcount) frame.setfastscope(arg_list) self.joinpoints = {} for joinpoint in code.getjoinpoints(): Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Thu Jun 24 18:15:03 2004 @@ -67,12 +67,13 @@ #print >> sys.stderr, '*** reraise', etype, evalue raise OperationError, OperationError(self.wrap(etype), self.wrap(evalue)), etb - def build_flow(self, func): + def build_flow(self, func, constargs={}): """ """ code = func.func_code code = PyCode()._from_code(code) - ec = flowcontext.FlowExecutionContext(self, code, func.func_globals) + ec = flowcontext.FlowExecutionContext(self, code, func.func_globals, + constargs) self.executioncontext = ec ec.build_flow() name = ec.graph.name @@ -131,6 +132,8 @@ op = issubclass elif name == 'id': op = id + elif name == 'getattr': + op = getattr else: if debug: print >> sys.stderr, "XXX missing operator:", name Modified: pypy/trunk/src/pypy/translator/annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/annrpython.py (original) +++ pypy/trunk/src/pypy/translator/annrpython.py Thu Jun 24 18:15:03 2004 @@ -35,6 +35,7 @@ if self.translator is None: from pypy.translator.translator import Translator self.translator = Translator(func_or_flowgraph) + self.translator.annotator = self flowgraph = self.translator.getflowgraph(func_or_flowgraph) # make input arguments and set their type input_arg_types = list(input_arg_types) Modified: pypy/trunk/src/pypy/translator/test/snippet.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/snippet.py (original) +++ pypy/trunk/src/pypy/translator/test/snippet.py Thu Jun 24 18:15:03 2004 @@ -328,6 +328,11 @@ def __init__(self, n): self.a = n +class WithMoreInit(WithInit): + def __init__(self, n, m): + WithInit.__init__(self, n) + self.b = m + def simple_method(v=anytype): z = Z() z.my_attribute = v @@ -337,6 +342,15 @@ z = WithInit(v) return z.a +def with_more_init(v=int, w=bool): + z = WithMoreInit(v, w) + +global_z = Z() +global_z.my_attribute = 42 + +def global_instance(): + return global_z.my_method() + def powerset(setsize=int): """Powerset Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_annrpython.py (original) +++ pypy/trunk/src/pypy/translator/test/test_annrpython.py Thu Jun 24 18:15:03 2004 @@ -217,6 +217,26 @@ # result should be an integer self.assertEquals(s.knowntype, int) + def test_with_more_init(self): + a = RPythonAnnotator() + s = a.build_types(snippet.with_more_init, [int, bool]) + # the user classes should have the following attributes: + classes = a.bookkeeper.userclasses + # XXX on which class should the attribute 'a' appear? We only + # ever flow WithInit.__init__ with a self which is an instance + # of WithMoreInit, so currently it appears on WithMoreInit. + self.assertEquals(classes[snippet.WithMoreInit].attrs.get('a'), + annmodel.SomeInteger()) + self.assertEquals(classes[snippet.WithMoreInit].attrs.get('b'), + annmodel.SomeBool()) + + def test_global_instance(self): + a = RPythonAnnotator() + s = a.build_types(snippet.global_instance, []) + # currently this returns the constant 42. + # XXX not sure this is the best behavior... + self.assertEquals(s, annmodel.immutablevalue(42)) + def g(n): return [0,1,2,n] Modified: pypy/trunk/src/pypy/translator/translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/translator.py (original) +++ pypy/trunk/src/pypy/translator/translator.py Thu Jun 24 18:15:03 2004 @@ -43,8 +43,9 @@ class Translator: - def __init__(self, func): + def __init__(self, func, verbose=False): self.entrypoint = func + self.verbose = verbose self.clear() def clear(self): @@ -60,8 +61,17 @@ try: graph = self.flowgraphs[func] except KeyError: + if self.verbose: + print 'getflowgraph:', func.__name__ + im_func = getattr(func, 'im_func', func) + im_self = getattr(func, 'im_self', None) + if im_self is not None: # bound method? + constargs = {0: im_self} + else: + constargs = {} space = FlowObjSpace() - graph = self.flowgraphs[func] = space.build_flow(func) + graph = self.flowgraphs[func] = space.build_flow(im_func, + constargs) self.functions.append(func) try: import inspect From arigo at codespeak.net Thu Jun 24 18:34:03 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 18:34:03 +0200 (MEST) Subject: [pypy-svn] r5270 - in pypy/trunk/src/pypy/objspace/flow: . test Message-ID: <20040624163403.D6AAD5A96A@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 18:34:03 2004 New Revision: 5270 Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Log: * Yet another test file silently ignored because of ImportErrors * Added support in FlowObjSpace for analyzing functions with free variables, which means just making sure that the free variables get passed to the interpreter properly, as Constants. Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Thu Jun 24 18:34:03 2004 @@ -63,10 +63,15 @@ class FlowExecutionContext(ExecutionContext): - def __init__(self, space, code, globals, constargs={}): + def __init__(self, space, code, globals, constargs={}, closure=None): ExecutionContext.__init__(self, space) self.code = code self.w_globals = w_globals = space.wrap(globals) + if closure is None: + self.closure = None + else: + from pypy.interpreter.nestedscope import Cell + self.closure = [Cell(Constant(value)) for value in closure] frame = self.create_frame() formalargcount = code.getformalargcount() dummy = UndefinedConstant() @@ -86,7 +91,8 @@ # create an empty frame suitable for the code object # while ignoring any operation like the creation of the locals dict self.crnt_ops = [] - return self.code.create_frame(self.space, self.w_globals) + return self.code.create_frame(self.space, self.w_globals, + self.closure) def bytecode_trace(self, frame): if isinstance(self.crnt_ops, ReplayList): Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Thu Jun 24 18:34:03 2004 @@ -72,8 +72,12 @@ """ code = func.func_code code = PyCode()._from_code(code) + if func.func_closure is None: + closure = None + else: + closure = [extract_cell_content(c) for c in func.func_closure] ec = flowcontext.FlowExecutionContext(self, code, func.func_globals, - constargs) + constargs, closure) self.executioncontext = ec ec.build_flow() name = ec.graph.name @@ -120,6 +124,16 @@ return 'implicitexc' implicitexc = ImplicitExcValue() +def extract_cell_content(c): + """Get the value contained in a CPython 'cell', as read through + the func_closure of a function object.""" + import new + def hackout(): + return hackout # this access becomes a cell reference + # now change the cell to become 'c' + hackout = new.function(hackout.func_code, {}, '', None, (c,)) + return hackout() + def make_op(name, symbol, arity, specialnames): if hasattr(FlowObjSpace, name): return # Shouldn't do it Modified: pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Thu Jun 24 18:34:03 2004 @@ -1,10 +1,8 @@ import autopath from pypy.tool import testit -from pypy.objspace.flow.wrapper import * -from pypy.translator.flowmodel import * -class TestFlowOjSpace(testit.TestCase): +class TestFlowObjSpace(testit.TestCase): def setUp(self): self.space = testit.objspace('flow') @@ -63,7 +61,7 @@ def print_(i): print i - def test_print(self): + def dont_test_print(self): # app-level helpers confuse replay x = self.codetest(self.print_) self.show(x) @@ -214,6 +212,16 @@ x = self.codetest(self.implicitIndexError) self.show(x) + #__________________________________________________________ + def freevar(self, x): + def adder(y): + return x+y + return adder + + def test_freevar(self): + x = self.codetest(self.freevar(3)) + self.show(x) + if __name__ == '__main__': testit.main() From arigo at codespeak.net Thu Jun 24 18:37:23 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 18:37:23 +0200 (MEST) Subject: [pypy-svn] r5271 - pypy/trunk/src/goal Message-ID: <20040624163723.8ED8F5A96A@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 18:37:23 2004 New Revision: 5271 Added: pypy/trunk/src/goal/autopath.py (contents, props changed) pypy/trunk/src/goal/translate_pypy.py (contents, props changed) Log: An ambitious goal: set the translation entry point to StdObjSpace.mul(). Added: pypy/trunk/src/goal/autopath.py ============================================================================== --- (empty file) +++ pypy/trunk/src/goal/autopath.py Thu Jun 24 18:37:23 2004 @@ -0,0 +1,3 @@ +import sys, os +sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir)) + Added: pypy/trunk/src/goal/translate_pypy.py ============================================================================== --- (empty file) +++ pypy/trunk/src/goal/translate_pypy.py Thu Jun 24 18:37:23 2004 @@ -0,0 +1,44 @@ +# +# +# + +import autopath + +from pypy.objspace.std.objspace import StdObjSpace, W_Object +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.restricted_int import r_int +from pypy.translator.translator import Translator +from pypy.annotation import model as annmodel + + +# __________ Entry point __________ + +space = StdObjSpace() + +def entry_point(): + w_a = W_IntObject(space, -6) + w_b = W_IntObject(space, -7) + return space.mul(w_a, w_b) + + +# __________ Special cases __________ + +def special_immutablevalue(x): + if x is r_int: + x = int + return general_immutablevalue(x) + +general_immutablevalue = annmodel.immutablevalue +annmodel.immutablevalue = special_immutablevalue + +# __________ Main __________ + +if __name__ == '__main__': + # 2.3 specific + import os + os.putenv("PYTHONINSPECT", "1") + + t = Translator(entry_point, verbose=True) + t.simplify() + a = t.annotate([]) + a.simplify() From arigo at codespeak.net Thu Jun 24 18:42:59 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 18:42:59 +0200 (MEST) Subject: [pypy-svn] r5272 - pypy/trunk/src/pypy/objspace/flow Message-ID: <20040624164259.D82CF5A96A@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 18:42:59 2004 New Revision: 5272 Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py Log: Useful assertion message for debugging. Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Thu Jun 24 18:42:59 2004 @@ -55,7 +55,12 @@ def append(self, operation): operation.result = self.listtoreplay[self.index].result - assert operation == self.listtoreplay[self.index] + assert operation == self.listtoreplay[self.index], ( + '\n'.join(["Not generating the same operation sequence:"] + + [str(s) for s in self.listtoreplay[:self.index]] + + [" ---> | while repeating we see here"] + + [" | %s" % operation] + + [str(s) for s in self.listtoreplay[self.index:]])) self.index += 1 def finished(self): From arigo at codespeak.net Thu Jun 24 18:51:18 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 18:51:18 +0200 (MEST) Subject: [pypy-svn] r5273 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040624165118.12E015AB48@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 18:51:17 2004 New Revision: 5273 Modified: pypy/trunk/src/pypy/objspace/std/multimethod.py Log: * Removed a deprecated multimethod hack. * Added BoundMultiMethod.__eq__() to ensure that space.xxx == space.xxx for each multimethod xxx. 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 Thu Jun 24 18:51:17 2004 @@ -35,8 +35,6 @@ """Abstract base class for MultiMethod and UnboundMultiMethod i.e. the classes that are not bound to a specific space instance.""" - class BASE_TYPE_OBJECT: pass - def __init__(self, operatorsymbol, arity): self.arity = arity self.operatorsymbol = operatorsymbol @@ -277,11 +275,9 @@ self.unbound_versions = {} - def __get__(self, space, cls=object): # cls is some W_xxxType - if issubclass(cls, self.BASE_TYPE_OBJECT): - return self.slice(cls).get(space) - elif space is None: - return self # hack for "StdObjSpace.xyz" returning xyz + def __get__(self, space, cls=None): + if space is None: + return self else: return BoundMultiMethod(space, self) @@ -401,6 +397,17 @@ self.space = space self.multimethod = multimethod + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.space == other.space and + self.multimethod == other.multimethod) + + def __ne__(self, other): + return self != other + + def __hash__(self): + return hash((self.__class__, self.space, self.multimethod)) + def __call__(self, *args): if len(args) < self.multimethod.arity: raise TypeError, ("multimethod needs at least %d arguments" % From arigo at codespeak.net Thu Jun 24 20:16:23 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 20:16:23 +0200 (MEST) Subject: [pypy-svn] r5274 - in pypy/trunk/src/pypy: interpreter objspace objspace/flow objspace/test Message-ID: <20040624181623.7D9ED5A96A@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 20:16:19 2004 New Revision: 5274 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/objspace/flow/flowcontext.py pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/objspace/test/test_traceobjspace.py pypy/trunk/src/pypy/objspace/trace.py Log: * Added a space.generalcache that can be used for any initialization-time lazy computations, populated by calls to space.loadfromcache(). * FlowObjSpace overloads loadfromcache() to performs the initialization-time operations in "concrete" mode, in which only Constants may be involved and no operation recorded. * This is used to build app-level Gateways. We are closer to allow, say, print and raise statements in FlowObjSpace. * TraceObjSpace needed some fixing. Now it also ignores all loadfromcache() operations, which is probably what we want. Note that it doesn't mean that operations done by the *called* app-level helper will be hidden, only the initial construction of this helper (which was already hidden with calls to settrace()). Grumble. Now FlowObjSpace cannot interpret app-level helpers because calling them packs and unpacks the arguments into a tuple, and FlowObjSpace forgets the length of a tuple... Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Thu Jun 24 20:16:19 2004 @@ -24,9 +24,16 @@ def __init__(self): "Basic initialization of objects." - # sets all the internal descriptors + self.generalcache = {} + # sets all the internal descriptors self.initialize() + def loadfromcache(self, key, builder): + try: + return self.generalcache[key] + except KeyError: + return self.generalcache.setdefault(key, builder(self)) + def make_builtins(self, for_builtins): # initializing builtins may require creating a frame which in # turn already accesses space.w_builtins, provide a dummy one ... @@ -82,7 +89,7 @@ def getexecutioncontext(self): "Return what we consider to be the active execution context." - ec = getthreadlocals().executioncontext #it's allways None (dec. 2003) + ec = getthreadlocals().executioncontext if ec is None: ec = self.createexecutioncontext() return ec Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Thu Jun 24 20:16:19 2004 @@ -11,10 +11,6 @@ """ import types -try: - from weakref import WeakKeyDictionary -except ImportError: - WeakKeyDictionary = dict # XXX for PyPy from pypy.interpreter import eval, pycode from pypy.interpreter.function import Function, Method from pypy.interpreter.baseobjspace import Wrappable @@ -123,9 +119,6 @@ # explicitely as the first argument (for plain function), or is read # from 'self.space' for methods. - def __init__(self): - self.functioncache = WeakKeyDictionary() # map {space: Function} - # after initialization the following attributes should be set # name # code @@ -138,40 +131,40 @@ return self.get_function(space) def get_function(self, space): - try: - return self.functioncache[space] - except KeyError: - # the construction is supposed to be done only once in advance, - # but must be done lazily when needed only, because - # 1) it depends on the object space - # 2) the w_globals must not be built before the underlying - # staticglobals is completely initialized, because - # w_globals must be built only once for all the Gateway - # instances of staticglobals - if self.staticglobals is None: - w_globals = None + return space.loadfromcache(self, self.build_all_functions) + + def build_all_functions(self, space): + # the construction is supposed to be done only once in advance, + # but must be done lazily when needed only, because + # 1) it depends on the object space + # 2) the w_globals must not be built before the underlying + # staticglobals is completely initialized, because + # w_globals must be built only once for all the Gateway + # instances of staticglobals + if self.staticglobals is None: + w_globals = None + else: + # is there another Gateway in staticglobals for which we + # already have a w_globals for this space ? + for value in self.staticglobals.itervalues(): + if isinstance(value, Gateway): + if self in space.generalcache: + # yes, we share its w_globals + fn = space.generalcache[value] + w_globals = fn.w_func_globals + break else: - # is there another Gateway in staticglobals for which we - # already have a w_globals for this space ? - for value in self.staticglobals.itervalues(): - if isinstance(value, Gateway): - if space in value.functioncache: - # yes, we share its w_globals - fn = value.functioncache[space] - w_globals = fn.w_func_globals - break - else: - # no, we build all Gateways in the staticglobals now. - w_globals = build_dict(self.staticglobals, space) - return self.build_function(space, w_globals) + # no, we build all Gateways in the staticglobals now. + w_globals = build_dict(self.staticglobals, space) + return self.build_function(space, w_globals) def build_function(self, space, w_globals): - if space in self.functioncache: - fn = self.functioncache[space] + if self in space.generalcache: + fn = space.generalcache[self] else: defs = self.getdefaults(space) # needs to be implemented by subclass fn = Function(space, self.code, w_globals, defs, forcename = self.name) - self.functioncache[space] = fn + space.generalcache[self] = fn return fn def get_method(self, obj): Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Thu Jun 24 20:16:19 2004 @@ -66,6 +66,13 @@ def finished(self): return self.index == len(self.listtoreplay) +class ConcreteNoOp: + # In "concrete mode", no SpaceOperations between Variables are allowed. + # Concrete mode is used to precompute lazily-initialized caches, + # when we don't want this precomputation to show up on the flow graph. + def append(self, operation): + raise AssertionError, "concrete mode: cannot perform %s" % operation + class FlowExecutionContext(ExecutionContext): def __init__(self, space, code, globals, constargs={}, closure=None): @@ -100,7 +107,7 @@ self.closure) def bytecode_trace(self, frame): - if isinstance(self.crnt_ops, ReplayList): + if not isinstance(self.crnt_ops, list): return next_instr = frame.next_instr if next_instr in self.joinpoints: @@ -140,7 +147,7 @@ self.joinpoints[next_instr].insert(0, newblock) def guessbool(self, w_condition, cases=[False,True]): - if not isinstance(self.crnt_ops, ReplayList): + if isinstance(self.crnt_ops, list): block = self.crnt_block vars = block.getvariables() links = [] @@ -156,11 +163,14 @@ # actually have block.exits[False] = elseLink and # block.exits[True] = ifLink. raise ExitFrame(None) - replaylist = self.crnt_ops - assert replaylist.finished() - self.crnt_block = replaylist.nextblock - self.crnt_ops = replaylist.nextreplaylist - return replaylist.booloutcome + if isinstance(self.crnt_ops, ReplayList): + replaylist = self.crnt_ops + assert replaylist.finished() + self.crnt_block = replaylist.nextblock + self.crnt_ops = replaylist.nextreplaylist + return replaylist.booloutcome + raise AssertionError, "concrete mode: cannot guessbool(%s)" % ( + w_condition,) def build_flow(self): while self.pendingblocks: Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Thu Jun 24 20:16:19 2004 @@ -17,6 +17,7 @@ def initialize(self): import __builtin__ + self.concrete_mode = 0 self.w_builtins = Constant(__builtin__.__dict__) self.w_None = Constant(None) self.w_False = Constant(False) @@ -27,7 +28,27 @@ #self.make_builtins() #self.make_sys() + def loadfromcache(self, key, builder): + try: + return self.generalcache[key] + except KeyError: + # this method is overloaded to allow the space to switch to + # "concrete mode" when building the object that goes into + # the cache. In concrete mode, only Constants are allowed. + previous_ops = self.executioncontext.crnt_ops + self.executioncontext.crnt_ops = flowcontext.ConcreteNoOp() + self.concrete_mode += 1 + try: + return self.generalcache.setdefault(key, builder(self)) + finally: + self.executioncontext.crnt_ops = previous_ops + self.concrete_mode -= 1 + def newdict(self, items_w): + if self.concrete_mode: + content = [(self.unwrap(w_key), self.unwrap(w_value)) + for w_key, w_value in items_w] + return Constant(dict(content)) flatlist_w = [] for w_key, w_value in items_w: flatlist_w.append(w_key) @@ -35,16 +56,31 @@ return self.do_operation('newdict', *flatlist_w) def newtuple(self, args_w): - return self.do_operation('newtuple', *args_w) + try: + content = [self.unwrap(w_arg) for w_arg in args_w] + except UnwrapException: + return self.do_operation('newtuple', *args_w) + else: + return Constant(tuple(content)) def newlist(self, args_w): + if self.concrete_mode: + content = [self.unwrap(w_arg) for w_arg in args_w] + return Constant(content) return self.do_operation('newlist', *args_w) def newslice(self, w_start=None, w_stop=None, w_step=None): if w_start is None: w_start = self.w_None if w_stop is None: w_stop = self.w_None if w_step is None: w_step = self.w_None - return self.do_operation('newslice', w_start, w_stop, w_step) + try: + content = slice(self.unwrap(w_start), + self.unwrap(w_stop), + self.unwrap(w_step)) + except UnwrapException: + return self.do_operation('newslice', w_start, w_stop, w_step) + else: + return Constant(content) def wrap(self, obj): if isinstance(obj, (Variable, Constant)): 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 Thu Jun 24 20:16:19 2004 @@ -14,10 +14,9 @@ def perform_trace(self, app_func): tspace = TraceObjSpace(self.space) - func_gw = app2interp(app_func) + func_gw = app2interp(app_func) func = func_gw.get_function(tspace) - tspace.settrace() - self.space.call_function(self.space.wrap(func)) + tspace.call_function(tspace.wrap(func)) res = tspace.getresult() return res Modified: pypy/trunk/src/pypy/objspace/trace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trace.py (original) +++ pypy/trunk/src/pypy/objspace/trace.py Thu Jun 24 20:16:19 2004 @@ -108,6 +108,7 @@ 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 @@ -122,6 +123,19 @@ 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(self)) + finally: + self.__result = saved + def getexecutioncontext(self): ec = self.__space.getexecutioncontext() if isinstance(ec, ExecutionContextTracer): From arigo at codespeak.net Thu Jun 24 20:33:44 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 20:33:44 +0200 (MEST) Subject: [pypy-svn] r5275 - in pypy/trunk/src/pypy: objspace/flow translator/test Message-ID: <20040624183344.139EC5A96A@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 20:33:43 2004 New Revision: 5275 Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/translator/test/test_annrpython.py Log: Three tests failed. Fixed. Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Thu Jun 24 20:33:43 2004 @@ -73,14 +73,11 @@ if w_start is None: w_start = self.w_None if w_stop is None: w_stop = self.w_None if w_step is None: w_step = self.w_None - try: - content = slice(self.unwrap(w_start), - self.unwrap(w_stop), - self.unwrap(w_step)) - except UnwrapException: - return self.do_operation('newslice', w_start, w_stop, w_step) - else: - return Constant(content) + if self.concrete_mode: + return Constant(slice(self.unwrap(w_start), + self.unwrap(w_stop), + self.unwrap(w_step))) + return self.do_operation('newslice', w_start, w_stop, w_step) def wrap(self, obj): if isinstance(obj, (Variable, Constant)): Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_annrpython.py (original) +++ pypy/trunk/src/pypy/translator/test/test_annrpython.py Thu Jun 24 20:33:43 2004 @@ -159,7 +159,7 @@ s = a.build_types(snippet.inheritance1, []) # result should be exactly: self.assertEquals(s, annmodel.SomeTuple([ - annmodel.SomeTuple([]), + annmodel.immutablevalue(()), annmodel.SomeInteger() ])) From arigo at codespeak.net Thu Jun 24 21:23:18 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 24 Jun 2004 21:23:18 +0200 (MEST) Subject: [pypy-svn] r5277 - pypy/trunk/src/pypy/translator/test Message-ID: <20040624192318.1D1835A96A@thoth.codespeak.net> Author: arigo Date: Thu Jun 24 21:23:17 2004 New Revision: 5277 Modified: pypy/trunk/src/pypy/translator/test/test_pyrextrans.py Log: In-place operators now work, re-enabling a test... Modified: pypy/trunk/src/pypy/translator/test/test_pyrextrans.py ============================================================================== --- pypy/trunk/src/pypy/translator/test/test_pyrextrans.py (original) +++ pypy/trunk/src/pypy/translator/test/test_pyrextrans.py Thu Jun 24 21:23:17 2004 @@ -131,7 +131,7 @@ nested_whiles = self.getcompiled(snippet.nested_whiles) self.assertEquals(nested_whiles(5,3), '!!!!!') - def xxxtest_call_five(self): + def test_call_five(self): call_five = self.getcompiled(snippet.call_five) self.assertEquals(call_five(), [5]) From arigo at codespeak.net Fri Jun 25 12:33:19 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 12:33:19 +0200 (MEST) Subject: [pypy-svn] r5280 - pypy/trunk/src/pypy/objspace/flow/test Message-ID: <20040625103319.B63B15AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 12:33:18 2004 New Revision: 5280 Modified: pypy/trunk/src/pypy/objspace/flow/test/test_model.py Log: Commented out a print. Modified: pypy/trunk/src/pypy/objspace/flow/test/test_model.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/test_model.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/test_model.py Fri Jun 25 12:33:18 2004 @@ -23,7 +23,7 @@ def test_simplefunc(self): graph = self.getflow(self.simplefunc) l = flatten(graph) - print l + #print l self.assertEquals(len(l), 4) def test_class(self): From arigo at codespeak.net Fri Jun 25 12:34:56 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 12:34:56 +0200 (MEST) Subject: [pypy-svn] r5281 - in pypy/trunk/src/pypy/objspace: . std Message-ID: <20040625103456.5EE155AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 12:34:55 2004 New Revision: 5281 Modified: pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/trivial.py Log: space.get(w_descr,w_obj,w_type) third argument is now optional. It is computed as space.type(w_obj) only if needed: simplification and minor speed-up. Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Fri Jun 25 12:34:55 2004 @@ -9,7 +9,7 @@ w_descr = space.lookup(w_obj, name) if w_descr is not None: if space.is_data_descr(w_descr): - return space.get(w_descr,w_obj,space.type(w_obj)) + return space.get(w_descr,w_obj) w_dict = space.getdict(w_obj) if w_dict is not None: try: @@ -18,7 +18,7 @@ if not e.match(space,space.w_KeyError): raise if w_descr is not None: - return space.get(w_descr,w_obj,space.type(w_obj)) + return space.get(w_descr,w_obj) raise OperationError(space.w_AttributeError,w_name) def descr__setattr__(space, w_obj, w_name, w_value): @@ -67,7 +67,7 @@ w_args = space.newtuple(args_w) return descr.call(w_args, w_kwargs) else: - w_impl = space.get(w_descr, w_obj, space.type(w_obj)) + w_impl = space.get(w_descr, w_obj) return space.call(w_impl, w_args, w_kwargs) def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w): @@ -80,7 +80,7 @@ for key, w_item in kwargs_w]) return descr.call(w_args, w_kwargs) else: - w_impl = space.get(w_descr, w_obj, space.type(w_obj)) + w_impl = space.get(w_descr, w_obj) return space.call_function(w_impl, *args_w, **kwargs_w) def unwrap_builtin(self, w_obj): @@ -94,10 +94,12 @@ space.wrap('object %r is not callable' % (w_obj,))) return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) - def get(space,w_descr,w_obj,w_type): + def get(space,w_descr,w_obj,w_type=None): w_get = space.lookup(w_descr,'__get__') if w_get is None: return w_descr + if w_type is None: + w_type = space.type(w_obj) return space.get_and_call_function(w_get,w_descr,w_obj,w_type) def set(space,w_descr,w_obj,w_val): 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 Fri Jun 25 12:34:55 2004 @@ -117,13 +117,13 @@ w_descr = space.lookup(w_type, name) if w_descr is not None: if space.is_data_descr(w_descr): - return space.get(w_descr,w_type,space.type(w_type)) + return space.get(w_descr,w_type) w_value = w_type.lookup(name) if w_value is not None: # __get__(None, type): turns e.g. functions into unbound methods return space.get(w_value, space.w_None, w_type) if w_descr is not None: - return space.get(w_descr,w_type,space.type(w_type)) + return space.get(w_descr,w_type) raise OperationError(space.w_AttributeError,w_name) def setattr__Type_ANY_ANY(space, w_type, w_name, w_value): Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 25 12:34:55 2004 @@ -198,7 +198,7 @@ # more generally, defining a property def fget(w_obj, descr=descr, space=self): w_descr = space.wrap(descr) - return space.get(w_descr, w_obj, space.type(w_obj)) + return space.get(w_descr, w_obj) def fset(w_obj, w_value, descr=descr, space=self): w_descr = space.wrap(descr) return space.set(w_descr, w_obj, w_value) From arigo at codespeak.net Fri Jun 25 14:10:45 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 14:10:45 +0200 (MEST) Subject: [pypy-svn] r5289 - in pypy/trunk/src/pypy: annotation interpreter objspace objspace/flow objspace/std translator Message-ID: <20040625121045.1B05F5AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 14:10:44 2004 New Revision: 5289 Modified: pypy/trunk/src/pypy/annotation/factory.py pypy/trunk/src/pypy/annotation/model.py pypy/trunk/src/pypy/annotation/unaryop.py pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/pyopcode.py pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/trivial.py pypy/trunk/src/pypy/translator/annrpython.py pypy/trunk/src/pypy/translator/transform.py Log: Refactoring: space.call_function(w_callable, ...) is now the basic operation, with a real tuple and a real dict with real strings containing wrapped objects. Small dicts with string keys are deemed acceptable for RPython. This avoid quite a lot of packing and unpacking arguments around. It is a simplification and it speeds things up noticeably too. The name 'call_function' is really inappropriate now. It should probably be renamed into 'call' after some time -- right now all tests pass but I'm not entierely confident about not having forgotten some calls to Function.call(), for example. If we want to do that we should first scrap space.call() completely -- which still exists but calls space.call_function() -- and make sure nobody uses it any more. The 'call' multimethod in StdObjSpace still uses the old w_args, w_kwds convention. XXX. Now FlowObjSpace can produce 'simple_call' operations directly when space.call_function() is invoked. It simplifies annotation stuff, too, who can deal with 'simple_call' instead of 'call' operations. A lot of code was commented out and should probably be removed completely. Modified: pypy/trunk/src/pypy/annotation/factory.py ============================================================================== --- pypy/trunk/src/pypy/annotation/factory.py (original) +++ pypy/trunk/src/pypy/annotation/factory.py Fri Jun 25 14:10:44 2004 @@ -128,22 +128,22 @@ class FuncCallFactory: - def pycall(self, func, arglist): - return self.bookkeeper.annotator.recursivecall(func, arglist, self) + def pycall(self, func, *args): + return self.bookkeeper.annotator.recursivecall(func, self, *args) class InstanceFactory(FuncCallFactory): - def create(self, cls, arglist): + def create(self, cls, *args): classdef = self.bookkeeper.getclassdef(cls) classdef.instancefactories[self] = True s_instance = SomeInstance(classdef) # flow into __init__() if the class has got one init = getattr(cls, '__init__', None) if init is not None and init != object.__init__: - self.pycall(init, [s_instance] + arglist) + self.pycall(init, s_instance, *args) else: - assert not arglist, "no __init__ found in %r" % (cls,) + assert not args, "no __init__ found in %r" % (cls,) return s_instance Modified: pypy/trunk/src/pypy/annotation/model.py ============================================================================== --- pypy/trunk/src/pypy/annotation/model.py (original) +++ pypy/trunk/src/pypy/annotation/model.py Fri Jun 25 14:10:44 2004 @@ -174,17 +174,17 @@ else: return SomeObject() -def decode_simple_call(s_args, s_kwds): - s_nbargs = s_args.len() - if not s_nbargs.is_constant(): - return None - nbargs = s_nbargs.const - arglist = [pair(s_args, immutablevalue(j)).getitem() - for j in range(nbargs)] - s_nbkwds = s_kwds.len() - if not s_nbkwds.is_constant() or s_nbkwds.const != 0: - return None # XXX deal with dictionaries with keywords - return arglist +##def decode_simple_call(s_args, s_kwds): +## s_nbargs = s_args.len() +## if not s_nbargs.is_constant(): +## return None +## nbargs = s_nbargs.const +## arglist = [pair(s_args, immutablevalue(j)).getitem() +## for j in range(nbargs)] +## s_nbkwds = s_kwds.len() +## if not s_nbkwds.is_constant() or s_nbkwds.const != 0: +## return None # XXX deal with dictionaries with keywords +## return arglist # ____________________________________________________________ Modified: pypy/trunk/src/pypy/annotation/unaryop.py ============================================================================== --- pypy/trunk/src/pypy/annotation/unaryop.py (original) +++ pypy/trunk/src/pypy/annotation/unaryop.py Fri Jun 25 14:10:44 2004 @@ -9,13 +9,13 @@ from pypy.annotation.model import SomeTuple, SomeImpossibleValue from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeClass from pypy.annotation.model import SomeFunction, SomeMethod, SomeIterator -from pypy.annotation.model import immutablevalue, decode_simple_call +from pypy.annotation.model import immutablevalue from pypy.annotation.model import unionof, set, setunion, missing_operation from pypy.annotation.factory import BlockedInference, getbookkeeper from pypy.annotation.factory import InstanceFactory, FuncCallFactory -UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'call', +UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'simple_call', 'iter', 'next']) for opname in UNARY_OPERATIONS: @@ -117,33 +117,25 @@ class __extend__(SomeBuiltin): - def call(bltn, args, kwds): - # decode the arguments and forward the analysis of this builtin - arglist = decode_simple_call(args, kwds) - if arglist is not None: - if bltn.s_self is not None: - arglist.insert(0, bltn.s_self) - return bltn.analyser(*arglist) + def simple_call(bltn, *args): + if bltn.s_self is not None: + return bltn.analyser(bltn.s_self, *args) else: - return SomeObject() + return bltn.analyser(*args) class __extend__(SomeClass): - def call(cls, args, kwds): - arglist = decode_simple_call(args, kwds) - assert arglist is not None + def simple_call(cls, *args): factory = getbookkeeper().getfactory(InstanceFactory) - return factory.create(cls.cls, arglist) + return factory.create(cls.cls, *args) class __extend__(SomeFunction): - def call(fun, args, kwds): - arglist = decode_simple_call(args, kwds) - assert arglist is not None + def simple_call(fun, *args): factory = getbookkeeper().getfactory(FuncCallFactory) - results = [factory.pycall(func, arglist) for func in fun.funcs] + results = [factory.pycall(func, *args) for func in fun.funcs] return unionof(*results) def classattribute(fun, classdef): # function -> unbound method @@ -157,10 +149,7 @@ class __extend__(SomeMethod): - def call(met, args, kwds): - arglist = decode_simple_call(args, kwds) - #print 'methodcall:', met, arglist - assert arglist is not None + def simple_call(met, *args): factory = getbookkeeper().getfactory(FuncCallFactory) results = [] for func, classdef in met.meths.items(): @@ -168,5 +157,5 @@ s_self = SomeInstance(classdef) classdef.instancefactories[factory] = True # call func(s_self, *arglist) - results.append(factory.pycall(func, [s_self]+arglist)) + results.append(factory.pycall(func, s_self, *args)) return unionof(*results) Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Fri Jun 25 14:10:44 2004 @@ -182,10 +182,35 @@ check_list.extend(exclst) return False - def call_function(self, w_func, *args_w, **kw_w): - w_kw = self.newdict([(self.wrap(k), w_v) for k, w_v in kw_w.iteritems()]) - w_args = self.newtuple(list(args_w)) - return self.call(w_func, w_args, w_kw) + def unpackdictionary(self, w_mapping): + "Turns a wrapped dictionary into a {'string': w_value} dict." + if not self.is_mapping(w_mapping): + raise OperationError(self.w_TypeError, + self.wrap("the keywords must be a dictionary")) + result = {} + for w_key in self.unpackiterable(w_mapping): + key = self.unwrap(w_key) + if not isinstance(key, str): + raise OperationError(self.w_TypeError, + self.wrap("keywords must be strings")) + result[key] = self.getitem(w_mapping, w_key) + return result + + def is_mapping(self, w_mapping): + # XXX extend to detect general mappings + return self.is_true(self.isinstance(w_mapping, self.w_dict)) + + def call(self, w_callable, w_args, w_kwds=None): + "Deprecated. Use call_function() instead." + args_w = self.unpacktuple(w_args) + if w_kwds is None: + return self.call_function(w_callable, *args_w) + else: + kwds_w = self.unpackdictionary(w_kwds) + return self.call_function(w_callable, *args_w, **kwds_w) + +## def call_function(self, w_func, *args_w, **kw_w): +## implemented by subclasses def call_method(self, w_obj, methname, *arg_w, **kw_w): w_meth = self.getattr(w_obj, self.wrap(methname)) @@ -288,7 +313,7 @@ ('contains', 'contains', 2, ['__contains__']), ('iter', 'iter', 1, ['__iter__']), ('next', 'next', 1, ['next']), - ('call', 'call', 3, ['__call__']), +# ('call', 'call', 3, ['__call__']), ('get', 'get', 3, ['__get__']), ('set', 'set', 3, ['__set__']), ('delete', 'delete', 2, ['__delete__']), @@ -352,4 +377,4 @@ # newstring([w_1, w_2,...]) -> w_string from ascii numbers (bytes) # newdict([(w_key,w_value),...]) -> w_dict #newslice(w_start,w_stop,w_step) -> w_slice (any argument may be a real None) -# +# call_function(w_obj,*args_w,**kwds_w) Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Fri Jun 25 14:10:44 2004 @@ -24,93 +24,81 @@ self.defs_w = defs_w # list of w_default's self.w_func_dict = space.newdict([]) - def call(self, w_args, w_kwds=None): - scope_w = self.parse_args(w_args, w_kwds) + def call_function(self, *args_w, **kwds_w): + scope_w = self.parse_args(list(args_w), kwds_w) frame = self.code.create_frame(self.space, self.w_func_globals, self.closure) frame.setfastscope(scope_w) return frame.run() - def parse_args(self, w_args, w_kwds=None): + def parse_args(self, args_w, kwds_w): """ parse args and kwargs to initialize the frame. """ space = self.space signature = self.code.signature() argnames, varargname, kwargname = signature # - # w_args = wrapped sequence of the normal actual parameters - # args_w = the same, as a list of wrapped actual parameters - # w_kwds = wrapped dictionary of keyword parameters or a real None + # args_w = list of the normal actual parameters, wrapped + # kwds_w = real dictionary {'keyword': wrapped parameter} # argnames = list of formal parameter names # scope_w = resulting list of wrapped values # # We try to give error messages following CPython's, which are # very informative. # - if w_kwds is not None: - if space.is_true(w_kwds): - # space.is_true() avoids infinite recursion copy<->parse_args - w_kwargs = space.call_method(w_kwds, "copy") - else: - w_kwargs = None co_argcount = len(argnames) # expected formal arguments, without */** # put as many positional input arguments into place as available - args_w = space.unpacktuple(w_args) scope_w = args_w[:co_argcount] input_argcount = len(scope_w) # check that no keyword argument conflicts with these - if w_kwargs is not None: + if kwds_w: for name in argnames[:input_argcount]: - w_name = space.wrap(name) - if space.is_true(space.contains(w_kwargs, w_name)): + if name in kwds_w: self.raise_argerr_multiple_values(name) + remainingkwds_w = kwds_w.copy() if input_argcount < co_argcount: # not enough args, fill in kwargs or defaults if exists def_first = co_argcount - len(self.defs_w) for i in range(input_argcount, co_argcount): - w_name = space.wrap(argnames[i]) - if (w_kwargs is not None and - space.is_true(space.contains(w_kwargs, w_name))): - scope_w.append(space.getitem(w_kwargs, w_name)) - space.delitem(w_kwargs, w_name) + name = argnames[i] + if name in remainingkwds_w: + scope_w.append(remainingkwds_w[name]) + del remainingkwds_w[name] elif i >= def_first: scope_w.append(self.defs_w[i-def_first]) else: - self.raise_argerr(w_args, w_kwds, False) + self.raise_argerr(args_w, kwds_w, False) # collect extra positional arguments into the *vararg if varargname is not None: scope_w.append(space.newtuple(args_w[co_argcount:])) elif len(args_w) > co_argcount: - self.raise_argerr(w_args, w_kwds, True) + self.raise_argerr(args_w, kwds_w, True) # collect extra keyword arguments into the **kwarg - if w_kwargs: - if kwargname is not None: - # XXX this doesn't check that the keys of kwargs are strings - scope_w.append(w_kwargs) - elif space.is_true(w_kwargs): - self.raise_argerr_unknown_kwds(w_kwds) - else: - if kwargname is not None: - scope_w.append(space.newdict([])) + if kwargname is not None: + w_kwds = space.newdict([(space.wrap(key), w_value) + for key, w_value in remainingkwds_w.items()]) + scope_w.append(w_kwds) + elif remainingkwds_w: + self.raise_argerr_unknown_kwds(remainingkwds_w) return scope_w # helper functions to build error message for the above - def raise_argerr(self, w_args, w_kwds, too_many): + def raise_argerr(self, args_w, kwds_w, too_many): argnames, varargname, kwargname = self.code.signature() - nargs = self.space.unwrap(self.space.len(w_args)) + nargs = len(args_w) n = len(argnames) if n == 0: if kwargname is not None: msg2 = "non-keyword " else: msg2 = "" - nargs += self.space.unwrap(self.space.len(w_kwds)) + nargs += len(kwds_w) msg = "%s() takes no %sargument (%d given)" % ( self.name, msg2, @@ -147,18 +135,15 @@ argname) raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - def raise_argerr_unknown_kwds(self, w_kwds): - nkwds = self.space.unwrap(self.space.len(w_kwds)) - if nkwds == 1: - w_iter = self.space.iter(w_kwds) - w_key = self.space.next(w_iter) + def raise_argerr_unknown_kwds(self, kwds_w): + if len(kwds_w) == 1: msg = "%s() got an unexpected keyword argument '%s'" % ( self.name, - self.space.unwrap(w_key)) + kwds_w.keys()[0]) else: msg = "%s() got %d unexpected keyword arguments" % ( self.name, - nkwds) + len(kwds_w)) raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) def getdict(self): @@ -181,11 +166,7 @@ return wrap(Method(space, wrap(self), None, w_cls)) def descr_function_call(self, *args_w, **kwds_w): - # XXX refactor to avoid unwrapping and rewrapping all around - space = self.space - return self.call(space.newtuple(list(args_w)), - space.newdict([(space.wrap(key), w_item) - for key, w_item in kwds_w.items()])) + return self.call_function(*args_w, **kwds_w) def fget_func_defaults(space, w_self): self = space.unwrap(w_self) @@ -218,12 +199,11 @@ self.w_instance = w_instance # or None self.w_class = w_class - def call(self, w_args, w_kwds=None): - args_w = self.space.unpacktuple(w_args) + def call_function(self, *args_w, **kwds_w): if self.w_instance is not None: # bound method - args_w = [self.w_instance] + args_w - w_args = self.space.newtuple(args_w) + return self.space.call_function(self.w_function, self.w_instance, + *args_w, **kwds_w) else: # unbound method if (len(args_w) >= 1 and self.space.is_true( @@ -234,14 +214,10 @@ "instance as first argument") # XXX fix error msg raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - return self.space.call(self.w_function, w_args, w_kwds) + return self.space.call_function(self.w_function, *args_w, **kwds_w) def descr_method_call(self, *args_w, **kwds_w): - # XXX refactor to avoid unwrapping and rewrapping all around - space = self.space - return self.call(space.newtuple(list(args_w)), - space.newdict([(space.wrap(key), w_item) - for key, w_item in kwds_w.items()])) + return self.call_function(*args_w, **kwds_w) class StaticMethod(Wrappable): """A static method. Note that there is one class staticmethod at Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Fri Jun 25 14:10:44 2004 @@ -687,38 +687,28 @@ w_varkw = f.valuestack.pop() if with_varargs: w_varargs = f.valuestack.pop() - keywords = [] + keywords = {} for i in range(n_keywords): w_value = f.valuestack.pop() w_key = f.valuestack.pop() - keywords.append((w_key, w_value)) + key = f.space.unwrap(w_key) # XXX type check: str + keywords[key] = w_value arguments = [f.valuestack.pop() for i in range(n_arguments)] arguments.reverse() w_function = f.valuestack.pop() - w_arguments = f.space.newtuple(arguments) - w_keywords = f.space.newdict(keywords) - if with_varargs: - w_arguments = f.update_star_args(w_arguments, w_varargs) - if with_varkw: - w_keywords = f.update_keyword_args(w_keywords, w_varkw) - w_result = f.space.call(w_function, w_arguments, w_keywords) + if with_varargs: # add the arguments provided by the *args syntax + arguments += tuple(f.space.unpackiterable(w_varargs)) + if with_varkw: # add the arguments provided by the **kwds syntax + kwds_w = f.space.unpackdictionary(w_varkw) + for key, w_value in kwds_w.items(): + if key in keywords: + raise OperationError(f.space.w_TypeError, + f.space.wrap("got multiple values for " + "keyword argument '%s'" % key)) + keywords[key] = w_value + w_result = f.space.call_function(w_function, *arguments, **keywords) f.valuestack.push(w_result) - def app_update_star_args(f, args, extra_args): - return args + tuple(extra_args) - - def app_update_keyword_args(f, kw, extra_kw): - if not isinstance(extra_kw, dict): - raise TypeError, "argument after ** must be a dictionary" - result = kw.copy() - for key, value in extra_kw.items(): - if key in result: - # XXX should mention the function name in error message - raise TypeError, ("got multiple values " - "for keyword argument '%s'" % key) - result[key] = value - return result - def CALL_FUNCTION(f, oparg): f.call_function_extra(oparg, False, False) Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Fri Jun 25 14:10:44 2004 @@ -58,27 +58,23 @@ def is_data_descr(space, w_obj): return space.lookup(w_obj, '__set__') is not None - def get_and_call(space, w_descr, w_obj, w_args, w_kwargs): - descr = space.unwrap_builtin(w_descr) - if isinstance(descr, Function): - # special-case Functions to avoid infinite recursion - args_w = space.unpacktuple(w_args) - args_w = [w_obj] + args_w - w_args = space.newtuple(args_w) - return descr.call(w_args, w_kwargs) - else: - w_impl = space.get(w_descr, w_obj) - return space.call(w_impl, w_args, w_kwargs) +## def get_and_call(space, w_descr, w_obj, w_args, w_kwargs): +## descr = space.unwrap_builtin(w_descr) +## if isinstance(descr, Function): +## # special-case Functions to avoid infinite recursion +## args_w = space.unpacktuple(w_args) +## args_w = [w_obj] + args_w +## w_args = space.newtuple(args_w) +## return descr.call(w_args, w_kwargs) +## else: +## w_impl = space.get(w_descr, w_obj) +## return space.call(w_impl, w_args, w_kwargs) def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w): descr = space.unwrap_builtin(w_descr) if isinstance(descr, Function): # special-case Functions to avoid infinite recursion - args_w = [w_obj] + list(args_w) - w_args = space.newtuple(args_w) - w_kwargs = space.newdict([(space.wrap(key), w_item) - for key, w_item in kwargs_w]) - return descr.call(w_args, w_kwargs) + return descr.call_function(w_obj, *args_w, **kwargs_w) else: w_impl = space.get(w_descr, w_obj) return space.call_function(w_impl, *args_w, **kwargs_w) @@ -86,13 +82,20 @@ def unwrap_builtin(self, w_obj): return w_obj # hook for hack by TrivialObjSpace - def call(space, w_obj, w_args, w_kwargs): - #print "call %r, %r, %r" %(w_obj, w_args, w_kwargs) +## def call(space, w_obj, w_args, w_kwargs): +## #print "call %r, %r, %r" %(w_obj, w_args, w_kwargs) +## w_descr = space.lookup(w_obj, '__call__') +## if w_descr is None: +## raise OperationError(space.w_TypeError, +## space.wrap('object %r is not callable' % (w_obj,))) +## return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) + + def call_function(space, w_obj, *args_w, **kwds_w): w_descr = space.lookup(w_obj, '__call__') if w_descr is None: raise OperationError(space.w_TypeError, - space.wrap('object %r is not callable' % (w_obj,))) - return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) + space.wrap('object %r is not callable' % (w_obj,))) + return space.get_and_call_function(w_descr, w_obj, *args_w, **kwds_w) def get(space,w_descr,w_obj,w_type=None): w_get = space.lookup(w_descr,'__get__') Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Fri Jun 25 14:10:44 2004 @@ -147,6 +147,10 @@ else: return w_item + def call_function(self, w_callable, *args_w, **kwds_w): + assert not kwds_w, "don't know yet about keyword arguments" + return self.do_operation('simple_call', w_callable, *args_w) + # ______________________________________________________________________ implicit_exceptions = { Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Fri Jun 25 14:10:44 2004 @@ -16,14 +16,12 @@ self.space = space self.cpyfunc = cpyfunc - def call(self, w_args, w_kwds): + def call_function(self, *args_w, **kwds_w): space = self.space try: - args = space.unwrap(w_args) - kwds = {} - keys_w = space.unpackiterable(w_kwds) - for w_key in keys_w: - kwds[space.unwrap(w_key)] = space.unwrap(space.getitem(w_kwds, w_key)) + args = [space.unwrap(w_arg) for w_arg in args_w] + kwds = dict([(key, space.unwrap(w_value)) + for key, w_value in kwds_w.items()]) except UnwrapError, e: raise UnwrapError('calling %s: %s' % (self.cpyfunc, e)) try: @@ -87,9 +85,8 @@ name = exc.__name__ if hasattr(space, 'w_' + name): w_exc = getattr(space, 'w_' + name) - w_value = space.call(w_exc, - space.newtuple([space.wrap(a) for a in value.args]), - space.newdict([])) + 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)) 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 Fri Jun 25 14:10:44 2004 @@ -92,18 +92,18 @@ def call__Type(space, w_type, w_args, w_kwds): args_w = space.unpacktuple(w_args) + kwds_w = space.unpackdictionary(w_kwds) # special case for type(x) if (space.is_true(space.is_(w_type, space.w_type)) and - len(args_w) == 1 and not space.is_true(w_kwds)): + len(args_w) == 1 and not kwds_w): return space.type(args_w[0]) # invoke the __new__ of the type - w_descr = space.getattr(w_type, space.wrap('__new__')) - w_extendedargs = space.newtuple([w_type] + args_w) - w_newobject = space.call(w_descr, w_extendedargs, w_kwds) + w_newfunc = space.getattr(w_type, space.wrap('__new__')) + w_newobject = space.call_function(w_newfunc, w_type, *args_w, **kwds_w) # maybe invoke the __init__ of the type if space.is_true(space.isinstance(w_newobject, w_type)): w_descr = space.lookup(w_newobject, '__init__') - space.get_and_call(w_descr, w_newobject, w_args, w_kwds) + space.get_and_call_function(w_descr, w_newobject, *args_w, **kwds_w) return w_newobject def issubtype__Type_Type(space, w_type1, w_type2): Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 25 14:10:44 2004 @@ -479,18 +479,18 @@ return cls.__dict__[name] return None - def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): - if isinstance(w_descr, CPyWrapper): - return DescrOperation.get_and_call(self, w_descr, w_obj, - w_args, w_kwargs) - else: - try: - obj = self.unwrap(w_obj) - if hasattr(w_descr, '__get__'): - obj = w_descr.__get__(obj, type(obj)) - return obj(*w_args, **w_kwargs) - except: - self.reraise() +## def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): +## if isinstance(w_descr, CPyWrapper): +## return DescrOperation.get_and_call(self, w_descr, w_obj, +## w_args, w_kwargs) +## else: +## try: +## obj = self.unwrap(w_obj) +## if hasattr(w_descr, '__get__'): +## obj = w_descr.__get__(obj, type(obj)) +## return obj(*w_args, **w_kwargs) +## except: +## self.reraise() def get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w): if isinstance(w_descr, CPyWrapper): Modified: pypy/trunk/src/pypy/translator/annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/annrpython.py (original) +++ pypy/trunk/src/pypy/translator/annrpython.py Fri Jun 25 14:10:44 2004 @@ -119,7 +119,7 @@ #___ interface for annotator.factory _______ - def recursivecall(self, func, inputcells, factory): + def recursivecall(self, func, factory, *args): graph = self.translator.getflowgraph(func) # self.notify[graph.returnblock] is a dictionary of # FuncCallFactories (call points to this func) which triggers a @@ -128,6 +128,7 @@ callfactories[factory] = True # generalize the function's input arguments block = graph.startblock + inputcells = list(args) assert len(inputcells) == len(block.inputargs) self.addpendingblock(block, inputcells) # get the (current) return value @@ -289,9 +290,9 @@ factory = self.bookkeeper.getfactory(DictFactory) return factory.create() - def decode_simple_call(self, s_varargs, s_varkwds): - # XXX replace all uses of this with direct calls into annmodel - return annmodel.decode_simple_call(s_varargs, s_varkwds) +## def decode_simple_call(self, s_varargs, s_varkwds): +## # XXX replace all uses of this with direct calls into annmodel +## return annmodel.decode_simple_call(s_varargs, s_varkwds) ## def consider_op_call(self, s_func, s_varargs, s_kwargs): ## if not s_func.is_constant(): Modified: pypy/trunk/src/pypy/translator/transform.py ============================================================================== --- pypy/trunk/src/pypy/translator/transform.py (original) +++ pypy/trunk/src/pypy/translator/transform.py Fri Jun 25 14:10:44 2004 @@ -67,34 +67,35 @@ # --> # e = simple_call(a, *b) -def transform_simple_call(self): - """Transforms call(a, (...), {}) to simple_call(a, ...)""" - for block in self.annotated: - known_vars = block.inputargs[:] - operations = [] - for op in block.operations: - try: - if op.opname != 'call': - raise CannotSimplify - varargs_cell = self.binding(op.args[1]) - varkwds_cell = self.binding(op.args[2]) - arg_cells = self.decode_simple_call(varargs_cell, - varkwds_cell) - if arg_cells is None: - raise CannotSimplify - - args = [self.reverse_binding(known_vars, c) for c in arg_cells] - args.insert(0, op.args[0]) - new_ops = [SpaceOperation('simple_call', args, op.result)] +## REMOVED: now FlowObjSpace produces 'simple_call' operations only +##def transform_simple_call(self): +## """Transforms call(a, (...), {}) to simple_call(a, ...)""" +## for block in self.annotated: +## known_vars = block.inputargs[:] +## operations = [] +## for op in block.operations: +## try: +## if op.opname != 'call': +## raise CannotSimplify +## varargs_cell = self.binding(op.args[1]) +## varkwds_cell = self.binding(op.args[2]) +## arg_cells = self.decode_simple_call(varargs_cell, +## varkwds_cell) +## if arg_cells is None: +## raise CannotSimplify + +## args = [self.reverse_binding(known_vars, c) for c in arg_cells] +## args.insert(0, op.args[0]) +## new_ops = [SpaceOperation('simple_call', args, op.result)] - except CannotSimplify: - new_ops = [op] +## except CannotSimplify: +## new_ops = [op] - for op in new_ops: - operations.append(op) - known_vars.append(op.result) +## for op in new_ops: +## operations.append(op) +## known_vars.append(op.result) - block.operations = operations +## block.operations = operations def transform_dead_op_vars(self): """Remove dead operations and variables that are passed over a link @@ -172,7 +173,6 @@ """Apply set of transformations available.""" transform_allocate(ann) transform_slice(ann) - transform_simple_call(ann) # do this last, after the previous transformations had a # chance to remove dependency on certain variables transform_dead_op_vars(ann) From arigo at codespeak.net Fri Jun 25 14:11:12 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 14:11:12 +0200 (MEST) Subject: [pypy-svn] r5290 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040625121112.412E15B54F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 14:11:11 2004 New Revision: 5290 Modified: pypy/trunk/src/pypy/objspace/std/stdtypedef.py Log: Forgot to check this comment it. Modified: pypy/trunk/src/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/stdtypedef.py (original) +++ pypy/trunk/src/pypy/objspace/std/stdtypedef.py Fri Jun 25 14:11:11 2004 @@ -122,6 +122,8 @@ self.framecls = framecls argnames = ['x%d'%(i+1) for i in range(multimethod.arity)] varargname = kwargname = None + # XXX do something about __call__ and __init__ which still use + # XXX packed arguments: w_args, w_kwds instead of *args_w, **kwds_w if multimethod.extras.get('varargs', False): varargname = 'args' if multimethod.extras.get('keywords', False): From arigo at codespeak.net Fri Jun 25 14:34:33 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 14:34:33 +0200 (MEST) Subject: [pypy-svn] r5292 - pypy/trunk/src/pypy/interpreter/test Message-ID: <20040625123433.49CFF5AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 14:34:32 2004 New Revision: 5292 Modified: pypy/trunk/src/pypy/interpreter/test/test_function.py Log: Uh oh. There is a problem with the ** arguments passed all around, as shown by this failing test... 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 Jun 25 14:34:32 2004 @@ -123,6 +123,12 @@ return arg1, kw self.assertRaises(TypeError, func, 42, **{'arg1': 23}) + def test_kwargs_confusing_name(self): + def func(self): # 'self' conflicts with the interp-level + return self*7 # argument to call_function() + res = func(self=6) + self.assertEquals(res, 42) + class TestMethod(testit.IntTestCase): def setUp(self): From arigo at codespeak.net Fri Jun 25 16:06:59 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 16:06:59 +0200 (MEST) Subject: [pypy-svn] r5298 - in pypy/trunk/src/pypy: interpreter/test module/test objspace/std/test Message-ID: <20040625140659.F39E55AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 16:06:59 2004 New Revision: 5298 Modified: pypy/trunk/src/pypy/interpreter/test/test_interpreter.py pypy/trunk/src/pypy/module/test/test_builtin.py pypy/trunk/src/pypy/objspace/std/test/test_cpythonobject.py Log: Converted a few space.call() to space.call_function(). Modified: pypy/trunk/src/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_interpreter.py Fri Jun 25 16:06:59 2004 @@ -23,11 +23,10 @@ code = space.unwrap(w_code) code.exec_code(space, w_glob, w_glob) - wrappedargs = space.newtuple([w(a) for a in args]) + wrappedargs = [w(a) for a in args] wrappedfunc = space.getitem(w_glob, w(functionname)) - wrappedkwds = space.newdict([]) try: - w_output = space.call(wrappedfunc, wrappedargs, wrappedkwds) + w_output = space.call_function(wrappedfunc, *wrappedargs) except baseobjspace.OperationError, e: #e.print_detailed_traceback(space) return '<<<%s>>>' % e.errorstr(space) 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 Fri Jun 25 16:06:59 2004 @@ -262,8 +262,8 @@ w_execfile = self.get_builtin('execfile') space = self.space w_dict = space.newdict([]) - self.space.call(w_execfile, space.newtuple([ - space.wrap(fn), w_dict, space.w_None]), space.newdict([])) + self.space.call_function(w_execfile, + space.wrap(fn), w_dict, space.w_None) w_value = space.getitem(w_dict, space.wrap('i')) self.assertEqual_w(w_value, space.wrap(42)) finally: Modified: pypy/trunk/src/pypy/objspace/std/test/test_cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_cpythonobject.py Fri Jun 25 16:06:59 2004 @@ -78,8 +78,7 @@ def test_call(self): w1 = self.space.wrap(len) - w_result = self.space.call(w1, self.space.wrap(("hello world",)), - self.space.wrap({})) + w_result = self.space.call_function(w1, self.space.wrap("hello world")) self.assertEquals(self.space.unwrap(w_result), 11) def test_next(self): From arigo at codespeak.net Fri Jun 25 17:00:10 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 17:00:10 +0200 (MEST) Subject: [pypy-svn] r5300 - in pypy/trunk/src/pypy: interpreter objspace objspace/flow objspace/std Message-ID: <20040625150010.89F095AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 17:00:08 2004 New Revision: 5300 Added: pypy/trunk/src/pypy/interpreter/argument.py (contents, props changed) Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/pyopcode.py pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/typeobject.py pypy/trunk/src/pypy/objspace/trivial.py Log: First steps in the direction of a cleaner argument handling scheme. There is now a class pypy.interpreter.argument.Arguments that holds the arguments of a Python call. All operations on them (joining & parsing) are now there. The official calling interface is now space.call_args(w_callable, args) with space.call_function still available as a thin helper (but no keyword arguments in space.call_function() please). We should scrap space.call() now. Work in progress: the app2interp gateways should use arguments of this kind instead of interp-level */** arguments; the multimethods as well. Added: pypy/trunk/src/pypy/interpreter/argument.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/interpreter/argument.py Fri Jun 25 17:00:08 2004 @@ -0,0 +1,191 @@ +""" +Arguments objects. +""" + +from pypy.interpreter.error import OperationError + + +class Arguments: + """ + Collects the arguments of a function call. + + Instances should be considered immutable. + """ + + ### Construction ### + + def __init__(self, space, args_w=[], kwds_w={}): + self.space = space + self.args_w = args_w + self.kwds_w = kwds_w + + def frompacked(space, w_args=None, w_kwds=None): + """Static method to build an Arguments + from a wrapped sequence and optionally a wrapped dictionary. + """ + if w_args is None: + args_w = [] + else: + args_w = space.unpackiterable(w_args) + if w_kwds is None: + return Arguments(space, args_w) + # maybe we could allow general mappings? + if not space.is_true(space.isinstance(w_kwds, space.w_dict)): + raise OperationError(space.w_TypeError, + space.wrap("the keywords must be " + "a dictionary")) + kwds_w = {} + for w_key in space.unpackiterable(w_kwds): + key = space.unwrap(w_key) + if not isinstance(key, str): + raise OperationError(space.w_TypeError, + space.wrap("keywords must be strings")) + kwds_w[key] = space.getitem(w_kwds, w_key) + return Arguments(space, args_w, kwds_w) + frompacked = staticmethod(frompacked) + + ### Manipulation ### + + def prepend(self, w_firstarg): + "Return a new Arguments with a new argument inserted first." + return Arguments(self.space, [w_firstarg] + self.args_w, self.kwds_w) + + def join(self, other): + "Return a new Arguments combining the content of two Arguments." + args_w = self.args_w + other.args_w + kwds_w = self.kwds_w.copy() + for key, w_value in other.kwds_w.items(): + if key in kwds_w: + raise OperationError(self.space.w_TypeError, + self.space.wrap("got multiple values for " + "keyword argument '%s'" % + key)) + kwds_w[key] = w_value + return Arguments(self.space, args_w, kwds_w) + + def pack(self): + "Return a (wrapped tuple, wrapped dictionary)." + space = self.space + w_args = space.newtuple(self.args_w) + w_kwds = space.newdict([(space.wrap(key), w_value) + for key, w_value in self.kwds_w.items()]) + return w_args, w_kwds + + ### Parsing for function calls ### + + def parse(self, fnname, signature, defaults_w=[]): + """Parse args and kwargs to initialize a frame + according to the signature of code object. + """ + space = self.space + args_w = self.args_w + kwds_w = self.kwds_w + argnames, varargname, kwargname = signature + # + # args_w = list of the normal actual parameters, wrapped + # kwds_w = real dictionary {'keyword': wrapped parameter} + # argnames = list of formal parameter names + # scope_w = resulting list of wrapped values + # + # We try to give error messages following CPython's, which are + # very informative. + # + co_argcount = len(argnames) # expected formal arguments, without */** + + # put as many positional input arguments into place as available + scope_w = args_w[:co_argcount] + input_argcount = len(scope_w) + + # check that no keyword argument conflicts with these + if kwds_w: + for name in argnames[:input_argcount]: + if name in kwds_w: + self.raise_argerr_multiple_values(fnname, name) + + remainingkwds_w = kwds_w.copy() + if input_argcount < co_argcount: + # not enough args, fill in kwargs or defaults if exists + def_first = co_argcount - len(defaults_w) + for i in range(input_argcount, co_argcount): + name = argnames[i] + if name in remainingkwds_w: + scope_w.append(remainingkwds_w[name]) + del remainingkwds_w[name] + elif i >= def_first: + scope_w.append(defaults_w[i-def_first]) + else: + self.raise_argerr(fnname, signature, defaults_w, False) + + # collect extra positional arguments into the *vararg + if varargname is not None: + scope_w.append(space.newtuple(args_w[co_argcount:])) + elif len(args_w) > co_argcount: + self.raise_argerr(fnname, signature, defaults_w, True) + + # collect extra keyword arguments into the **kwarg + if kwargname is not None: + w_kwds = space.newdict([(space.wrap(key), w_value) + for key, w_value in remainingkwds_w.items()]) + scope_w.append(w_kwds) + elif remainingkwds_w: + self.raise_argerr_unknown_kwds(fnname, remainingkwds_w) + return scope_w + + # helper functions to build error message for the above + + def raise_argerr(self, fnname, signature, defaults_w, too_many): + argnames, varargname, kwargname = signature + nargs = len(self.args_w) + n = len(argnames) + if n == 0: + if kwargname is not None: + msg2 = "non-keyword " + else: + msg2 = "" + nargs += len(self.kwds_w) + msg = "%s() takes no %sargument (%d given)" % ( + fnname, + msg2, + nargs) + else: + defcount = len(defaults_w) + if defcount == 0: + msg1 = "exactly" + elif too_many: + msg1 = "at most" + else: + msg1 = "at least" + n -= defcount + if kwargname is not None: + msg2 = "non-keyword " + else: + msg2 = "" + if n == 1: + plural = "" + else: + plural = "s" + msg = "%s() takes %s %d %sargument%s (%d given)" % ( + fnname, + msg1, + n, + msg2, + plural, + nargs) + raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) + + def raise_argerr_multiple_values(self, fnname, argname): + msg = "%s() got multiple values for keyword argument %s" % ( + fnname, + argname) + raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) + + def raise_argerr_unknown_kwds(self, fnname, kwds_w): + if len(kwds_w) == 1: + msg = "%s() got an unexpected keyword argument '%s'" % ( + fnname, + kwds_w.keys()[0]) + else: + msg = "%s() got %d unexpected keyword arguments" % ( + fnname, + len(kwds_w)) + raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Fri Jun 25 17:00:08 2004 @@ -1,6 +1,7 @@ from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.error import OperationError from pypy.interpreter.miscutils import getthreadlocals +from pypy.interpreter.argument import Arguments __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable'] @@ -182,39 +183,17 @@ check_list.extend(exclst) return False - def unpackdictionary(self, w_mapping): - "Turns a wrapped dictionary into a {'string': w_value} dict." - if not self.is_mapping(w_mapping): - raise OperationError(self.w_TypeError, - self.wrap("the keywords must be a dictionary")) - result = {} - for w_key in self.unpackiterable(w_mapping): - key = self.unwrap(w_key) - if not isinstance(key, str): - raise OperationError(self.w_TypeError, - self.wrap("keywords must be strings")) - result[key] = self.getitem(w_mapping, w_key) - return result - - def is_mapping(self, w_mapping): - # XXX extend to detect general mappings - return self.is_true(self.isinstance(w_mapping, self.w_dict)) - def call(self, w_callable, w_args, w_kwds=None): - "Deprecated. Use call_function() instead." - args_w = self.unpacktuple(w_args) - if w_kwds is None: - return self.call_function(w_callable, *args_w) - else: - kwds_w = self.unpackdictionary(w_kwds) - return self.call_function(w_callable, *args_w, **kwds_w) + args = Arguments.frompacked(self, w_args, w_kwds) + return self.call_args(w_callable, args) -## def call_function(self, w_func, *args_w, **kw_w): -## implemented by subclasses + def call_function(self, w_func, *args_w): + args = Arguments(self, list(args_w)) + return self.call_args(w_func, args) - def call_method(self, w_obj, methname, *arg_w, **kw_w): + def call_method(self, w_obj, methname, *arg_w): w_meth = self.getattr(w_obj, self.wrap(methname)) - return self.call_function(w_meth, *arg_w, **kw_w) + return self.call_function(w_meth, *arg_w) def isinstance(self, w_obj, w_type): w_objtype = self.type(w_obj) @@ -377,4 +356,4 @@ # newstring([w_1, w_2,...]) -> w_string from ascii numbers (bytes) # newdict([(w_key,w_value),...]) -> w_dict #newslice(w_start,w_stop,w_step) -> w_slice (any argument may be a real None) -# call_function(w_obj,*args_w,**kwds_w) +# call_args(w_obj,Arguments()) -> w_result Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Fri Jun 25 17:00:08 2004 @@ -8,6 +8,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.argument import Arguments class Function(Wrappable): """A function is a code object captured with some environment: @@ -24,128 +25,13 @@ self.defs_w = defs_w # list of w_default's self.w_func_dict = space.newdict([]) - def call_function(self, *args_w, **kwds_w): - scope_w = self.parse_args(list(args_w), kwds_w) + def call_args(self, args): + scope_w = args.parse(self.name, self.code.signature(), self.defs_w) frame = self.code.create_frame(self.space, self.w_func_globals, self.closure) frame.setfastscope(scope_w) return frame.run() - def parse_args(self, args_w, kwds_w): - """ parse args and kwargs to initialize the frame. - """ - space = self.space - signature = self.code.signature() - argnames, varargname, kwargname = signature - # - # args_w = list of the normal actual parameters, wrapped - # kwds_w = real dictionary {'keyword': wrapped parameter} - # argnames = list of formal parameter names - # scope_w = resulting list of wrapped values - # - # We try to give error messages following CPython's, which are - # very informative. - # - co_argcount = len(argnames) # expected formal arguments, without */** - - # put as many positional input arguments into place as available - scope_w = args_w[:co_argcount] - input_argcount = len(scope_w) - - # check that no keyword argument conflicts with these - if kwds_w: - for name in argnames[:input_argcount]: - if name in kwds_w: - self.raise_argerr_multiple_values(name) - - remainingkwds_w = kwds_w.copy() - if input_argcount < co_argcount: - # not enough args, fill in kwargs or defaults if exists - def_first = co_argcount - len(self.defs_w) - for i in range(input_argcount, co_argcount): - name = argnames[i] - if name in remainingkwds_w: - scope_w.append(remainingkwds_w[name]) - del remainingkwds_w[name] - elif i >= def_first: - scope_w.append(self.defs_w[i-def_first]) - else: - self.raise_argerr(args_w, kwds_w, False) - - # collect extra positional arguments into the *vararg - if varargname is not None: - scope_w.append(space.newtuple(args_w[co_argcount:])) - elif len(args_w) > co_argcount: - self.raise_argerr(args_w, kwds_w, True) - - # collect extra keyword arguments into the **kwarg - if kwargname is not None: - w_kwds = space.newdict([(space.wrap(key), w_value) - for key, w_value in remainingkwds_w.items()]) - scope_w.append(w_kwds) - elif remainingkwds_w: - self.raise_argerr_unknown_kwds(remainingkwds_w) - return scope_w - - # helper functions to build error message for the above - - def raise_argerr(self, args_w, kwds_w, too_many): - argnames, varargname, kwargname = self.code.signature() - nargs = len(args_w) - n = len(argnames) - if n == 0: - if kwargname is not None: - msg2 = "non-keyword " - else: - msg2 = "" - nargs += len(kwds_w) - msg = "%s() takes no %sargument (%d given)" % ( - self.name, - msg2, - nargs) - else: - defcount = len(self.defs_w) - if defcount == 0: - msg1 = "exactly" - elif too_many: - msg1 = "at most" - else: - msg1 = "at least" - n -= defcount - if kwargname is not None: - msg2 = "non-keyword " - else: - msg2 = "" - if n == 1: - plural = "" - else: - plural = "s" - msg = "%s() takes %s %d %sargument%s (%d given)" % ( - self.name, - msg1, - n, - msg2, - plural, - nargs) - raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - - def raise_argerr_multiple_values(self, argname): - msg = "%s() got multiple values for keyword argument %s" % ( - self.name, - argname) - raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - - def raise_argerr_unknown_kwds(self, kwds_w): - if len(kwds_w) == 1: - msg = "%s() got an unexpected keyword argument '%s'" % ( - self.name, - kwds_w.keys()[0]) - else: - msg = "%s() got %d unexpected keyword arguments" % ( - self.name, - len(kwds_w)) - raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - def getdict(self): return self.w_func_dict @@ -166,7 +52,9 @@ return wrap(Method(space, wrap(self), None, w_cls)) def descr_function_call(self, *args_w, **kwds_w): - return self.call_function(*args_w, **kwds_w) + # XXX the Gateway interface should not use interp-level */** + # XXX arguments -- conflict with 'self'! + return self.call_args(Arguments(self.space, list(args_w), kwds_w)) def fget_func_defaults(space, w_self): self = space.unwrap(w_self) @@ -199,25 +87,25 @@ self.w_instance = w_instance # or None self.w_class = w_class - def call_function(self, *args_w, **kwds_w): + def call_args(self, args): if self.w_instance is not None: # bound method - return self.space.call_function(self.w_function, self.w_instance, - *args_w, **kwds_w) + args = args.prepend(self.w_instance) else: # unbound method - if (len(args_w) >= 1 and self.space.is_true( - self.space.isinstance(args_w[0], self.w_class))): + if (len(args.args_w) >= 1 and self.space.is_true( + self.space.isinstance(args.args_w[0], self.w_class))): pass # ok else: msg = ("unbound method must be called with " "instance as first argument") # XXX fix error msg raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) - return self.space.call_function(self.w_function, *args_w, **kwds_w) + return self.space.call_args(self.w_function, args) def descr_method_call(self, *args_w, **kwds_w): - return self.call_function(*args_w, **kwds_w) + # XXX same as descr_function_call() + return self.call_args(Arguments(self.space, list(args_w), kwds_w)) class StaticMethod(Wrappable): """A static method. Note that there is one class staticmethod at Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Fri Jun 25 17:00:08 2004 @@ -9,6 +9,7 @@ from pypy.interpreter import gateway, function from pypy.interpreter import pyframe, pytraceback from pypy.interpreter.miscutils import InitializedClass +from pypy.interpreter.argument import Arguments class unaryoperation: @@ -680,13 +681,9 @@ block = pyframe.FinallyBlock(f, f.next_instr + offsettoend) f.blockstack.push(block) - def call_function_extra(f, oparg, with_varargs, with_varkw): + def CALL_FUNCTION(f, oparg, extra_args=None): n_arguments = oparg & 0xff n_keywords = (oparg>>8) & 0xff - if with_varkw: - w_varkw = f.valuestack.pop() - if with_varargs: - w_varargs = f.valuestack.pop() keywords = {} for i in range(n_keywords): w_value = f.valuestack.pop() @@ -695,31 +692,28 @@ keywords[key] = w_value arguments = [f.valuestack.pop() for i in range(n_arguments)] arguments.reverse() + args = Arguments(f.space, arguments, keywords) + if extra_args: + args = args.join(extra_args) w_function = f.valuestack.pop() - if with_varargs: # add the arguments provided by the *args syntax - arguments += tuple(f.space.unpackiterable(w_varargs)) - if with_varkw: # add the arguments provided by the **kwds syntax - kwds_w = f.space.unpackdictionary(w_varkw) - for key, w_value in kwds_w.items(): - if key in keywords: - raise OperationError(f.space.w_TypeError, - f.space.wrap("got multiple values for " - "keyword argument '%s'" % key)) - keywords[key] = w_value - w_result = f.space.call_function(w_function, *arguments, **keywords) + w_result = f.space.call_args(w_function, args) f.valuestack.push(w_result) - def CALL_FUNCTION(f, oparg): - f.call_function_extra(oparg, False, False) - def CALL_FUNCTION_VAR(f, oparg): - f.call_function_extra(oparg, True, False) + w_varargs = f.valuestack.pop() + extra_args = Arguments.frompacked(f.space, w_varargs) + f.CALL_FUNCTION(oparg, extra_args) def CALL_FUNCTION_KW(f, oparg): - f.call_function_extra(oparg, False, True) + w_varkw = f.valuestack.pop() + extra_args = Arguments.frompacked(f.space, w_kwds=w_varkw) + f.CALL_FUNCTION(oparg, extra_args) def CALL_FUNCTION_VAR_KW(f, oparg): - f.call_function_extra(oparg, True, True) + w_varkw = f.valuestack.pop() + w_varargs = f.valuestack.pop() + extra_args = Arguments.frompacked(f.space, w_varargs, w_varkw) + f.CALL_FUNCTION(oparg, extra_args) def MAKE_FUNCTION(f, numdefaults): w_codeobj = f.valuestack.pop() Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Fri Jun 25 17:00:08 2004 @@ -2,6 +2,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.function import Function +from pypy.interpreter.argument import Arguments class Object: def descr__getattribute__(space, w_obj, w_name): @@ -58,26 +59,18 @@ def is_data_descr(space, w_obj): return space.lookup(w_obj, '__set__') is not None -## def get_and_call(space, w_descr, w_obj, w_args, w_kwargs): -## descr = space.unwrap_builtin(w_descr) -## if isinstance(descr, Function): -## # special-case Functions to avoid infinite recursion -## args_w = space.unpacktuple(w_args) -## args_w = [w_obj] + args_w -## w_args = space.newtuple(args_w) -## return descr.call(w_args, w_kwargs) -## else: -## w_impl = space.get(w_descr, w_obj) -## return space.call(w_impl, w_args, w_kwargs) - - def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w): + def get_and_call_args(space, w_descr, w_obj, args): descr = space.unwrap_builtin(w_descr) if isinstance(descr, Function): # special-case Functions to avoid infinite recursion - return descr.call_function(w_obj, *args_w, **kwargs_w) + return descr.call_args(args.prepend(w_obj)) else: w_impl = space.get(w_descr, w_obj) - return space.call_function(w_impl, *args_w, **kwargs_w) + return space.call_args(w_impl, args) + + def get_and_call_function(space, w_descr, w_obj, *args_w): + args = Arguments(space, list(args_w)) + return space.get_and_call_args(w_descr, w_obj, args) def unwrap_builtin(self, w_obj): return w_obj # hook for hack by TrivialObjSpace @@ -90,12 +83,12 @@ ## space.wrap('object %r is not callable' % (w_obj,))) ## return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) - def call_function(space, w_obj, *args_w, **kwds_w): + def call_args(space, w_obj, args): w_descr = space.lookup(w_obj, '__call__') if w_descr is None: raise OperationError(space.w_TypeError, space.wrap('object %r is not callable' % (w_obj,))) - return space.get_and_call_function(w_descr, w_obj, *args_w, **kwds_w) + return space.get_and_call_args(w_descr, w_obj, args) def get(space,w_descr,w_obj,w_type=None): w_get = space.lookup(w_descr,'__get__') Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Fri Jun 25 17:00:08 2004 @@ -147,9 +147,12 @@ else: return w_item - def call_function(self, w_callable, *args_w, **kwds_w): - assert not kwds_w, "don't know yet about keyword arguments" - return self.do_operation('simple_call', w_callable, *args_w) + def call_args(self, w_callable, args): + if args.kwds_w: + w_args, w_kwds = args.pack() + return self.do_operation('call', w_callable, w_args, w_kwds) + else: + return self.do_operation('simple_call', w_callable, *args.args_w) # ______________________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Fri Jun 25 17:00:08 2004 @@ -16,16 +16,16 @@ self.space = space self.cpyfunc = cpyfunc - def call_function(self, *args_w, **kwds_w): + def call_args(self, args): space = self.space try: - args = [space.unwrap(w_arg) for w_arg in args_w] - kwds = dict([(key, space.unwrap(w_value)) - for key, w_value in kwds_w.items()]) + 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, args, kwds) + result = apply(self.cpyfunc, unwrappedargs, unwrappedkwds) except: wrap_exception(space) return space.wrap(result) 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 Fri Jun 25 17:00:08 2004 @@ -1,6 +1,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter.typedef import default_dict_descr +from pypy.interpreter.argument import Arguments from pypy.objspace.std.stdtypedef import issubtypedef from pypy.objspace.std.objecttype import object_typedef @@ -91,19 +92,18 @@ def call__Type(space, w_type, w_args, w_kwds): - args_w = space.unpacktuple(w_args) - kwds_w = space.unpackdictionary(w_kwds) + args = Arguments.frompacked(space, w_args, w_kwds) # special case for type(x) if (space.is_true(space.is_(w_type, space.w_type)) and - len(args_w) == 1 and not kwds_w): - return space.type(args_w[0]) + len(args.args_w) == 1 and not args.kwds_w): + return space.type(args.args_w[0]) # invoke the __new__ of the type w_newfunc = space.getattr(w_type, space.wrap('__new__')) - w_newobject = space.call_function(w_newfunc, w_type, *args_w, **kwds_w) + w_newobject = space.call_args(w_newfunc, args.prepend(w_type)) # maybe invoke the __init__ of the type if space.is_true(space.isinstance(w_newobject, w_type)): w_descr = space.lookup(w_newobject, '__init__') - space.get_and_call_function(w_descr, w_newobject, *args_w, **kwds_w) + space.get_and_call_args(w_descr, w_newobject, args) return w_newobject def issubtype__Type_Type(space, w_type1, w_type2): Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 25 17:00:08 2004 @@ -479,29 +479,15 @@ return cls.__dict__[name] return None -## def get_and_call(self, w_descr, w_obj, w_args, w_kwargs): -## if isinstance(w_descr, CPyWrapper): -## return DescrOperation.get_and_call(self, w_descr, w_obj, -## w_args, w_kwargs) -## else: -## try: -## obj = self.unwrap(w_obj) -## if hasattr(w_descr, '__get__'): -## obj = w_descr.__get__(obj, type(obj)) -## return obj(*w_args, **w_kwargs) -## except: -## self.reraise() - - def get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w): + def get_and_call_args(self, w_descr, w_obj, args): if isinstance(w_descr, CPyWrapper): - return DescrOperation.get_and_call_function(self, w_descr, w_obj, - *args_w, **kwargs_w) + return DescrOperation.get_and_call_args(self, w_descr, w_obj, args) else: try: obj = self.unwrap(w_obj) if hasattr(w_descr, '__get__'): obj = w_descr.__get__(obj, type(obj)) - return obj(*args_w, **kwargs_w) + return obj(*args.args_w, **args.kwds_w) except: #import traceback; traceback.print_exc() self.reraise() From arigo at codespeak.net Fri Jun 25 18:25:39 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 18:25:39 +0200 (MEST) Subject: [pypy-svn] r5309 - in pypy/trunk/src/pypy: interpreter interpreter/test objspace objspace/std Message-ID: <20040625162539.701835AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 18:25:37 2004 New Revision: 5309 Modified: pypy/trunk/src/pypy/interpreter/argument.py pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/module.py pypy/trunk/src/pypy/interpreter/test/test_function.py pypy/trunk/src/pypy/interpreter/test/test_gateway.py pypy/trunk/src/pypy/objspace/descroperation.py pypy/trunk/src/pypy/objspace/std/dicttype.py pypy/trunk/src/pypy/objspace/std/listtype.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/trivial.py Log: Gateway cleanups: trying to remove interpreter-level ** arguments. Now interp2app(f) no longer accepts interp-level functions with **. Instead, the signature of f should either end with a * argument, or with an argument called __args__ (hum). In the latter case, the app-level version of f appears to have a * and a ** argument, and the interp-level version will get all that nicely collected in an pypy.interpreter.argument.Arguments instance. Hum, the goal was to solve the problem in the failing test, but it still fails. See mail to pypy-dev "fun with functions". Modified: pypy/trunk/src/pypy/interpreter/argument.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/argument.py (original) +++ pypy/trunk/src/pypy/interpreter/argument.py Fri Jun 25 18:25:37 2004 @@ -15,6 +15,8 @@ ### Construction ### def __init__(self, space, args_w=[], kwds_w={}): + assert isinstance(args_w, list) # I keep forgetting the 'space' + assert isinstance(kwds_w, dict) # argument so hopefully this helps self.space = space self.args_w = args_w self.kwds_w = kwds_w Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Fri Jun 25 18:25:37 2004 @@ -32,6 +32,9 @@ frame.setfastscope(scope_w) return frame.run() + def interplevel_call(self, *args_w): + return self.call_args(Arguments(self.space, list(args_w))) + def getdict(self): return self.w_func_dict @@ -51,10 +54,8 @@ else: return wrap(Method(space, wrap(self), None, w_cls)) - def descr_function_call(self, *args_w, **kwds_w): - # XXX the Gateway interface should not use interp-level */** - # XXX arguments -- conflict with 'self'! - return self.call_args(Arguments(self.space, list(args_w), kwds_w)) + def descr_function_call(self, __args__): + return self.call_args(__args__) def fget_func_defaults(space, w_self): self = space.unwrap(w_self) @@ -103,9 +104,11 @@ self.space.wrap(msg)) return self.space.call_args(self.w_function, args) - def descr_method_call(self, *args_w, **kwds_w): - # XXX same as descr_function_call() - return self.call_args(Arguments(self.space, list(args_w), kwds_w)) + def interplevel_call(self, *args_w): + return self.call_args(Arguments(self.space, list(args_w))) + + def descr_method_call(self, __args__): + return self.call_args(__args__) class StaticMethod(Wrappable): """A static method. Note that there is one class staticmethod at Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Fri Jun 25 18:25:37 2004 @@ -14,6 +14,7 @@ from pypy.interpreter import eval, pycode from pypy.interpreter.function import Function, Method from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.argument import Arguments class BuiltinCode(eval.Code): @@ -34,7 +35,8 @@ # Currently we enforce the following signature tricks: # * the first arg must be either 'self' or 'space' # * 'w_' prefixes for the rest - # * '_w' suffixes on * and ** + # * '_w' suffix for the optional '*' argument + # * alternatively a final '__args__' means an Arguments() # Not exactly a clean approach XXX. argnames, varargname, kwargname = tmp.signature() argnames = list(argnames) @@ -47,22 +49,31 @@ self.spacearg = spacearg if spacearg: del argnames[0] - for i in range(ismethod, len(argnames)): - a = argnames[i] - assert a.startswith('w_'), ( - "argument %s of built-in function %r should start with 'w_'" % - (a, func)) - argnames[i] = a[2:] - if varargname is not None: + + assert kwargname is None, ( + "built-in function %r should not take a ** argument" % func) + + self.generalargs = argnames[-1:] == ['__args__'] + self.starargs = varargname is not None + assert not (self.generalargs and self.starargs), ( + "built-in function %r has both __args__ and a * argument" % func) + if self.generalargs: + del argnames[-1] + varargname = "args" + kwargname = "keywords" + elif self.starargs: assert varargname.endswith('_w'), ( "argument *%s of built-in function %r should end in '_w'" % (varargname, func)) varargname = varargname[:-2] - if kwargname is not None: - assert kwargname.endswith('_w'), ( - "argument **%s of built-in function %r should end in '_w'" % - (kwargname, func)) - kwargname = kwargname[:-2] + + for i in range(ismethod, len(argnames)): + a = argnames[i] + assert a.startswith('w_'), ( + "argument %s of built-in function %r should " + "start with 'w_'" % (a, func)) + argnames[i] = a[2:] + self.sig = argnames, varargname, kwargname def create_frame(self, space, w_globals, closure=None): @@ -79,34 +90,19 @@ # via the interface defined in eval.Frame. def run(self): - argarray = self.fastlocals_w + argarray = list(self.fastlocals_w) + if self.code.generalargs: + w_kwds = argarray.pop() + w_args = argarray.pop() + argarray.append(Arguments.frompacked(self.space, w_args, w_kwds)) + elif self.code.starargs: + w_args = argarray.pop() + argarray += self.space.unpacktuple(w_args) if self.code.ismethod: - argarray = [self.space.unwrap(argarray[0])] + argarray[1:] + argarray[0] = self.space.unwrap(argarray[0]) if self.code.spacearg: - argarray = [self.space] + argarray - return call_with_prepared_arguments(self.space, self.code.func, - argarray) - - -def call_with_prepared_arguments(space, function, argarray): - """Call the given function. 'argarray' is a correctly pre-formatted - list of values for the formal parameters, including one for * and one - for **.""" - # XXX there is no clean way to do this in Python, - # we have to hack back an arguments tuple and keywords dict. - # This algorithm is put in its own well-isolated function so that - # you don't need to look at it :-) - keywords = {} - co = function.func_code - if co.co_flags & 8: # CO_VARKEYWORDS - w_kwds = argarray[-1] - for w_key in space.unpackiterable(w_kwds): - keywords[space.unwrap(w_key)] = space.getitem(w_kwds, w_key) - argarray = argarray[:-1] - if co.co_flags & 4: # CO_VARARGS - w_varargs = argarray[-1] - argarray = argarray[:-1] + space.unpacktuple(w_varargs) - return function(*argarray, **keywords) + argarray.insert(0, self.space) + return self.code.func(*argarray) class Gateway(Wrappable): @@ -203,18 +199,18 @@ def getdefaults(self, space): return [space.wrap(val) for val in self.staticdefs] - def __call__(self, space, *args_w, **kwds_w): + def __call__(self, space, *args_w): # to call the Gateway as a non-method, 'space' must be explicitely # supplied. We build the Function object and call it. fn = self.get_function(space) - return fn.descr_function_call(*args_w, **kwds_w) + return fn.interplevel_call(*args_w) def __get__(self, obj, cls=None): if obj is None: return self else: method = self.get_method(obj) - return method.descr_method_call + return method.interplevel_call class interp2app(Gateway): """Build a Gateway that calls 'f' at interp-level.""" Modified: pypy/trunk/src/pypy/interpreter/module.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/module.py (original) +++ pypy/trunk/src/pypy/interpreter/module.py Fri Jun 25 18:25:37 2004 @@ -21,7 +21,7 @@ def setdict(self, w_dict): self.w_dict = w_dict - def descr_module__new__(space, w_subtype, *args_w, **kwds_w): + def descr_module__new__(space, w_subtype, __args__): module = space.allocate_instance(Module, w_subtype) module.__init__(space, space.wrap('?')) return space.wrap(module) 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 Jun 25 18:25:37 2004 @@ -148,7 +148,7 @@ space = self.space w_meth = self.fn.descr_function_get(space.wrap(5), space.type(space.wrap(5))) meth = space.unwrap(w_meth) - w_result = meth.descr_method_call(space.wrap(42)) + w_result = meth.interplevel_call(space.wrap(42)) self.assertEquals(space.unwrap(w_result), 42) def test_fail_call(self): @@ -156,7 +156,7 @@ w_meth = self.fn.descr_function_get(space.wrap(5), space.type(space.wrap(5))) meth = space.unwrap(w_meth) self.assertRaises_w(self.space.w_TypeError, - meth.descr_method_call, + meth.interplevel_call, space.wrap("spam"), space.wrap("egg")) if __name__ == '__main__': Modified: pypy/trunk/src/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_gateway.py Fri Jun 25 18:25:37 2004 @@ -9,27 +9,50 @@ self.space = testit.objspace() def test_signature(self): - def c(space, w_x, w_y, *args_w, **kw_w): + def c(space, w_x, w_y, *hello_w): pass code = gateway.BuiltinCode(c) - self.assertEqual(code.signature(), (['x', 'y'], 'args', 'kw')) + self.assertEqual(code.signature(), (['x', 'y'], 'hello', None)) def d(self, w_boo): pass code = gateway.BuiltinCode(d) self.assertEqual(code.signature(), (['self', 'boo'], None, None)) + def e(space, w_x, w_y, __args__): + pass + code = gateway.BuiltinCode(e) + self.assertEqual(code.signature(), (['x', 'y'], 'args', 'keywords')) def test_call(self): - def c(space, w_x, w_y, *args_w, **kw_w): + def c(space, w_x, w_y, *hello_w): + u = space.unwrap + w = space.wrap + self.assertEquals(len(hello_w), 2) + self.assertEquals(u(hello_w[0]), 0) + self.assertEquals(u(hello_w[1]), True) + return w((u(w_x) - u(w_y) + len(hello_w))) + code = gateway.BuiltinCode(c) + w = self.space.wrap + w_dict = self.space.newdict([ + (w('x'), w(123)), + (w('y'), w(23)), + (w('hello'), self.space.newtuple([w(0), w(True)])), + ]) + w_result = code.exec_code(self.space, w_dict, w_dict) + self.assertEqual_w(w_result, w(102)) + + def test_call_args(self): + def c(space, w_x, w_y, __args__): u = space.unwrap w = space.wrap - return w((u(w_x) - u(w_y) + len(args_w)) * u(kw_w['boo'])) + return w((u(w_x) - u(w_y) + len(__args__.args_w)) + * u(__args__.kwds_w['boo'])) code = gateway.BuiltinCode(c) w = self.space.wrap w_dict = self.space.newdict([ (w('x'), w(123)), (w('y'), w(23)), (w('args'), self.space.newtuple([w(0), w(True)])), - (w('kw'), self.space.newdict([(w('boo'), w(10))])), + (w('keywords'), self.space.newdict([(w('boo'), w(10))])), ]) w_result = code.exec_code(self.space, w_dict, w_dict) self.assertEqual_w(w_result, w(1020)) Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Fri Jun 25 18:25:37 2004 @@ -48,7 +48,7 @@ raise raise OperationError(space.w_AttributeError,w_name) - def descr__init__(space, w_obj, *args_w, **kwds_w): + def descr__init__(space, w_obj, __args__): pass # XXX some strange checking maybe class DescrOperation: Modified: pypy/trunk/src/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/dicttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/dicttype.py Fri Jun 25 18:25:37 2004 @@ -93,7 +93,7 @@ # ____________________________________________________________ -def descr__new__(space, w_dicttype, *args_w, **kwds_w): +def descr__new__(space, w_dicttype, __args__): from pypy.objspace.std.dictobject import W_DictObject w_obj = space.allocate_instance(W_DictObject, w_dicttype) w_obj.__init__(space, []) Modified: pypy/trunk/src/pypy/objspace/std/listtype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/listtype.py (original) +++ pypy/trunk/src/pypy/objspace/std/listtype.py Fri Jun 25 18:25:37 2004 @@ -13,7 +13,7 @@ # ____________________________________________________________ -def descr__new__(space, w_listtype, *args_w, **kwds_w): +def descr__new__(space, w_listtype, __args__): from pypy.objspace.std.listobject import W_ListObject w_obj = space.allocate_instance(W_ListObject, w_listtype) w_obj.__init__(space, []) Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Fri Jun 25 18:25:37 2004 @@ -21,19 +21,19 @@ def descr__class__(space, w_obj): return space.type(w_obj) -def descr__new__(space, w_type, *args_w, **kwds_w): +def descr__new__(space, w_type, __args__): from pypy.objspace.std.objectobject import W_ObjectObject # don't allow arguments if the default object.__init__() is about # to be called w_parentinit, w_ignored = w_type.lookup_where('__init__') - if w_parentinit is space.w_object and (args_w or kwds_w): + if w_parentinit is space.w_object and (__args__.args_w or __args__.kwds_w): raise OperationError(space.w_TypeError, space.wrap("default __new__ takes no parameters")) w_obj = space.allocate_instance(W_ObjectObject, w_type) w_obj.__init__(space) return w_obj -def descr__init__(space, *args_w, **kwds_w): +def descr__init__(space, __args__): pass # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 25 18:25:37 2004 @@ -182,10 +182,10 @@ for descrname, descr in typedef.rawdict.items(): if isinstance(descr, interp2app): def make_stuff(descr=descr, descrname=descrname, space=self): - def stuff(w_obj, *args, **kwds): + def stuff(w_obj, *args): fn = descr.get_function(space) try: - return fn.descr_function_call(w_obj, *args, **kwds) + return fn.interplevel_call(w_obj, *args) except OperationError, e: if not hasattr(e.w_type, 'originalex'): raise # XXX From arigo at codespeak.net Fri Jun 25 18:30:13 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 18:30:13 +0200 (MEST) Subject: [pypy-svn] r5311 - pypy/trunk/src/pypy/interpreter Message-ID: <20040625163013.429665AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 18:30:12 2004 New Revision: 5311 Modified: pypy/trunk/src/pypy/interpreter/argument.py Log: Tentative solution to the problem of r5309: The name of extra bound arguments are ignored by the keywords checking code. Modified: pypy/trunk/src/pypy/interpreter/argument.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/argument.py (original) +++ pypy/trunk/src/pypy/interpreter/argument.py Fri Jun 25 18:30:12 2004 @@ -14,6 +14,8 @@ ### Construction ### + blind_arguments = 0 + def __init__(self, space, args_w=[], kwds_w={}): assert isinstance(args_w, list) # I keep forgetting the 'space' assert isinstance(kwds_w, dict) # argument so hopefully this helps @@ -50,7 +52,9 @@ def prepend(self, w_firstarg): "Return a new Arguments with a new argument inserted first." - return Arguments(self.space, [w_firstarg] + self.args_w, self.kwds_w) + args = Arguments(self.space, [w_firstarg] + self.args_w, self.kwds_w) + args.blind_arguments = self.blind_arguments + 1 + return args def join(self, other): "Return a new Arguments combining the content of two Arguments." @@ -99,8 +103,11 @@ input_argcount = len(scope_w) # check that no keyword argument conflicts with these + # note that for this purpose we ignore the first blind_arguments, + # which were put into place by prepend(). This way, keywords do + # not conflict with the hidden extra argument bound by methods. if kwds_w: - for name in argnames[:input_argcount]: + for name in argnames[self.blind_arguments:input_argcount]: if name in kwds_w: self.raise_argerr_multiple_values(fnname, name) From arigo at codespeak.net Fri Jun 25 19:34:57 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 19:34:57 +0200 (MEST) Subject: [pypy-svn] r5319 - in pypy/trunk/src/pypy: interpreter interpreter/test module objspace objspace/std Message-ID: <20040625173457.983E95AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 19:34:55 2004 New Revision: 5319 Modified: pypy/trunk/src/pypy/interpreter/eval.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/pycode.py pypy/trunk/src/pypy/interpreter/test/test_code.py pypy/trunk/src/pypy/interpreter/typedef.py pypy/trunk/src/pypy/module/__builtin__interp.py pypy/trunk/src/pypy/module/sysinterp.py pypy/trunk/src/pypy/module/sysmodule.py pypy/trunk/src/pypy/objspace/std/objecttype.py pypy/trunk/src/pypy/objspace/trivial.py Log: * Built-in code objects have some inspectable co_xxx attributes now. * 'sys.pypy_objspaceclass' is a string naming the object space on which we are running. * A few TrivialObjSpace simplifications and fixes. Modified: pypy/trunk/src/pypy/interpreter/eval.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/eval.py (original) +++ pypy/trunk/src/pypy/interpreter/eval.py Fri Jun 25 19:34:55 2004 @@ -46,6 +46,8 @@ argcount += 1 return argcount + def getdocstring(self): + return None UNDEFINED = object() # marker for undefined local variables @@ -83,7 +85,7 @@ return self.w_locals def fget_getdictscope(space, w_self): - self = space.unwrap(w_self) + self = space.unwrap_builtin(w_self) return self.getdictscope() def setdictscope(self, w_locals): Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Fri Jun 25 19:34:55 2004 @@ -28,6 +28,7 @@ # Note that this uses a lot of (construction-time) introspection. eval.Code.__init__(self, func.__name__) self.func = func + self.docstring = func.__doc__ # extract the signature from the (CPython-level) code object tmp = pycode.PyCode(None) tmp._from_code(func.func_code) @@ -82,6 +83,9 @@ def signature(self): return self.sig + def getdocstring(self): + return self.docstring + class BuiltinFrame(eval.Frame): "Frame emulation for BuiltinCode." Modified: pypy/trunk/src/pypy/interpreter/pycode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pycode.py (original) +++ pypy/trunk/src/pypy/interpreter/pycode.py Fri Jun 25 19:34:55 2004 @@ -87,6 +87,12 @@ def getvarnames(self): return self.co_varnames + def getdocstring(self): + if self.co_consts: # it is probably never empty + return self.co_consts[0] + else: + return None + def dictscope_needed(self): # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS. # class bodies only have CO_NEWLOCALS. Modified: pypy/trunk/src/pypy/interpreter/test/test_code.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_code.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_code.py Fri Jun 25 19:34:55 2004 @@ -5,18 +5,57 @@ class AppTestCodeIntrospection(testit.AppTestCase): + def test_attributes(self): def f(): pass - code = f.func_code - self.assert_(hasattr(code, 'co_code')) - self.assert_(hasattr(code, '__class__')) - self.assert_(not hasattr(code,'__dict__')) - self.assertEquals(code.co_name,'f') - self.assertEquals(code.co_names,()) - self.assertEquals(code.co_varnames,()) - self.assertEquals(code.co_argcount,0) + def g(x, *y, **z): "docstring" + self.assert_(hasattr(f.func_code, 'co_code')) + self.assert_(hasattr(g.func_code, 'co_code')) + + testcases = [ + (f.func_code, {'co_name': 'f', + 'co_names': (), + 'co_varnames': (), + 'co_argcount': 0, + 'co_consts': (None,) + }), + (g.func_code, {'co_name': 'g', + 'co_names': (), + 'co_varnames': ('x', 'y', 'z'), + 'co_argcount': 1, + 'co_consts': ("docstring", None), + }), + ] + + import sys + if sys.pypy_objspaceclass != 'TrivialObjSpace': + testcases += [ + (abs.func_code, {'co_name': 'abs', + 'co_varnames': ('val',), + 'co_argcount': 1, + 'co_flags': 0, + 'co_consts': ("abs(number) -> number\n\nReturn the absolute value of the argument.",), + }), + (object.__init__.im_func.func_code, + {#'co_name': '__init__', XXX getting descr__init__ + 'co_varnames': ('obj', 'args', 'keywords'), + 'co_argcount': 1, + 'co_flags': 0x000C, # VARARGS|VARKEYWORDS + }), + ] + + # in PyPy, built-in functions have code objects + # that emulate some attributes + for code, expected in testcases: + self.assert_(hasattr(code, '__class__')) + self.assert_(not hasattr(code,'__dict__')) + for key, value in expected.items(): + self.assertEquals(getattr(code, key), value) + def test_code(self): - import new + import sys, new + if sys.pypy_objspaceclass == 'TrivialObjSpace': + return # skip codestr = "global c\na = 1\nb = 2\nc = a + b\n" ccode = compile(codestr, '', 'exec') co = new.code(ccode.co_argcount, Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Fri Jun 25 19:34:55 2004 @@ -128,7 +128,7 @@ # Definition of the type's descriptors for all the internal types from pypy.interpreter.eval import Code, Frame -from pypy.interpreter.pycode import PyCode +from pypy.interpreter.pycode import PyCode, CO_VARARGS, CO_VARKEYWORDS from pypy.interpreter.pyframe import PyFrame, ControlFlowException from pypy.interpreter.module import Module from pypy.interpreter.function import Function, Method, StaticMethod @@ -150,15 +150,40 @@ default_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict) +# co_xxx interface emulation for built-in code objects +def fget_co_varnames(space, w_code): + code = space.unwrap_builtin(w_code) + return space.newtuple([space.wrap(name) for name in code.getvarnames()]) + +def fget_co_argcount(space, w_code): + code = space.unwrap_builtin(w_code) + argnames, varargname, kwargname = code.signature() + return space.wrap(len(argnames)) + +def fget_co_flags(space, w_code): + code = space.unwrap_builtin(w_code) + argnames, varargname, kwargname = code.signature() + flags = 0 + if varargname is not None: flags |= CO_VARARGS + if kwargname is not None: flags |= CO_VARKEYWORDS + return space.wrap(flags) + +def fget_co_consts(space, w_code): + code = space.unwrap_builtin(w_code) + w_docstring = space.wrap(code.getdocstring()) + return space.newtuple([w_docstring]) + Code.typedef = TypeDef('internal-code', co_name = attrproperty('co_name'), - # XXX compute more co_xxx from the methods in Code + co_varnames = GetSetProperty(fget_co_varnames), + co_argcount = GetSetProperty(fget_co_argcount), + co_flags = GetSetProperty(fget_co_flags), + co_consts = GetSetProperty(fget_co_consts), ) Frame.typedef = TypeDef('internal-frame', f_code = attrproperty('code'), - f_locals = GetSetProperty(Frame.fget_getdictscope.im_func, - ), # , setdictscope), XXX + f_locals = GetSetProperty(Frame.fget_getdictscope.im_func), f_globals = attrproperty_w('w_globals'), ) 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 Fri Jun 25 19:34:55 2004 @@ -237,6 +237,7 @@ return space.unwrap(w_codeobj).exec_code(space, w_globals, w_locals) def abs(w_val): + "abs(number) -> number\n\nReturn the absolute value of the argument." return space.abs(w_val) def chr(w_ascii): Modified: pypy/trunk/src/pypy/module/sysinterp.py ============================================================================== --- pypy/trunk/src/pypy/module/sysinterp.py (original) +++ pypy/trunk/src/pypy/module/sysinterp.py Fri Jun 25 19:34:55 2004 @@ -74,6 +74,8 @@ w_stdout = space.wrap(cpy_sys.stdout) w_stderr = space.wrap(cpy_sys.stderr) +w_pypy_objspaceclass = space.wrap(space.__class__.__name__) + # ____________________________________________________________ def setmodule(w_module): Modified: pypy/trunk/src/pypy/module/sysmodule.py ============================================================================== --- pypy/trunk/src/pypy/module/sysmodule.py (original) +++ pypy/trunk/src/pypy/module/sysmodule.py Fri Jun 25 19:34:55 2004 @@ -12,6 +12,7 @@ # Objects from interpreter-level from __interplevel__ import stdin, stdout, stderr, maxint from __interplevel__ import hexversion, platform +from __interplevel__ import pypy_objspaceclass # Functions from interpreter-level from __interplevel__ import displayhook, _getframe, exc_info Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/src/pypy/objspace/std/objecttype.py Fri Jun 25 19:34:55 2004 @@ -33,7 +33,7 @@ w_obj.__init__(space) return w_obj -def descr__init__(space, __args__): +def descr__init__(space, w_obj, __args__): pass # ____________________________________________________________ Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 25 19:34:55 2004 @@ -7,7 +7,7 @@ from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import * from pypy.objspace.descroperation import DescrOperation, Object -import operator, types, sys +import types, sys import __builtin__ as cpy_builtin class CPyWrapper(object): @@ -134,6 +134,9 @@ # optional check for double-wrapping if isinstance(x, CPyWrapper): raise TypeError, "wrapping an already-wrapped object" + # grumble grumble grumble recursive wrapping grumble + if isinstance(x, tuple): + return tuple([self.wrap(y) for y in x]) return x def unwrap(self, w): @@ -246,31 +249,51 @@ nv = evalue raise OperationError, OperationError(nt, nv), etb - def _auto(name, sourcefn, classlocals): - s = """ -def %(name)s(self, x, *args): - try: - value = %(sourcefn)s(x, *args) - except: - self.reraise() - return self.wrap(value) -""" % locals() - exec s in globals(), classlocals - # from the built-ins - _auto('issubtype', 'issubclass', locals()) - _auto('newtuple', 'tuple', locals()) - _auto('newlist', 'list', locals()) - _auto('newdict', 'dict', locals()) - _auto('newslice', 'slice', locals()) - is_true = operator.truth - # 'is_true' is not called 'truth' because it returns a *non-wrapped* boolean + def issubtype(self, w_x, w_y): + try: + return issubclass(w_x, w_y) + except: + self.reraise() + + def newtuple(self, args_w): + return tuple(args_w) + + def newlist(self, args_w): + return list(args_w) - for _name in ('type', 'ord', 'round'): - _auto(_name, _name, locals()) + def newdict(self, items_w): + try: + return dict(items_w) + except: + self.reraise() - def not_(self, w_obj): # default implementation - return self.wrap(not self.is_true(w_obj)) + def newslice(self, *args_w): + try: + return slice(*args_w) + except: + self.reraise() + + def is_true(self, w_obj): + return not not w_obj + + def not_(self, w_obj): + return not w_obj + + def type(self, w_x): + return type(w_x) + + def ord(self, w_x): + try: + return ord(w_x) + except: + self.reraise() + + def round(self, w_x): + try: + return round(w_x) + except: + self.reraise() def iter(self, w_obj): if isinstance(w_obj, str) and not hasattr(w_obj, '__iter__'): From arigo at codespeak.net Fri Jun 25 20:27:01 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 20:27:01 +0200 (MEST) Subject: [pypy-svn] r5332 - pypy/trunk/src/pypy/interpreter Message-ID: <20040625182701.EB4A15AD9F@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 20:26:56 2004 New Revision: 5332 Modified: pypy/trunk/src/pypy/interpreter/interactive.py Log: Confusion enabler. If we go to the interp-level prompt with Ctrl-C and set some wrapped objects in w_xxx variables, then upon leaving the objects are visible back at app-level under the name xxx. So you can e.g. say w_s = space.wrap(space) and see your own object space under the name s at app-level. Although you cannot do much apart from crashing PyPy by using it. Modified: pypy/trunk/src/pypy/interpreter/interactive.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/interactive.py (original) +++ pypy/trunk/src/pypy/interpreter/interactive.py Fri Jun 25 20:26:56 2004 @@ -39,6 +39,12 @@ local['w_' + self.space.unwrap(w_name)] = ( self.space.getitem(self.w_globals, w_name)) code.interact(banner=banner, local=local) + # copy back 'w_' names + for name in local: + if name.startswith('w_'): + self.space.setitem(self.w_globals, + self.space.wrap(name[2:]), + local[name]) print '*** Leaving interpreter-level console ***' raise From arigo at codespeak.net Fri Jun 25 22:17:21 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 25 Jun 2004 22:17:21 +0200 (MEST) Subject: [pypy-svn] r5334 - in pypy/trunk/src/pypy: interpreter interpreter/test objspace objspace/flow/test Message-ID: <20040625201721.739015A1B5@thoth.codespeak.net> Author: arigo Date: Fri Jun 25 22:17:20 2004 New Revision: 5334 Modified: pypy/trunk/src/pypy/interpreter/function.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/test/test_function.py pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py pypy/trunk/src/pypy/objspace/trivial.py Log: Replaced the gateway's direct call to the Function with space.call_function(). Now FlowObjSpace works on code using app-level helpers! Each one shows up in the flow graph as a function call. Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Fri Jun 25 22:17:20 2004 @@ -32,9 +32,6 @@ frame.setfastscope(scope_w) return frame.run() - def interplevel_call(self, *args_w): - return self.call_args(Arguments(self.space, list(args_w))) - def getdict(self): return self.w_func_dict @@ -104,9 +101,6 @@ self.space.wrap(msg)) return self.space.call_args(self.w_function, args) - def interplevel_call(self, *args_w): - return self.call_args(Arguments(self.space, list(args_w))) - def descr_method_call(self, __args__): return self.call_args(__args__) Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Fri Jun 25 22:17:20 2004 @@ -207,14 +207,17 @@ # to call the Gateway as a non-method, 'space' must be explicitely # supplied. We build the Function object and call it. fn = self.get_function(space) - return fn.interplevel_call(*args_w) + return space.call_function(space.wrap(fn), *args_w) def __get__(self, obj, cls=None): if obj is None: return self else: - method = self.get_method(obj) - return method.interplevel_call + space = obj.space + w_method = space.wrap(self.get_method(obj)) + def helper_method_caller(*args_w): + return space.call_function(w_method, *args_w) + return helper_method_caller class interp2app(Gateway): """Build a Gateway that calls 'f' at interp-level.""" 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 Jun 25 22:17:20 2004 @@ -4,6 +4,7 @@ import unittest from pypy.interpreter.function import Function, Method from pypy.interpreter.pycode import PyCode +from pypy.interpreter.argument import Arguments class AppTestFunctionIntrospection(testit.AppTestCase): @@ -148,16 +149,15 @@ space = self.space w_meth = self.fn.descr_function_get(space.wrap(5), space.type(space.wrap(5))) meth = space.unwrap(w_meth) - w_result = meth.interplevel_call(space.wrap(42)) + w_result = meth.call_args(Arguments(space, [space.wrap(42)])) self.assertEquals(space.unwrap(w_result), 42) def test_fail_call(self): space = self.space w_meth = self.fn.descr_function_get(space.wrap(5), space.type(space.wrap(5))) meth = space.unwrap(w_meth) - self.assertRaises_w(self.space.w_TypeError, - meth.interplevel_call, - space.wrap("spam"), space.wrap("egg")) + args = Arguments(space, [space.wrap("spam"), space.wrap("egg")]) + self.assertRaises_w(self.space.w_TypeError, meth.call_args, args) if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Fri Jun 25 22:17:20 2004 @@ -61,7 +61,7 @@ def print_(i): print i - def dont_test_print(self): # app-level helpers confuse replay + def test_print(self): x = self.codetest(self.print_) self.show(x) Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Fri Jun 25 22:17:20 2004 @@ -188,7 +188,8 @@ def stuff(w_obj, *args): fn = descr.get_function(space) try: - return fn.interplevel_call(w_obj, *args) + return space.call_function(space.wrap(fn), + w_obj, *args) except OperationError, e: if not hasattr(e.w_type, 'originalex'): raise # XXX From arigo at codespeak.net Sat Jun 26 00:51:13 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 00:51:13 +0200 (MEST) Subject: [pypy-svn] r5335 - pypy/trunk/src/pypy/interpreter Message-ID: <20040625225113.B6FCD5ABA5@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 00:51:10 2004 New Revision: 5335 Modified: pypy/trunk/src/pypy/interpreter/gateway.py Log: bug fix Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Sat Jun 26 00:51:10 2004 @@ -105,8 +105,12 @@ if self.code.ismethod: argarray[0] = self.space.unwrap(argarray[0]) if self.code.spacearg: - argarray.insert(0, self.space) - return self.code.func(*argarray) + w_result = self.code.func(self.space, *argarray) + else: + w_result = self.code.func(*argarray) + if w_result is None: + w_result = self.space.w_None + return w_result class Gateway(Wrappable): From arigo at codespeak.net Sat Jun 26 01:01:06 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 01:01:06 +0200 (MEST) Subject: [pypy-svn] r5336 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040625230106.C418E5B688@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 01:01:05 2004 New Revision: 5336 Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py Log: * Ouak! A pdb breakpoint we forgot here long ago. I don't understand why the test suite suddenly triggers it while it didn't use to. * A lot of time was spent in resizing dictionaries. Starting with a minimum size of 8 seems to help. 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 Sat Jun 26 01:01:05 2004 @@ -19,8 +19,8 @@ W_Object.__init__(w_self, space) w_self.used = 0 - w_self.data = [[r_uint(0), None, None]] - w_self.resize(len(list_pairs_w)*2) + w_self.data = [] + w_self.resize(min(len(list_pairs_w)*2, 8)) for w_k, w_v in list_pairs_w: w_self.insert(w_self.hash(w_k), w_k, w_v) @@ -76,10 +76,6 @@ c = 0 while 1: c += 1 - if c > 1000: - import pdb - pdb.set_trace() - i = (i << 2) + i + perturb + 1 entry = self.data[i%len(self.data)] if entry[1] is None: From arigo at codespeak.net Sat Jun 26 01:04:59 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 01:04:59 +0200 (MEST) Subject: [pypy-svn] r5337 - in pypy/trunk/src/pypy: interpreter objspace Message-ID: <20040625230459.644EC5B68E@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 01:04:51 2004 New Revision: 5337 Modified: pypy/trunk/src/pypy/interpreter/argument.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/objspace/descroperation.py Log: Huge performance improvement (30-50%) by special-casing calls to built-in functions early. Not entierely satisfying, but the special-case is well marked as such and everything also works fine if it is disabled. Modified: pypy/trunk/src/pypy/interpreter/argument.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/argument.py (original) +++ pypy/trunk/src/pypy/interpreter/argument.py Sat Jun 26 01:04:51 2004 @@ -17,8 +17,6 @@ blind_arguments = 0 def __init__(self, space, args_w=[], kwds_w={}): - assert isinstance(args_w, list) # I keep forgetting the 'space' - assert isinstance(kwds_w, dict) # argument so hopefully this helps self.space = space self.args_w = args_w self.kwds_w = kwds_w Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Sat Jun 26 01:04:51 2004 @@ -86,6 +86,44 @@ def getdocstring(self): return self.docstring + def performance_shortcut_call(self, space, args): + # this shortcut is only used for performance reasons + if self.generalargs or args.kwds_w: + return None + args_w = args.args_w + if self.ismethod: + if not args_w: + return None + args_w = list(args_w) + args_w[0] = space.unwrap(args_w[0]) + if self.spacearg: + w_result = self.func(space, *args_w) + else: + w_result = self.func(*args_w) + if w_result is None: + w_result = space.w_None + return w_result + + def performance_shortcut_call_meth(self, space, w_obj, args): + # this shortcut is only used for performance reasons + if self.generalargs: + if self.ismethod and not self.spacearg and len(self.sig[0]) == 1: + w_result = self.func(space.unwrap(w_obj), args) + else: + return None + else: + if args.kwds_w: + return None + if self.ismethod: + w_obj = space.unwrap(w_obj) # abuse name w_obj + if self.spacearg: + w_result = self.func(space, w_obj, *args.args_w) + else: + w_result = self.func(w_obj, *args.args_w) + if w_result is None: + w_result = space.w_None + return w_result + class BuiltinFrame(eval.Frame): "Frame emulation for BuiltinCode." Modified: pypy/trunk/src/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/src/pypy/objspace/descroperation.py (original) +++ pypy/trunk/src/pypy/objspace/descroperation.py Sat Jun 26 01:04:51 2004 @@ -2,6 +2,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.function import Function +from pypy.interpreter.gateway import BuiltinCode from pypy.interpreter.argument import Arguments class Object: @@ -61,8 +62,14 @@ def get_and_call_args(space, w_descr, w_obj, args): descr = space.unwrap_builtin(w_descr) - if isinstance(descr, Function): + 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) + if w_result is not None: + return w_result return descr.call_args(args.prepend(w_obj)) else: w_impl = space.get(w_descr, w_obj) @@ -84,6 +91,11 @@ ## return space.get_and_call(w_descr, w_obj, w_args, w_kwargs) def call_args(space, w_obj, args): + if type(w_obj) is Function and isinstance(w_obj.code, BuiltinCode): + # this special case is ONLY for performance reasons + w_result = w_obj.code.performance_shortcut_call(space, args) + if w_result is not None: + return w_result w_descr = space.lookup(w_obj, '__call__') if w_descr is None: raise OperationError(space.w_TypeError, From arigo at codespeak.net Sat Jun 26 01:46:33 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 01:46:33 +0200 (MEST) Subject: [pypy-svn] r5338 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040625234633.A93CD5B68F@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 01:46:33 2004 New Revision: 5338 Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py Log: Previous revision buggy! Using min() to means "at least"... It's max() that should be used for that purpose... Re-enabled the runaway check, and made sure that it cannot fire except in buggy cases. 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 Sat Jun 26 01:46:33 2004 @@ -20,7 +20,7 @@ w_self.used = 0 w_self.data = [] - w_self.resize(min(len(list_pairs_w)*2, 8)) + w_self.resize(len(list_pairs_w)*2) for w_k, w_v in list_pairs_w: w_self.insert(w_self.hash(w_k), w_k, w_v) @@ -41,7 +41,7 @@ cell[2] = w_value def resize(self, minused): - newsize = 1 + newsize = 4 while newsize < minused: newsize *= 2 od = self.data @@ -73,9 +73,16 @@ freeslot = None perturb = lookup_hash - c = 0 + if __debug__: + c = len(self.data) + 99 while 1: - c += 1 + if __debug__: + c -= 1 + if not c: + import sys, pdb + print >> sys.stderr, 'dict lookup lost in infinite loop' + pdb.set_trace() + i = (i << 2) + i + perturb + 1 entry = self.data[i%len(self.data)] if entry[1] is None: From arigo at codespeak.net Sat Jun 26 10:56:19 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 10:56:19 +0200 (MEST) Subject: [pypy-svn] r5339 - pypy/trunk/src/pypy/interpreter Message-ID: <20040626085619.E97D75A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 10:56:11 2004 New Revision: 5339 Modified: pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/pyopcode.py Log: Rationalization of some app-level helpers of pyopcode.py: * special-cased bare 'raise' statements * removed the 'import sys' everywhere, replaced them with a helper __setupgateways__() which is called once Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Sat Jun 26 10:56:11 2004 @@ -198,6 +198,8 @@ else: # no, we build all Gateways in the staticglobals now. w_globals = build_dict(self.staticglobals, space) + if '__setupgateways__' in self.staticglobals: + self.staticglobals['__setupgateways__'](space) return self.build_function(space, w_globals) def build_function(self, space, w_globals): Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Sat Jun 26 10:56:11 2004 @@ -305,10 +305,16 @@ # we use the .app.py file to prepare the exception/value/traceback # but not to actually raise it, because we cannot use the 'raise' # statement to implement RAISE_VARARGS - w_type = w_value = w_traceback = f.space.w_None + if nbargs == 0: + operror = f.space.getexecutioncontext().sys_exc_info() + if operror is None: + raise OperationError(f.space.w_TypeError, + f.space.wrap("raise: no active exception to re-raise")) + raise operror # re-raise the same OperationError + w_value = w_traceback = f.space.w_None if nbargs >= 3: w_traceback = f.valuestack.pop() if nbargs >= 2: w_value = f.valuestack.pop() - if nbargs >= 1: w_type = f.valuestack.pop() + if 1: w_type = f.valuestack.pop() w_resulttuple = prepare_raise(f.space, w_type, w_value, w_traceback) w_type, w_value, w_traceback = f.space.unpacktuple(w_resulttuple, 3) tb = f.space.unwrap(w_traceback) @@ -788,8 +794,11 @@ # There are also a couple of helpers that are methods, defined in the # class above. -def app_print_expr(x): +def app___setupgateways__(): + global sys import sys + +def app_print_expr(x): try: displayhook = sys.displayhook except AttributeError: @@ -808,7 +817,6 @@ return softspace def app_sys_stdout(): - import sys try: return sys.stdout except AttributeError: @@ -834,15 +842,6 @@ # we get an infinite loop if this import fails: # import types -> IMPORT_NAME -> import_name -> raise ImportError # -> RAISE_VARARGS -> prepare_raise -> import types ... - if etype is None: - # reraise - # XXX this means that "raise" is equivalent to "raise None" - # which is not the case in CPython, but well - import sys - etype, value, traceback = sys.exc_info() - #XXX re-enable the following check - #if not isinstance(traceback, (types.NoneType, types.TracebackType)): - # raise TypeError, "raise: arg 3 must be traceback or None" while isinstance(etype, tuple): etype = etype[0] if isinstance(etype, type): From arigo at codespeak.net Sat Jun 26 11:38:18 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 11:38:18 +0200 (MEST) Subject: [pypy-svn] r5340 - pypy/trunk/src/pypy/interpreter Message-ID: <20040626093818.2FE145A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 11:37:56 2004 New Revision: 5340 Modified: pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/interpreter/pyopcode.py Log: Previous revision broke test_print in flowobjspace. Fixed by forcing 'sys' into the app-level helpers' globals if it is already built (fragile bootstrapping workaround). Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Sat Jun 26 11:37:56 2004 @@ -198,8 +198,6 @@ else: # no, we build all Gateways in the staticglobals now. w_globals = build_dict(self.staticglobals, space) - if '__setupgateways__' in self.staticglobals: - self.staticglobals['__setupgateways__'](space) return self.build_function(space, w_globals) def build_function(self, space, w_globals): @@ -326,4 +324,6 @@ w_name = space.wrap(value.name) w_object = space.wrap(fn) space.setitem(w_globals, w_name, w_object) + if hasattr(space, 'w_sys'): # give them 'sys' if it exists already + space.setitem(w_globals, space.wrap('sys'), space.w_sys) return w_globals Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Sat Jun 26 11:37:56 2004 @@ -794,10 +794,6 @@ # There are also a couple of helpers that are methods, defined in the # class above. -def app___setupgateways__(): - global sys - import sys - def app_print_expr(x): try: displayhook = sys.displayhook From arigo at codespeak.net Sat Jun 26 11:59:20 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 11:59:20 +0200 (MEST) Subject: [pypy-svn] r5341 - pypy/trunk/src/pypy/interpreter Message-ID: <20040626095920.2F6355A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 11:59:17 2004 New Revision: 5341 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py Log: 'raise' handling *still* wasn't completely correct... What if instantiating the exception class returns some completely unrelated object? Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Sat Jun 26 11:59:17 2004 @@ -315,8 +315,8 @@ if nbargs >= 3: w_traceback = f.valuestack.pop() if nbargs >= 2: w_value = f.valuestack.pop() if 1: w_type = f.valuestack.pop() - w_resulttuple = prepare_raise(f.space, w_type, w_value, w_traceback) - w_type, w_value, w_traceback = f.space.unpacktuple(w_resulttuple, 3) + w_resulttuple = prepare_raise(f.space, w_type, w_value) + w_type, w_value = f.space.unpacktuple(w_resulttuple, 2) tb = f.space.unwrap(w_traceback) if tb is not None: if not isinstance(tb,pytraceback.PyTraceback): @@ -833,7 +833,7 @@ stream.write("\n") file_softspace(stream, False) -def app_prepare_raise(etype, value, traceback): +def app_prepare_raise(etype, value): # careful if 'import types' is added here! # we get an infinite loop if this import fails: # import types -> IMPORT_NAME -> import_name -> raise ImportError @@ -841,15 +841,15 @@ while isinstance(etype, tuple): etype = etype[0] if isinstance(etype, type): - if isinstance(value, etype): - # raise Type, Instance: let etype be the exact type of value - etype = value.__class__ - elif value is None: - # raise Type: we assume we have to instantiate Type - value = etype() - else: - # raise Type, X: assume X is the constructor argument - value = etype(value) + if not isinstance(value, etype): + if value is None: + # raise Type: we assume we have to instantiate Type + value = etype() + else: + # raise Type, X: assume X is the constructor argument + value = etype(value) + # raise Type, Instance: let etype be the exact type of value + etype = value.__class__ elif type(etype) is str: # XXX warn -- deprecated if value is not None and type(value) is not str: @@ -866,7 +866,7 @@ if not hasattr(value, '__dict__') and not hasattr(value, '__slots__'): raise TypeError("raising built-in objects can be ambiguous, " "use 'raise type, value' instead") - return etype, value, traceback + return etype, value def app_find_metaclass(bases, namespace, globals): if '__metaclass__' in namespace: From arigo at codespeak.net Sat Jun 26 12:26:10 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 12:26:10 +0200 (MEST) Subject: [pypy-svn] r5350 - pypy/trunk/src/pypy/interpreter Message-ID: <20040626102610.DAEF35A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 12:25:53 2004 New Revision: 5350 Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py Log: *still* wasn't right. Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Sat Jun 26 12:25:53 2004 @@ -310,7 +310,8 @@ if operror is None: raise OperationError(f.space.w_TypeError, f.space.wrap("raise: no active exception to re-raise")) - raise operror # re-raise the same OperationError + # re-raise, no new traceback obj will be attached + raise pyframe.SApplicationException(operror) w_value = w_traceback = f.space.w_None if nbargs >= 3: w_traceback = f.valuestack.pop() if nbargs >= 2: w_value = f.valuestack.pop() From arigo at codespeak.net Sat Jun 26 12:43:35 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 12:43:35 +0200 (MEST) Subject: [pypy-svn] r5351 - pypy/trunk/src/pypy/interpreter Message-ID: <20040626104335.122E25A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 12:43:31 2004 New Revision: 5351 Modified: pypy/trunk/src/pypy/interpreter/function.py Log: use code.getdocstring() from Function.func_doc. Modified: pypy/trunk/src/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/function.py (original) +++ pypy/trunk/src/pypy/interpreter/function.py Sat Jun 26 12:43:31 2004 @@ -18,7 +18,7 @@ def __init__(self, space, code, w_globals=None, defs_w=[], closure=None, forcename=None): self.space = space self.name = forcename or code.co_name - self.w_doc = None # lazily read and wrapped from code.co_consts[0] + self.w_doc = None # lazily read and wrapped from code.getdocstring() self.code = code # Code instance self.w_func_globals = w_globals # the globals dictionary self.closure = closure # normally, list of Cell instances or None @@ -64,8 +64,7 @@ def fget_func_doc(space, w_self): self = space.unwrap(w_self) if self.w_doc is None: - doc = getattr(self.code, 'co_consts', (None,))[0] - self.w_doc = space.wrap(doc) + self.w_doc = space.wrap(self.code.getdocstring()) return self.w_doc def fset_func_doc(space, w_self, w_doc): From arigo at codespeak.net Sat Jun 26 12:49:16 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 12:49:16 +0200 (MEST) Subject: [pypy-svn] r5352 - in pypy/trunk/src/pypy/objspace/flow: . test Message-ID: <20040626104916.D22BA5A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 12:48:39 2004 New Revision: 5352 Added: pypy/trunk/src/pypy/objspace/flow/specialcase.py (contents, props changed) Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Log: 'raise' in flow graphs. Requires special-casing the app_prepare_raise() app-helper, so here is some framework to handle special cases. Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Sat Jun 26 12:48:39 2004 @@ -22,7 +22,7 @@ self.w_None = Constant(None) self.w_False = Constant(False) self.w_True = Constant(True) - for exc in [KeyError, ValueError, StopIteration]: + for exc in [KeyError, ValueError, IndexError, StopIteration]: clsname = exc.__name__ setattr(self, 'w_'+clsname, Constant(exc)) #self.make_builtins() @@ -100,6 +100,11 @@ #print >> sys.stderr, '*** reraise', etype, evalue raise OperationError, OperationError(self.wrap(etype), self.wrap(evalue)), etb + def setup_executioncontext(self, ec): + self.executioncontext = ec + from pypy.objspace.flow import specialcase + self.specialcases = specialcase.setup(self) + def build_flow(self, func, constargs={}): """ """ @@ -111,7 +116,7 @@ closure = [extract_cell_content(c) for c in func.func_closure] ec = flowcontext.FlowExecutionContext(self, code, func.func_globals, constargs, closure) - self.executioncontext = ec + self.setup_executioncontext(ec) ec.build_flow() name = ec.graph.name for c in "<>&!": @@ -148,6 +153,13 @@ return w_item def call_args(self, w_callable, args): + try: + sc = self.specialcases[self.unwrap(w_callable)] + except (UnwrapException, KeyError): + pass + else: + return sc(self, args) + if args.kwds_w: w_args, w_kwds = args.pack() return self.do_operation('call', w_callable, w_args, w_kwds) Added: pypy/trunk/src/pypy/objspace/flow/specialcase.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/objspace/flow/specialcase.py Sat Jun 26 12:48:39 2004 @@ -0,0 +1,52 @@ +import types +from pypy.interpreter import pyopcode +from pypy.interpreter.error import OperationError +from pypy.objspace.flow.objspace import UnwrapException +from pypy.objspace.flow.model import Variable + + +def getconstclass(space, w_cls): + try: + ecls = space.unwrap(w_cls) + except UnwrapException: + pass + else: + if isinstance(ecls, (type, types.ClassType)): + return ecls + return None + + +def prepare_raise(space, args): + """Special-case for 'raise' statements. + + Only accept the following syntaxes: + * raise Class + * raise Class, Arg + * raise Class(...) + """ + assert len(args.args_w) == 2 and args.kwds_w == {} + w_arg1, w_arg2 = args.args_w + # + # Note that we immediately raise the correct OperationError to + # prevent further processing by pyopcode.py. + # + etype = getconstclass(space, w_arg1) + if etype is not None: + # raise Class or raise Class, Arg: ignore the Arg + raise OperationError(w_arg1, Variable()) + else: + # raise Instance: we need a hack to figure out of which class it is. + # Normally, Instance should have been created by the previous operation + # which should be a simple_call(, ...). + # Fetch the out of there. (This doesn't work while replaying) + spaceop = space.executioncontext.crnt_ops[-1] + assert spaceop.opname == 'simple_call' + assert spaceop.result is w_arg1 + w_type = spaceop.args[0] + raise OperationError(w_type, w_arg2) + + +def setup(space): + return { + pyopcode.prepare_raise.get_function(space): prepare_raise, + } Modified: pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Sat Jun 26 12:48:39 2004 @@ -222,6 +222,30 @@ x = self.codetest(self.freevar(3)) self.show(x) + #__________________________________________________________ + def raise1(msg): + raise IndexError + + def test_raise1(self): + x = self.codetest(self.raise1) + self.show(x) + + #__________________________________________________________ + def raise2(msg): + raise IndexError, msg + + def test_raise2(self): + x = self.codetest(self.raise2) + self.show(x) + + #__________________________________________________________ + def raise3(msg): + raise IndexError(msg) + + def test_raise3(self): + x = self.codetest(self.raise3) + self.show(x) + if __name__ == '__main__': testit.main() From arigo at codespeak.net Sat Jun 26 14:49:22 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 14:49:22 +0200 (MEST) Subject: [pypy-svn] r5353 - in pypy/trunk/src/pypy: interpreter interpreter/test objspace/flow Message-ID: <20040626124922.829645A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 14:47:07 2004 New Revision: 5353 Added: pypy/trunk/src/pypy/interpreter/test/test_raise.py - copied, changed from r5339, pypy/trunk/src/pypy/interpreter/test/test_interpreter.py Modified: pypy/trunk/src/pypy/interpreter/pyframe.py pypy/trunk/src/pypy/interpreter/pyopcode.py pypy/trunk/src/pypy/interpreter/test/test_interpreter.py pypy/trunk/src/pypy/objspace/flow/specialcase.py Log: * Exceptions were still not right. * Unified prepare_raise() and normalize_exception(), which looks better. * Lots of tests. Moved them to a new test_raise, even. Modified: pypy/trunk/src/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/src/pypy/interpreter/pyframe.py Sat Jun 26 14:47:07 2004 @@ -152,8 +152,10 @@ if frame.space.full_exceptions: w_normalized = normalize_exception(frame.space, w_type, w_value) w_type, w_value = frame.space.unpacktuple(w_normalized, 2) - # this is to make sure that sys.exc_info() etc see - # normalized exception -- not sure here is best place! + # save the normalized exception back into the OperationError + # -- in particular it makes sure that sys.exc_info() etc see + # normalized exception. + operationerr.w_type = w_type operationerr.w_value = w_value # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, @@ -165,25 +167,43 @@ return True # stop unrolling return False -def app_normalize_exception(etype, evalue): - # XXX should really be defined as a method on OperationError, - # but this is not so easy because OperationError cannot be - # at the same time an old-style subclass of Exception and a - # new-style subclass of Wrappable :-( - # moreover, try importing gateway from errors.py and you'll see :-( - +def app_normalize_exception(etype, value): + """Normalize an (exc_type, exc_value) pair: + exc_value will be an exception instance and exc_type its class. + """ # mistakes here usually show up as infinite recursion, which is fun. - if isinstance(evalue, etype): - return etype, evalue - if isinstance(etype, type) and issubclass(etype, Exception): - if evalue is None: - evalue = () - elif not isinstance(evalue, tuple): - evalue = (evalue,) - evalue = etype(*evalue) + while isinstance(etype, tuple): + etype = etype[0] + if isinstance(etype, type): + if not isinstance(value, etype): + if value is None: + # raise Type: we assume we have to instantiate Type + value = etype() + elif isinstance(value, tuple): + # raise Type, Tuple: assume Tuple contains the constructor args + value = etype(*value) + else: + # raise Type, X: assume X is the constructor argument + value = etype(value) + # raise Type, Instance: let etype be the exact type of value + etype = value.__class__ + elif type(etype) is str: + # XXX warn -- deprecated + if value is not None and type(value) is not str: + raise TypeError("string exceptions can only have a string value") else: - raise Exception, "?!" # XXX - return etype, evalue + # raise X: we assume that X is an already-built instance + if value is not None: + raise TypeError("instance exception may not have a separate value") + value = etype + etype = value.__class__ + # for the sake of language consistency we should not allow + # things like 'raise 1', but it's probably fine (i.e. + # not ambiguous) to allow them in the explicit form 'raise int, 1' + if not hasattr(value, '__dict__') and not hasattr(value, '__slots__'): + raise TypeError("raising built-in objects can be ambiguous, " + "use 'raise type, value' instead") + return etype, value normalize_exception = gateway.app2interp(app_normalize_exception) Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/src/pypy/interpreter/pyopcode.py Sat Jun 26 14:47:07 2004 @@ -316,7 +316,7 @@ if nbargs >= 3: w_traceback = f.valuestack.pop() if nbargs >= 2: w_value = f.valuestack.pop() if 1: w_type = f.valuestack.pop() - w_resulttuple = prepare_raise(f.space, w_type, w_value) + w_resulttuple = pyframe.normalize_exception(f.space, w_type, w_value) w_type, w_value = f.space.unpacktuple(w_resulttuple, 2) tb = f.space.unwrap(w_traceback) if tb is not None: @@ -834,41 +834,6 @@ stream.write("\n") file_softspace(stream, False) -def app_prepare_raise(etype, value): - # careful if 'import types' is added here! - # we get an infinite loop if this import fails: - # import types -> IMPORT_NAME -> import_name -> raise ImportError - # -> RAISE_VARARGS -> prepare_raise -> import types ... - while isinstance(etype, tuple): - etype = etype[0] - if isinstance(etype, type): - if not isinstance(value, etype): - if value is None: - # raise Type: we assume we have to instantiate Type - value = etype() - else: - # raise Type, X: assume X is the constructor argument - value = etype(value) - # raise Type, Instance: let etype be the exact type of value - etype = value.__class__ - elif type(etype) is str: - # XXX warn -- deprecated - if value is not None and type(value) is not str: - raise TypeError("string exceptions can only have a string value") - else: - # raise X: we assume that X is an already-built instance - if value is not None: - raise TypeError("instance exception may not have a separate value") - value = etype - etype = value.__class__ - # for the sake of language consistency we should not allow - # things like 'raise 1', but it's probably fine (i.e. - # not ambiguous) to allow them in the explicit form 'raise int, 1' - if not hasattr(value, '__dict__') and not hasattr(value, '__slots__'): - raise TypeError("raising built-in objects can be ambiguous, " - "use 'raise type, value' instead") - return etype, value - def app_find_metaclass(bases, namespace, globals): if '__metaclass__' in namespace: return namespace['__metaclass__'] Modified: pypy/trunk/src/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_interpreter.py Sat Jun 26 14:47:07 2004 @@ -143,61 +143,10 @@ 1+2+3 + 5+6+7+8+900) class AppTestInterpreter(testit.AppTestCase): - def test_exception(self): - try: - raise Exception, 1 - except Exception, e: - self.assertEquals(e.args[0], 1) - def test_trivial(self): x = 42 self.assertEquals(x, 42) - def test_raise(self): - def f(): - raise Exception - self.assertRaises(Exception, f) - - def test_exception(self): - try: - raise Exception - self.fail("exception failed to raise") - except: - pass - else: - self.fail("exception executing else clause!") - - def test_raise2(self): - def f(r): - try: - raise r - except LookupError: - return 1 - self.assertRaises(Exception, f, Exception) - self.assertEquals(f(IndexError), 1) - - def test_raise3(self): - try: - raise 1 - except TypeError: - pass - else: - self.fail("shouldn't be able to raise 1") - - def test_raise_three_args(self): - import sys - try: - raise ValueError - except: - exc_type,exc_val,exc_tb = sys.exc_info() - try: - raise exc_type,exc_val,exc_tb - except: - exc_type2,exc_val2,exc_tb2 = sys.exc_info() - self.assertEquals(exc_type,exc_type2) - self.assertEquals(exc_val,exc_val2) - self.assertEquals(exc_tb,exc_tb2) - def test_trivial_call(self): def f(): return 42 self.assertEquals(f(), 42) Copied: pypy/trunk/src/pypy/interpreter/test/test_raise.py (from r5339, pypy/trunk/src/pypy/interpreter/test/test_interpreter.py) ============================================================================== --- pypy/trunk/src/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/trunk/src/pypy/interpreter/test/test_raise.py Sat Jun 26 14:47:07 2004 @@ -1,173 +1,67 @@ import autopath from pypy.tool import testit -class TestInterpreter(testit.TestCase): - def codetest(self, source, functionname, args): - """Compile and run the given code string, and then call its function - named by 'functionname' with arguments 'args'.""" - from pypy.interpreter import baseobjspace, executioncontext - from pypy.interpreter import pyframe, gateway, module - space = self.space - - compile = space.builtin.compile - w = space.wrap - w_code = compile(w(source), w(''), w('exec'), w(0), w(0)) - - ec = executioncontext.ExecutionContext(space) - - tempmodule = module.Module(space, w("__temp__")) - w_glob = tempmodule.w_dict - space.setitem(w_glob, w("__builtins__"), space.w_builtins) - - code = space.unwrap(w_code) - code.exec_code(space, w_glob, w_glob) - - wrappedargs = [w(a) for a in args] - wrappedfunc = space.getitem(w_glob, w(functionname)) - try: - w_output = space.call_function(wrappedfunc, *wrappedargs) - except baseobjspace.OperationError, e: - #e.print_detailed_traceback(space) - return '<<<%s>>>' % e.errorstr(space) +class AppTestRaise(testit.AppTestCase): + def test_control_flow(self): + try: + raise Exception + self.fail("exception failed to raise") + except: + pass else: - return space.unwrap(w_output) + self.fail("exception executing else clause!") - def setUp(self): - self.space = testit.objspace() + def test_1arg(self): + try: + raise SystemError, 1 + except Exception, e: + self.assertEquals(e.args[0], 1) - def test_exception_trivial(self): - x = self.codetest(''' -def f(): - try: - raise Exception() - except Exception, e: - return 1 - return 2 -''', 'f', []) - self.assertEquals(x, 1) - - def test_exception(self): - x = self.codetest(''' -def f(): - try: - raise Exception, 1 - except Exception, e: - return e.args[0] -''', 'f', []) - self.assertEquals(x, 1) - - def test_finally(self): - code = ''' -def f(a): - try: - if a: - raise Exception - a = -12 - finally: - return a -''' - self.assertEquals(self.codetest(code, 'f', [0]), -12) - self.assertEquals(self.codetest(code, 'f', [1]), 1) - -## def test_raise(self): -## x = self.codetest(''' -## def f(): -## raise 1 -## ''', 'f', []) -## self.assertEquals(x, '<<>>') - - def test_except2(self): - x = self.codetest(''' -def f(): - try: - z = 0 - try: - "x"+1 - except TypeError, e: - z = 5 - raise e - except TypeError: - return z -''', 'f', []) - self.assertEquals(x, 5) - - def test_except3(self): - code = ''' -def f(v): - z = 0 - try: - z = 1//v - except ZeroDivisionError, e: - z = "infinite result" - return z -''' - self.assertEquals(self.codetest(code, 'f', [2]), 0) - self.assertEquals(self.codetest(code, 'f', [0]), "infinite result") - ess = "TypeError: unsupported operand type" - res = self.codetest(code, 'f', ['x']) - self.failUnless(res.find(ess) >= 0) - # the following (original) test was a bit too strict...: - # self.assertEquals(self.codetest(code, 'f', ['x']), "<<>>") - - def test_break(self): - code = ''' -def f(n): - total = 0 - for i in range(n): - try: - if i == 4: - break - finally: - total += i - return total -''' - self.assertEquals(self.codetest(code, 'f', [4]), 1+2+3) - self.assertEquals(self.codetest(code, 'f', [9]), 1+2+3+4) - - def test_continue(self): - code = ''' -def f(n): - total = 0 - for i in range(n): - try: - if i == 4: - continue - finally: - total += 100 - total += i - return total -''' - self.assertEquals(self.codetest(code, 'f', [4]), 1+2+3+400) - self.assertEquals(self.codetest(code, 'f', [9]), - 1+2+3 + 5+6+7+8+900) + def test_2args(self): + try: + raise SystemError, (1, 2) + except Exception, e: + self.assertEquals(e.args[0], 1) + self.assertEquals(e.args[1], 2) -class AppTestInterpreter(testit.AppTestCase): - def test_exception(self): + def test_instancearg(self): try: - raise Exception, 1 + raise SystemError, SystemError(1, 2) except Exception, e: self.assertEquals(e.args[0], 1) + self.assertEquals(e.args[1], 2) - def test_trivial(self): - x = 42 - self.assertEquals(x, 42) + def test_more_precise_instancearg(self): + try: + raise Exception, SystemError(1, 2) + except SystemError, e: + self.assertEquals(e.args[0], 1) + self.assertEquals(e.args[1], 2) - def test_raise(self): - def f(): - raise Exception - self.assertRaises(Exception, f) + def test_stringexc(self): + a = "hello world" + try: + raise a + except a, e: + self.assertEquals(e, None) + try: + raise a, "message" + except a, e: + self.assertEquals(e, "message") - def test_exception(self): + def test_builtin_exc(self): try: - raise Exception - self.fail("exception failed to raise") - except: - pass - else: - self.fail("exception executing else clause!") + [][0] + except IndexError, e: + self.assert_(isinstance(e, IndexError)) + + def test_raise_cls(self): + def f(): + raise IndexError + self.assertRaises(IndexError, f) - def test_raise2(self): + def test_raise_cls_catch(self): def f(r): try: raise r @@ -176,7 +70,7 @@ self.assertRaises(Exception, f, Exception) self.assertEquals(f(IndexError), 1) - def test_raise3(self): + def test_raise_wrong(self): try: raise 1 except TypeError: @@ -198,34 +92,38 @@ self.assertEquals(exc_val,exc_val2) self.assertEquals(exc_tb,exc_tb2) - def test_trivial_call(self): - def f(): return 42 - self.assertEquals(f(), 42) - - def test_trivial_call2(self): - def f(): return 1 + 1 - self.assertEquals(f(), 2) - - def test_print(self): - import sys - save = sys.stdout - class Out: - def __init__(self): - self.args = [] - def write(self, *args): - self.args.extend(args) - out = Out() - try: - sys.stdout = out - print 10 - self.assertEquals(out.args, ['10','\n']) - finally: - sys.stdout = save - - def test_identity(self): - def f(x): return x - self.assertEquals(f(666), 666) + def test_tuple_type(self): + def f(): + raise ((StopIteration, 123), 456, 789) + self.assertRaises(StopIteration, f) + def test_userclass(self): + class A: + def __init__(self, x=None): + self.x = x + class B(A): + pass + try: + raise A + except A, a: + self.assertEquals(a.x, None) + try: + raise A(42) + except A, a: + self.assertEquals(a.x, 42) + try: + raise A, 42 + except A, a: + self.assertEquals(a.x, 42) + try: + raise B + except A, b: + self.assertEquals(type(b), B) + try: + raise A, B(42) + except B, b: + self.assertEquals(type(b), B) + self.assertEquals(b.x, 42) if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/objspace/flow/specialcase.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/specialcase.py (original) +++ pypy/trunk/src/pypy/objspace/flow/specialcase.py Sat Jun 26 14:47:07 2004 @@ -1,5 +1,5 @@ import types -from pypy.interpreter import pyopcode +from pypy.interpreter import pyframe from pypy.interpreter.error import OperationError from pypy.objspace.flow.objspace import UnwrapException from pypy.objspace.flow.model import Variable @@ -48,5 +48,5 @@ def setup(space): return { - pyopcode.prepare_raise.get_function(space): prepare_raise, + pyframe.normalize_exception.get_function(space): prepare_raise, } From arigo at codespeak.net Sat Jun 26 19:04:32 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 19:04:32 +0200 (MEST) Subject: [pypy-svn] r5354 - in pypy/trunk/src/pypy: interpreter objspace objspace/flow objspace/std translator Message-ID: <20040626170432.A54405A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 19:04:31 2004 New Revision: 5354 Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/gateway.py pypy/trunk/src/pypy/objspace/flow/objspace.py pypy/trunk/src/pypy/objspace/flow/specialcase.py pypy/trunk/src/pypy/objspace/std/objspace.py pypy/trunk/src/pypy/objspace/trace.py pypy/trunk/src/pypy/translator/translator.py Log: * slight change in the interface of loadfromcache() * hack in flowobjspace to handle temporary tuples of wrapped values where calling newtuple() and unpacktuple() would loose all information because it would return a Variable. Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Sat Jun 26 19:04:31 2004 @@ -33,7 +33,7 @@ try: return self.generalcache[key] except KeyError: - return self.generalcache.setdefault(key, builder(self)) + return self.generalcache.setdefault(key, builder(key, self)) def make_builtins(self, for_builtins): # initializing builtins may require creating a frame which in Modified: pypy/trunk/src/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/gateway.py (original) +++ pypy/trunk/src/pypy/interpreter/gateway.py Sat Jun 26 19:04:31 2004 @@ -173,7 +173,7 @@ return self.get_function(space) def get_function(self, space): - return space.loadfromcache(self, self.build_all_functions) + return space.loadfromcache(self, Gateway.build_all_functions) def build_all_functions(self, space): # the construction is supposed to be done only once in advance, Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Sat Jun 26 19:04:31 2004 @@ -39,7 +39,7 @@ self.executioncontext.crnt_ops = flowcontext.ConcreteNoOp() self.concrete_mode += 1 try: - return self.generalcache.setdefault(key, builder(self)) + return self.generalcache.setdefault(key, builder(key, self)) finally: self.executioncontext.crnt_ops = previous_ops self.concrete_mode -= 1 @@ -103,7 +103,7 @@ def setup_executioncontext(self, ec): self.executioncontext = ec from pypy.objspace.flow import specialcase - self.specialcases = specialcase.setup(self) + specialcase.setup(self) def build_flow(self, func, constargs={}): """ @@ -124,6 +124,19 @@ ec.graph.name = name return ec.graph + def unpacktuple(self, w_tuple, expected_length=None): + # special case to accept either Constant tuples + # or real tuples of Variables/Constants + if isinstance(w_tuple, tuple): + result = w_tuple + else: + unwrapped = self.unwrap(w_tuple) + result = tuple([Constant(x) for x in unwrapped]) + if expected_length is not None and len(result) != expected_length: + raise ValueError, "got a tuple of length %d instead of %d" % ( + len(result), expected_length) + return result + # ____________________________________________________________ def do_operation(self, name, *args_w): spaceop = SpaceOperation(name, args_w, Variable()) @@ -154,8 +167,8 @@ def call_args(self, w_callable, args): try: - sc = self.specialcases[self.unwrap(w_callable)] - except (UnwrapException, KeyError): + sc = self.unwrap(w_callable)._flowspecialcase_ + except (UnwrapException, AttributeError): pass else: return sc(self, args) Modified: pypy/trunk/src/pypy/objspace/flow/specialcase.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/specialcase.py (original) +++ pypy/trunk/src/pypy/objspace/flow/specialcase.py Sat Jun 26 19:04:31 2004 @@ -1,8 +1,8 @@ import types -from pypy.interpreter import pyframe +from pypy.interpreter import pyframe, baseobjspace from pypy.interpreter.error import OperationError from pypy.objspace.flow.objspace import UnwrapException -from pypy.objspace.flow.model import Variable +from pypy.objspace.flow.model import Variable, Constant def getconstclass(space, w_cls): @@ -16,7 +16,7 @@ return None -def prepare_raise(space, args): +def normalize_exception(space, args): """Special-case for 'raise' statements. Only accept the following syntaxes: @@ -26,14 +26,10 @@ """ assert len(args.args_w) == 2 and args.kwds_w == {} w_arg1, w_arg2 = args.args_w - # - # Note that we immediately raise the correct OperationError to - # prevent further processing by pyopcode.py. - # etype = getconstclass(space, w_arg1) if etype is not None: # raise Class or raise Class, Arg: ignore the Arg - raise OperationError(w_arg1, Variable()) + return (w_arg1, Variable()) else: # raise Instance: we need a hack to figure out of which class it is. # Normally, Instance should have been created by the previous operation @@ -43,10 +39,20 @@ assert spaceop.opname == 'simple_call' assert spaceop.result is w_arg1 w_type = spaceop.args[0] - raise OperationError(w_type, w_arg2) + return (w_type, w_arg2) + # this function returns a real tuple that can be handled + # by FlowObjSpace.unpacktuple() + +def loadfromcache(space, args): + # XXX need some way to know how to fully initialize the cache + assert len(args.args_w) == 2 and args.kwds_w == {} + w_key, w_builder = args.args_w + w_cache = Constant('space_cache') # temporary + return space.do_operation('getitem', w_cache, w_key) def setup(space): - return { - pyframe.normalize_exception.get_function(space): prepare_raise, - } + fn = pyframe.normalize_exception.get_function(space) + fn._flowspecialcase_ = normalize_exception + fn = baseobjspace.ObjSpace.loadfromcache.im_func + fn._flowspecialcase_ = loadfromcache 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 Sat Jun 26 19:04:31 2004 @@ -4,6 +4,7 @@ from pypy.interpreter.typedef import instantiate, UserSubclass from pypy.objspace.std.multimethod import * from pypy.objspace.descroperation import DescrOperation +from pypy.objspace.std import stdtypedef import types @@ -207,12 +208,7 @@ def gettypeobject(self, typedef): # types_w maps each StdTypeDef instance to its # unique-for-this-space W_TypeObject instance - try: - w_type = self.types_w[typedef] - except KeyError: - from pypy.objspace.std.stdtypedef import buildtypeobject - w_type = self.types_w[typedef] = buildtypeobject(typedef, self) - return w_type + return self.loadfromcache(typedef, stdtypedef.buildtypeobject) def wrap(self, x): "Wraps the Python value 'x' into one of the wrapper classes." Modified: pypy/trunk/src/pypy/objspace/trace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trace.py (original) +++ pypy/trunk/src/pypy/objspace/trace.py Sat Jun 26 19:04:31 2004 @@ -132,7 +132,7 @@ saved = self.__result self.settrace() try: - return self.generalcache.setdefault(key, builder(self)) + return self.generalcache.setdefault(key, builder(key, self)) finally: self.__result = saved Modified: pypy/trunk/src/pypy/translator/translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/translator.py (original) +++ pypy/trunk/src/pypy/translator/translator.py Sat Jun 26 19:04:31 2004 @@ -62,7 +62,10 @@ graph = self.flowgraphs[func] except KeyError: if self.verbose: - print 'getflowgraph:', func.__name__ + print 'getflowgraph (%s:%d) %s' % ( + func.func_globals.get('__name__', '?'), + func.func_code.co_firstlineno, + func.__name__) im_func = getattr(func, 'im_func', func) im_self = getattr(func, 'im_self', None) if im_self is not None: # bound method? From arigo at codespeak.net Sat Jun 26 20:34:26 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 26 Jun 2004 20:34:26 +0200 (MEST) Subject: [pypy-svn] r5355 - in pypy/trunk/src: goal pypy/module pypy/objspace/flow Message-ID: <20040626183426.3950C5A11D@thoth.codespeak.net> Author: arigo Date: Sat Jun 26 20:34:25 2004 New Revision: 5355 Modified: pypy/trunk/src/goal/autopath.py pypy/trunk/src/pypy/module/__builtin__module.py pypy/trunk/src/pypy/objspace/flow/objspace.py Log: Some Python 2.2 compatibility. We still have some test failures and even a segfault with a Pyrex-compiled module -- but it only shows up in non-debug builds of Python <= 2.2.2 ! Not sure I want to investigate more. Modified: pypy/trunk/src/goal/autopath.py ============================================================================== --- pypy/trunk/src/goal/autopath.py (original) +++ pypy/trunk/src/goal/autopath.py Sat Jun 26 20:34:25 2004 @@ -1,3 +1,2 @@ import sys, os -sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir)) - +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 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 Sat Jun 26 20:34:25 2004 @@ -560,7 +560,10 @@ r[s] = value return r - dict.fromkeys = classmethod(_fromkeys) + try: + dict.fromkeys = classmethod(_fromkeys) + except TypeError: + pass # Python2.2 with trivial object space del _fromkeys Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/objspace.py Sat Jun 26 20:34:25 2004 @@ -192,12 +192,14 @@ def extract_cell_content(c): """Get the value contained in a CPython 'cell', as read through the func_closure of a function object.""" - import new - def hackout(): - return hackout # this access becomes a cell reference - # now change the cell to become 'c' - hackout = new.function(hackout.func_code, {}, '', None, (c,)) - return hackout() + # yuk! this is all I could come up with that works in Python 2.2 too + class X(object): + def __eq__(self, other): + self.other = other + x = X() + x_cell, = (lambda: x).func_closure + x_cell == c + return x.other def make_op(name, symbol, arity, specialnames): if hasattr(FlowObjSpace, name): From arigo at codespeak.net Sun Jun 27 12:42:42 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 27 Jun 2004 12:42:42 +0200 (MEST) Subject: [pypy-svn] r5362 - in pypy/trunk/src: goal pypy/interpreter pypy/objspace/flow pypy/objspace/flow/test pypy/translator pypy/translator/tool/pygame Message-ID: <20040627104242.997BB5ABA5@thoth.codespeak.net> Author: arigo Date: Sun Jun 27 12:42:41 2004 New Revision: 5362 Modified: pypy/trunk/src/goal/translate_pypy.py pypy/trunk/src/pypy/interpreter/eval.py pypy/trunk/src/pypy/objspace/flow/flowcontext.py pypy/trunk/src/pypy/objspace/flow/framestate.py pypy/trunk/src/pypy/objspace/flow/model.py pypy/trunk/src/pypy/objspace/flow/specialcase.py pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py pypy/trunk/src/pypy/translator/annrpython.py pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py pypy/trunk/src/pypy/translator/translator.py Log: Going a bit farther in translate_pypy with FlowObjSpace: * Support for default args * Fixed a problem with the 'del' statement (which is used implicitely by list comprehension) * Various interactive & debugging improvements Modified: pypy/trunk/src/goal/translate_pypy.py ============================================================================== --- pypy/trunk/src/goal/translate_pypy.py (original) +++ pypy/trunk/src/goal/translate_pypy.py Sun Jun 27 12:42:41 2004 @@ -38,7 +38,7 @@ import os os.putenv("PYTHONINSPECT", "1") - t = Translator(entry_point, verbose=True) + t = Translator(entry_point, verbose=True, simplifying=True) t.simplify() a = t.annotate([]) a.simplify() Modified: pypy/trunk/src/pypy/interpreter/eval.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/eval.py (original) +++ pypy/trunk/src/pypy/interpreter/eval.py Sun Jun 27 12:42:41 2004 @@ -49,7 +49,9 @@ def getdocstring(self): return None -UNDEFINED = object() # marker for undefined local variables +class UndefinedClass: + pass +UNDEFINED = UndefinedClass() # marker for undefined local variables class Frame(Wrappable): Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py Sun Jun 27 12:42:41 2004 @@ -86,11 +86,9 @@ self.closure = [Cell(Constant(value)) for value in closure] frame = self.create_frame() formalargcount = code.getformalargcount() - dummy = UndefinedConstant() arg_list = [Variable() for i in range(formalargcount)] for position, value in constargs.items(): arg_list[position] = Constant(value) - arg_list += [dummy] * (len(frame.fastlocals_w) - formalargcount) frame.setfastscope(arg_list) self.joinpoints = {} for joinpoint in code.getjoinpoints(): Modified: pypy/trunk/src/pypy/objspace/flow/framestate.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/framestate.py (original) +++ pypy/trunk/src/pypy/objspace/flow/framestate.py Sun Jun 27 12:42:41 2004 @@ -18,6 +18,9 @@ else: raise TypeError("can't get framestate for %r" % state.__class__.__name__) + for w1 in self.mergeable: + assert isinstance(w1, (Variable, Constant)), ( + '%r found in frame state' % w1) def restoreframe(self, frame): if isinstance(frame, PyFrame): @@ -82,8 +85,6 @@ for w_output, w_target in zip(self.mergeable, targetstate.mergeable): if isinstance(w_target, Variable): result.append(w_output) - elif not isinstance(w_target, Constant): - raise TypeError('output arg %r' % w_target.__class__.__name__) return result Modified: pypy/trunk/src/pypy/objspace/flow/model.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/model.py (original) +++ pypy/trunk/src/pypy/objspace/flow/model.py Sun Jun 27 12:42:41 2004 @@ -101,10 +101,13 @@ def __repr__(self): return '(%r)' % (self.value,) -class UndefinedConstant(Constant): - # for local variables not defined yet. - def __init__(self): - Constant.__init__(self, None) +# hack! it is useful to have UNDEFINED be an instance of Constant too. +# PyFrame then automatically uses this Constant as a marker for +# non-initialized variables. +from pypy.interpreter.eval import UNDEFINED +UndefinedConstant = UNDEFINED.__class__ +UndefinedConstant.__bases__ += (Constant,) +Constant.__init__(UNDEFINED, None) class SpaceOperation: def __init__(self, opname, args, result): Modified: pypy/trunk/src/pypy/objspace/flow/specialcase.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/specialcase.py (original) +++ pypy/trunk/src/pypy/objspace/flow/specialcase.py Sun Jun 27 12:42:41 2004 @@ -2,7 +2,7 @@ from pypy.interpreter import pyframe, baseobjspace from pypy.interpreter.error import OperationError from pypy.objspace.flow.objspace import UnwrapException -from pypy.objspace.flow.model import Variable, Constant +from pypy.objspace.flow.model import Constant def getconstclass(space, w_cls): @@ -28,8 +28,8 @@ w_arg1, w_arg2 = args.args_w etype = getconstclass(space, w_arg1) if etype is not None: - # raise Class or raise Class, Arg: ignore the Arg - return (w_arg1, Variable()) + # raise Class or raise Class, Arg: no normalization + return (w_arg1, w_arg2) else: # raise Instance: we need a hack to figure out of which class it is. # Normally, Instance should have been created by the previous operation Modified: pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Sun Jun 27 12:42:41 2004 @@ -246,6 +246,17 @@ x = self.codetest(self.raise3) self.show(x) + #__________________________________________________________ + def dellocal(): + x = 1 + del x + for i in range(10): + pass + + def test_dellocal(self): + x = self.codetest(self.dellocal) + self.show(x) + if __name__ == '__main__': testit.main() Modified: pypy/trunk/src/pypy/translator/annrpython.py ============================================================================== --- pypy/trunk/src/pypy/translator/annrpython.py (original) +++ pypy/trunk/src/pypy/translator/annrpython.py Sun Jun 27 12:42:41 2004 @@ -129,7 +129,13 @@ # generalize the function's input arguments block = graph.startblock inputcells = list(args) - assert len(inputcells) == len(block.inputargs) + # add default arguments if necessary + missingargs = len(block.inputargs) - len(inputcells) + if missingargs: + assert missingargs >= 0 + assert missingargs <= len(func.func_defaults or ()) + for extra in func.func_defaults[-missingargs:]: + inputcells.append(annmodel.immutablevalue(extra)) self.addpendingblock(block, inputcells) # get the (current) return value v = graph.getreturnvar() Modified: pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py (original) +++ pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py Sun Jun 27 12:42:41 2004 @@ -156,7 +156,7 @@ class GraphDisplay(Display): STATUSBARFONT = os.path.join(autopath.this_dir, 'VeraMoBd.ttf') - def __init__(self, translator): + def __init__(self, translator, functions=None): super(GraphDisplay, self).__init__() self.translator = translator self.annotator = translator.annotator @@ -168,11 +168,12 @@ self.variables_by_name[var.name] = var graphs = [] - for func in self.translator.functions: + functions = functions or self.translator.functions + for func in functions: graph = self.translator.getflowgraph(func) graphs.append((graph.name, graph)) - xdotfile = make_dot_graphs(self.translator.entrypoint.__name__, graphs, target='xdot') - pngfile = make_dot_graphs(self.translator.entrypoint.__name__, graphs, target='png') + xdotfile = make_dot_graphs(functions[0].__name__, graphs, target='xdot') + pngfile = make_dot_graphs(functions[0].__name__, graphs, target='png') self.viewer = GraphViewer(str(xdotfile), str(pngfile)) self.viewer.offsetx = (self.viewer.width - self.width) // 2 self.statusbarinfo = None Modified: pypy/trunk/src/pypy/translator/translator.py ============================================================================== --- pypy/trunk/src/pypy/translator/translator.py (original) +++ pypy/trunk/src/pypy/translator/translator.py Sun Jun 27 12:42:41 2004 @@ -43,9 +43,10 @@ class Translator: - def __init__(self, func, verbose=False): + def __init__(self, func, verbose=False, simplifying=False): self.entrypoint = func self.verbose = verbose + self.simplifying = simplifying self.clear() def clear(self): @@ -73,8 +74,10 @@ else: constargs = {} space = FlowObjSpace() - graph = self.flowgraphs[func] = space.build_flow(im_func, - constargs) + graph = space.build_flow(im_func, constargs) + if self.simplifying: + graph = simplify_graph(graph) + self.flowgraphs[func] = graph self.functions.append(func) try: import inspect @@ -100,11 +103,11 @@ dest = make_dot(graph.name, graph) os.system('gv %s' % str(dest)) - def view(self): + def view(self, *functions): """Shows the control flow graph with annotations if computed. Requires 'dot' and pygame.""" from pypy.translator.tool.pygame.graphviewer import GraphDisplay - GraphDisplay(self).run() + GraphDisplay(self, functions).run() def simplify(self, func=None): """Simplifies the control flow graph (default: for all functions).""" From arigo at codespeak.net Sun Jun 27 13:18:30 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 27 Jun 2004 13:18:30 +0200 (MEST) Subject: [pypy-svn] r5363 - in pypy/trunk/src: goal pypy/annotation pypy/interpreter Message-ID: <20040627111830.C4B3B5ABA5@thoth.codespeak.net> Author: arigo Date: Sun Jun 27 13:18:30 2004 New Revision: 5363 Modified: pypy/trunk/src/goal/translate_pypy.py pypy/trunk/src/pypy/annotation/binaryop.py pypy/trunk/src/pypy/annotation/builtin.py pypy/trunk/src/pypy/annotation/model.py pypy/trunk/src/pypy/interpreter/pyframe.py Log: Progress on translate_pypy. * Unsigned integers Modified: pypy/trunk/src/goal/translate_pypy.py ============================================================================== --- pypy/trunk/src/goal/translate_pypy.py (original) +++ pypy/trunk/src/goal/translate_pypy.py Sun Jun 27 13:18:30 2004 @@ -6,9 +6,7 @@ from pypy.objspace.std.objspace import StdObjSpace, W_Object from pypy.objspace.std.intobject import W_IntObject -from pypy.objspace.std.restricted_int import r_int from pypy.translator.translator import Translator -from pypy.annotation import model as annmodel # __________ Entry point __________ @@ -21,24 +19,18 @@ return space.mul(w_a, w_b) -# __________ Special cases __________ - -def special_immutablevalue(x): - if x is r_int: - x = int - return general_immutablevalue(x) - -general_immutablevalue = annmodel.immutablevalue -annmodel.immutablevalue = special_immutablevalue - # __________ Main __________ if __name__ == '__main__': - # 2.3 specific - import os - os.putenv("PYTHONINSPECT", "1") - t = Translator(entry_point, verbose=True, simplifying=True) - t.simplify() - a = t.annotate([]) - a.simplify() + try: + a = t.annotate([]) + #a.simplify() + except: + import sys, traceback + exc, val, tb = sys.exc_info() + print >> sys.stderr + traceback.print_exception(exc, val, tb) + print >> sys.stderr + import pdb + pdb.post_mortem(tb) Modified: pypy/trunk/src/pypy/annotation/binaryop.py ============================================================================== --- pypy/trunk/src/pypy/annotation/binaryop.py (original) +++ pypy/trunk/src/pypy/annotation/binaryop.py Sun Jun 27 13:18:30 2004 @@ -39,17 +39,20 @@ class __extend__(pairtype(SomeInteger, SomeInteger)): + # unsignedness is considered a rare and contagious disease def union((int1, int2)): - return SomeInteger(nonneg = int1.nonneg and int2.nonneg) + return SomeInteger(nonneg = int1.nonneg and int2.nonneg, + unsigned = int1.unsigned or int2.unsigned) def add((int1, int2)): - return SomeInteger(nonneg = int1.nonneg and int2.nonneg) + return SomeInteger(nonneg = int1.nonneg and int2.nonneg, + unsigned = int1.unsigned or int2.unsigned) mul = div = mod = add def sub((int1, int2)): - return SomeInteger() + return SomeInteger(unsigned = int1.unsigned or int2.unsigned) def lt((int1, int2)): return SomeBool() def le((int1, int2)): return SomeBool() Modified: pypy/trunk/src/pypy/annotation/builtin.py ============================================================================== --- pypy/trunk/src/pypy/annotation/builtin.py (original) +++ pypy/trunk/src/pypy/annotation/builtin.py Sun Jun 27 13:18:30 2004 @@ -4,6 +4,7 @@ from pypy.annotation.model import SomeInteger, SomeObject from pypy.annotation.factory import ListFactory, getbookkeeper +import pypy.objspace.std.restricted_int def builtin_len(s_obj): @@ -21,10 +22,10 @@ return SomeObject() def builtin_int(s_obj): # we can consider 'int' as a function - if isinstance(s_obj, SomeInteger): - return s_obj - else: - return SomeInteger() + return SomeInteger() + +def restricted_uint(s_obj): # for r_uint + return SomeInteger(nonneg=True, unsigned=True) # collect all functions @@ -34,3 +35,6 @@ if name.startswith('builtin_'): original = getattr(__builtin__, name[8:]) BUILTIN_FUNCTIONS[original] = value + +BUILTIN_FUNCTIONS[pypy.objspace.std.restricted_int.r_int] = builtin_int +BUILTIN_FUNCTIONS[pypy.objspace.std.restricted_int.r_uint] = restricted_uint Modified: pypy/trunk/src/pypy/annotation/model.py ============================================================================== --- pypy/trunk/src/pypy/annotation/model.py (original) +++ pypy/trunk/src/pypy/annotation/model.py Sun Jun 27 13:18:30 2004 @@ -53,13 +53,15 @@ class SomeInteger(SomeObject): "Stands for an object which is known to be an integer." knowntype = int - def __init__(self, nonneg=False): + def __init__(self, nonneg=False, unsigned=False): self.nonneg = nonneg + self.unsigned = unsigned # pypy.objspace.std.restricted_int.r_uint class SomeBool(SomeInteger): "Stands for true or false." knowntype = bool nonneg = True + unsigned = False def __init__(self): pass Modified: pypy/trunk/src/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/src/pypy/interpreter/pyframe.py Sun Jun 27 13:18:30 2004 @@ -149,14 +149,13 @@ operationerr = unroller.args[0] w_type = operationerr.w_type w_value = operationerr.w_value - if frame.space.full_exceptions: - w_normalized = normalize_exception(frame.space, w_type, w_value) - w_type, w_value = frame.space.unpacktuple(w_normalized, 2) - # save the normalized exception back into the OperationError - # -- in particular it makes sure that sys.exc_info() etc see - # normalized exception. - operationerr.w_type = w_type - operationerr.w_value = w_value + w_normalized = normalize_exception(frame.space, w_type, w_value) + w_type, w_value = frame.space.unpacktuple(w_normalized, 2) + # save the normalized exception back into the OperationError + # -- in particular it makes sure that sys.exc_info() etc see + # normalized exception. + operationerr.w_type = w_type + operationerr.w_value = w_value # the stack setup is slightly different than in CPython: # instead of the traceback, we store the unroller object, # wrapped. From rocco at codespeak.net Sun Jun 27 22:53:28 2004 From: rocco at codespeak.net (rocco at codespeak.net) Date: Sun, 27 Jun 2004 22:53:28 +0200 (MEST) Subject: [pypy-svn] r5369 - in pypy/trunk/src/pypy: scripttest scripttest/test tool Message-ID: <20040627205328.E1C995ABA5@thoth.codespeak.net> Author: rocco Date: Sun Jun 27 22:53:28 2004 New Revision: 5369 Added: pypy/trunk/src/pypy/scripttest/ (props changed) pypy/trunk/src/pypy/scripttest/__init__.py (contents, props changed) pypy/trunk/src/pypy/scripttest/autopath.py (contents, props changed) pypy/trunk/src/pypy/scripttest/grammar.py (contents, props changed) pypy/trunk/src/pypy/scripttest/grammar.txt (contents, props changed) pypy/trunk/src/pypy/scripttest/test/ (props changed) pypy/trunk/src/pypy/scripttest/test/__init__.py (contents, props changed) pypy/trunk/src/pypy/scripttest/test/autopath.py (contents, props changed) pypy/trunk/src/pypy/scripttest/test/test_grammar.py (contents, props changed) pypy/trunk/src/pypy/scripttest/test/test_tutorial.py (contents, props changed) pypy/trunk/src/pypy/scripttest/tutorial.py (contents, props changed) pypy/trunk/src/pypy/scripttest/tutorial.txt (contents, props changed) pypy/trunk/src/pypy/tool/app_level_diff.py (contents, props changed) Log: * tool/app_level_diff.py I hacked together a little tool for running a script at app level, and checking its output against an expected output file. (Sort of like regrtest.py) I added a feature where the files can be sectioned off into multiple parts, to reduce disk clutter. * scripttest directory The start of using app_level_diff as a testing tool - I've converted the CPython regression test test_grammar to it's use. Sectioning is incomplete - the parts that are sectioned are mainly to isolate failures I've also started to do a script made from the examples given in Guido's tutorial. Incomplete as of now. I've commented out the tests that fail - These have to do with lambdas, the exec statement, exponentiation, and imaginary numbers. Added: pypy/trunk/src/pypy/scripttest/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/__init__.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1 @@ +# Added: pypy/trunk/src/pypy/scripttest/autopath.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/autopath.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1,80 @@ +""" +self cloning, automatic path configuration + +copy this into any subdirectory of pypy from which scripts need +to be run, typically all of the test subdirs. +The idea is that any such script simply issues + + import autopath + +and this will make sure that the parent directory containing "pypy" +is in sys.path. + +If you modify the master "autopath.py" version (in pypy/tool/autopath.py) +you can directly run it which will copy itself on all autopath.py files +it finds under the pypy root directory. + +This module always provides these attributes: + + pypydir pypy root directory path + this_dir directory where this autopath.py resides + +""" + + +def __dirinfo(part): + """ return (partdir, this_dir) and insert parent of partdir + into sys.path. If the parent directories dont have the part + an EnvironmentError is raised.""" + + import sys, os + try: + head = this_dir = os.path.abspath(os.path.dirname(__file__)) + except NameError: + head = this_dir = os.path.abspath(os.path.dirname(sys.argv[0])) + + while head: + partdir = head + head, tail = os.path.split(head) + if tail == part: + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) + return partdir, this_dir + + raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) + +def __clone(): + """ clone master version of autopath.py into all subdirs """ + from os.path import join, walk + if not this_dir.endswith(join('pypy','tool')): + raise EnvironmentError("can only clone master version " + "'%s'" % join(pypydir, 'tool',_myname)) + + + def sync_walker(arg, dirname, fnames): + if _myname in fnames: + fn = join(dirname, _myname) + f = open(fn, 'rwb+') + try: + if f.read() == arg: + print "checkok", fn + else: + print "syncing", fn + f = open(fn, 'w') + f.write(arg) + finally: + f.close() + s = open(join(pypydir, 'tool', _myname), 'rb').read() + walk(pypydir, sync_walker, s) + +_myname = 'autopath.py' + +# set guaranteed attributes + +pypydir, this_dir = __dirinfo('pypy') + +if __name__ == '__main__': + __clone() Added: pypy/trunk/src/pypy/scripttest/grammar.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/grammar.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1,788 @@ +# Python test set -- part 1, grammar. +# This just tests whether the parser accepts them all. + +# NOTE: When you run this test as a script from the command line, you +# get warnings about certain hex/oct constants. Since those are +# issued by the parser, you can't suppress them by adding a +# filterwarnings() call to this module. + +# This is a modified version of the file found in the CPython Regression tests +# Not all subsections have been broken apart - only enough to isolate +# failures. Some sections need to remain combined due to dependancies on +# definitions in previous sections. + + +import sys + +def verify(condition, reason='test failed'): + if not condition: + print 'TestFailed -', reason + +def check_syntax(statement): + try: + compile(statement, '', 'exec') + except SyntaxError: + pass + else: + print 'Missing SyntaxError: "%s"' % statement + +##! Section 1. + +print '1. Parser' + +print '1.1 Tokens' + +print '1.1.1 Backslashes' + +# Backslash means line continuation: +x = 1 \ ++ 1 +if x != 2: print 'Test Failed -', 'backslash for line continuation' + +# Backslash does not means continuation in comments :\ +x = 0 +if x != 0: print 'Test Failed -', 'backslash ending comment' + +print '1.1.2 Numeric literals' + +print '1.1.2.1 Plain integers' +if 0xff != 255: print 'Test Failed -', 'hex int' +if 0377 != 255: print 'Test Failed -', 'octal int' +if 2147483647 != 017777777777: print 'Test Failed -', 'large positive int' +try: + from sys import maxint +except ImportError: + maxint = 2147483647 +if maxint == 2147483647: + # The following test will start to fail in Python 2.4; + # change the 020000000000 to -020000000000 + if -2147483647-1 != 020000000000: print 'Test Failed -', 'max negative int' + # XXX -2147483648 + if 037777777777 != -1: print 'Test Failed -', 'oct -1' + if 0xffffffff != -1: print 'Test Failed -', 'hex -1' + for s in '2147483648', '040000000000', '0x100000000': + try: + x = eval(s) + except OverflowError: + print "OverflowError on huge integer literal " + `s` +elif eval('maxint == 9223372036854775807'): + if eval('-9223372036854775807-1 != 01000000000000000000000'): + print 'Test Failed -', 'max negative int' + if eval('01777777777777777777777') != -1: print 'Test Failed -', 'oct -1' + if eval('0xffffffffffffffff') != -1: print 'Test Failed -', 'hex -1' + for s in '9223372036854775808', '02000000000000000000000', \ + '0x10000000000000000': + try: + x = eval(s) + except OverflowError: + print "OverflowError on huge integer literal " + `s` +else: + print 'Weird maxint value', maxint + +print '1.1.2.2 Long integers' +x = 0L +x = 0l +x = 0xffffffffffffffffL +x = 0xffffffffffffffffl +x = 077777777777777777L +x = 077777777777777777l +x = 123456789012345678901234567890L +x = 123456789012345678901234567890l + +print '1.1.2.3 Floating point' +x = 3.14 +x = 314. +x = 0.314 +# XXX x = 000.314 +x = .314 +x = 3e14 +x = 3E14 +x = 3e-14 +x = 3e+14 +x = 3.e14 +x = .3e14 +x = 3.1e4 + +print '1.1.3 String literals' + +x = ''; y = ""; verify(len(x) == 0 and x == y) +x = '\''; y = "'"; verify(len(x) == 1 and x == y and ord(x) == 39) +x = '"'; y = "\""; verify(len(x) == 1 and x == y and ord(x) == 34) +x = "doesn't \"shrink\" does it" +y = 'doesn\'t "shrink" does it' +verify(len(x) == 24 and x == y) +x = "does \"shrink\" doesn't it" +y = 'does "shrink" doesn\'t it' +verify(len(x) == 24 and x == y) +x = """ +The "quick" +brown fox +jumps over +the 'lazy' dog. +""" +y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' +verify(x == y) +y = ''' +The "quick" +brown fox +jumps over +the 'lazy' dog. +'''; verify(x == y) +y = "\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the 'lazy' dog.\n\ +"; verify(x == y) +y = '\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the \'lazy\' dog.\n\ +'; verify(x == y) + + +print '1.2 Grammar' + +print 'single_input' # NEWLINE | simple_stmt | compound_stmt NEWLINE +# XXX can't test in a script -- this rule is only used when interactive + +print 'file_input' # (NEWLINE | stmt)* ENDMARKER +# Being tested as this very moment this very module + +print 'expr_input' # testlist NEWLINE +# XXX Hard to test -- used only in calls to input() + +print 'eval_input' # testlist ENDMARKER +x = eval('1, 0 or 1') + +print 'funcdef' +### 'def' NAME parameters ':' suite +### parameters: '(' [varargslist] ')' +### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] +### | ('**'|'*' '*') NAME) +### | fpdef ['=' test] (',' fpdef ['=' test])* [','] +### fpdef: NAME | '(' fplist ')' +### fplist: fpdef (',' fpdef)* [','] +### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) +### argument: [test '='] test # Really [keyword '='] test +def f1(): pass +f1() +f1(*()) +f1(*(), **{}) +def f2(one_argument): pass +def f3(two, arguments): pass +def f4(two, (compound, (argument, list))): pass +def f5((compound, first), two): pass +verify(f2.func_code.co_varnames == ('one_argument',)) +verify(f3.func_code.co_varnames == ('two', 'arguments')) +if sys.platform.startswith('java'): + verify(f4.func_code.co_varnames == + ('two', '(compound, (argument, list))', 'compound', 'argument', + 'list',)) + verify(f5.func_code.co_varnames == + ('(compound, first)', 'two', 'compound', 'first')) +else: + verify(f4.func_code.co_varnames == ('two', '.2', 'compound', + 'argument', 'list')) + verify(f5.func_code.co_varnames == ('.0', 'two', 'compound', 'first')) +def a1(one_arg,): pass +def a2(two, args,): pass +def v0(*rest): pass +def v1(a, *rest): pass +def v2(a, b, *rest): pass +def v3(a, (b, c), *rest): return a, b, c, rest +if sys.platform.startswith('java'): + verify(v3.func_code.co_varnames == ('a', '(b, c)', 'rest', 'b', 'c')) +else: + verify(v3.func_code.co_varnames == ('a', '.2', 'rest', 'b', 'c')) +verify(v3(1, (2, 3), 4) == (1, 2, 3, (4,))) +def d01(a=1): pass +d01() +d01(1) +d01(*(1,)) +d01(**{'a':2}) +def d11(a, b=1): pass +d11(1) +d11(1, 2) +d11(1, **{'b':2}) +def d21(a, b, c=1): pass +d21(1, 2) +d21(1, 2, 3) +d21(*(1, 2, 3)) +d21(1, *(2, 3)) +d21(1, 2, *(3,)) +d21(1, 2, **{'c':3}) +def d02(a=1, b=2): pass +d02() +d02(1) +d02(1, 2) +d02(*(1, 2)) +d02(1, *(2,)) +d02(1, **{'b':2}) +d02(**{'a': 1, 'b': 2}) +def d12(a, b=1, c=2): pass +d12(1) +d12(1, 2) +d12(1, 2, 3) +def d22(a, b, c=1, d=2): pass +d22(1, 2) +d22(1, 2, 3) +d22(1, 2, 3, 4) +def d01v(a=1, *rest): pass +d01v() +d01v(1) +d01v(1, 2) +d01v(*(1, 2, 3, 4)) +d01v(*(1,)) +d01v(**{'a':2}) +def d11v(a, b=1, *rest): pass +d11v(1) +d11v(1, 2) +d11v(1, 2, 3) +def d21v(a, b, c=1, *rest): pass +d21v(1, 2) +d21v(1, 2, 3) +d21v(1, 2, 3, 4) +d21v(*(1, 2, 3, 4)) +d21v(1, 2, **{'c': 3}) +def d02v(a=1, b=2, *rest): pass +d02v() +d02v(1) +d02v(1, 2) +d02v(1, 2, 3) +d02v(1, *(2, 3, 4)) +d02v(**{'a': 1, 'b': 2}) +def d12v(a, b=1, c=2, *rest): pass +d12v(1) +d12v(1, 2) +d12v(1, 2, 3) +d12v(1, 2, 3, 4) +d12v(*(1, 2, 3, 4)) +d12v(1, 2, *(3, 4, 5)) +d12v(1, *(2,), **{'c': 3}) +def d22v(a, b, c=1, d=2, *rest): pass +d22v(1, 2) +d22v(1, 2, 3) +d22v(1, 2, 3, 4) +d22v(1, 2, 3, 4, 5) +d22v(*(1, 2, 3, 4)) +d22v(1, 2, *(3, 4, 5)) +d22v(1, *(2, 3), **{'d': 4}) + +print 'selectors' +### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME +### subscript: expr | [expr] ':' [expr] +f1() +f2(1) +f2(1,) +f3(1, 2) +f3(1, 2,) +f4(1, (2, (3, 4))) +v0() +v0(1) +v0(1,) +v0(1,2) +v0(1,2,3,4,5,6,7,8,9,0) +v1(1) +v1(1,) +v1(1,2) +v1(1,2,3) +v1(1,2,3,4,5,6,7,8,9,0) +v2(1,2) +v2(1,2,3) +v2(1,2,3,4) +v2(1,2,3,4,5,6,7,8,9,0) +v3(1,(2,3)) +v3(1,(2,3),4) +v3(1,(2,3),4,5,6,7,8,9,0) + +print +##! Section lambdef + +### lambdef: 'lambda' [varargslist] ':' test +print 'lambdef' +l1 = lambda : 0 +verify(l1() == 0) +l2 = lambda : a[d] # XXX just testing the expression +l3 = lambda : [2 < x for x in [-1, 3, 0L]] +verify(l3() == [0, 1, 0]) +l4 = lambda x = lambda y = lambda z=1 : z : y() : x() +verify(l4() == 1) +l5 = lambda x, y, z=2: x + y + z +verify(l5(1, 2) == 5) +verify(l5(1, 2, 3) == 6) +check_syntax("lambda x: x = 2") + +print +##! Section simple_stmt + +### stmt: simple_stmt | compound_stmt +# Tested below + +### simple_stmt: small_stmt (';' small_stmt)* [';'] +print 'simple_stmt' +x = 1; pass; del x + +### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt +# Tested below + +print 'expr_stmt' # (exprlist '=')* exprlist +1 +1, 2, 3 +x = 1 +x = 1, 2, 3 +x = y = z = 1, 2, 3 +x, y, z = 1, 2, 3 +abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) +# NB these variables are deleted below + +check_syntax("x + 1 = 1") +check_syntax("a + 1 = b + 2") + +print 'del_stmt' # 'del' exprlist +del abc +del x, y, (z, xyz) + +print 'print_stmt' # 'print' (test ',')* [test] +print 1, 2, 3 +print 1, 2, 3, +print +print 0 or 1, 0 or 1, +print 0 or 1 + + +print +##! Section extended print_stmt + +print 'extended print_stmt' # 'print' '>>' test ',' +import sys +print >> sys.stdout, 1, 2, 3 +print >> sys.stdout, 1, 2, 3, +print >> sys.stdout +print >> sys.stdout, 0 or 1, 0 or 1, +print >> sys.stdout, 0 or 1 + +# test printing to an instance +class Gulp: + def write(self, msg): pass + +gulp = Gulp() +print >> gulp, 1, 2, 3 +print >> gulp, 1, 2, 3, +print >> gulp +print >> gulp, 0 or 1, 0 or 1, +print >> gulp, 0 or 1 + +# test print >> None +def driver(): + oldstdout = sys.stdout + sys.stdout = Gulp() + try: + tellme(Gulp()) + tellme() + finally: + sys.stdout = oldstdout + +# we should see this once +def tellme(file=sys.stdout): + print >> file, 'hello world' + +driver() + +# we should not see this at all +def tellme(file=None): + print >> file, 'goodbye universe' + +driver() + +# syntax errors +check_syntax('print ,') +check_syntax('print >> x,') + +print +##! Section pass_stmt +print 'pass_stmt' # 'pass' +pass + +print 'flow_stmt' # break_stmt | continue_stmt | return_stmt | raise_stmt +# Tested below + +print 'break_stmt' # 'break' +while 1: break + +print +##! Section continue_stmt +print 'continue_stmt' # 'continue' +i = 1 +while i: i = 0; continue + +msg = "" +while not msg: + msg = "continue + try/except ok" + try: + continue + msg = "continue failed to continue inside try" + except: + msg = "continue inside try called except block" +print msg + +msg = "" +while not msg: + msg = "finally block not called" + try: + continue + finally: + msg = "continue + try/finally ok" +print msg + + +# This test warrants an explanation. It is a test specifically for SF bugs +# #463359 and #462937. The bug is that a 'break' statement executed or +# exception raised inside a try/except inside a loop, *after* a continue +# statement has been executed in that loop, will cause the wrong number of +# arguments to be popped off the stack and the instruction pointer reset to +# a very small number (usually 0.) Because of this, the following test +# *must* written as a function, and the tracking vars *must* be function +# arguments with default values. Otherwise, the test will loop and loop. + +print "testing continue and break in try/except in loop" +def test_break_continue_loop(extra_burning_oil = 1, count=0): + big_hippo = 2 + while big_hippo: + count += 1 + try: + if extra_burning_oil and big_hippo == 1: + extra_burning_oil -= 1 + break + big_hippo -= 1 + continue + except: + raise + if count > 2 or big_hippo <> 1: + print "continue then break in try/except in loop broken!" +test_break_continue_loop() + +print +##! Section return_stmt + +print 'return_stmt' # 'return' [testlist] +def g1(): return +def g2(): return 1 +g1() +x = g2() + +print 'raise_stmt' # 'raise' test [',' test] +try: raise RuntimeError, 'just testing' +except RuntimeError: pass +try: raise KeyboardInterrupt +except KeyboardInterrupt: pass + +print 'import_stmt' # 'import' NAME (',' NAME)* | 'from' NAME 'import' ('*' | NAME (',' NAME)*) +import sys +import time, sys +from time import time +from sys import * +from sys import path, argv + + +print +##! Section global_stmt + +print 'global_stmt' # 'global' NAME (',' NAME)* +def f(): + global a + global a, b + global one, two, three, four, five, six, seven, eight, nine, ten + +print +##! Section exec_stmt + +print 'exec_stmt' # 'exec' expr ['in' expr [',' expr]] +def f(): + z = None + del z + exec 'z=1+1\n' + if z != 2: print 'Test Failed -', 'exec \'z=1+1\'\\n' + del z + exec 'z=1+1' + if z != 2: print 'Test Failed -', 'exec \'z=1+1\'' + z = None + del z + import types + if hasattr(types, "UnicodeType"): + exec r"""if 1: + exec u'z=1+1\n' + if z != 2: print 'Test Failed -', 'exec u\'z=1+1\'\\n' + del z + exec u'z=1+1' + if z != 2: print 'Test Failed -', 'exec u\'z=1+1\'' +""" +f() +g = {} +exec 'z = 1' in g +if g.has_key('__builtins__'): del g['__builtins__'] +if g != {'z': 1}: print 'Test Failed -', 'exec \'z = 1\' in g' +g = {} +l = {} + +import warnings +warnings.filterwarnings("ignore", "global statement", module="") +exec 'global a; a = 1; b = 2' in g, l +if g.has_key('__builtins__'): del g['__builtins__'] +if l.has_key('__builtins__'): del l['__builtins__'] +if (g, l) != ({'a':1}, {'b':2}): print 'Test Failed -', 'exec ... in g (%s), l (%s)' %(g,l) + +print +##! Section assert_stmt + +print "assert_stmt" # assert_stmt: 'assert' test [',' test] +assert 1 +assert 1, 1 +assert lambda x:x +assert 1, lambda x:x+1 + +### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef +# Tested below + +print 'if_stmt' # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] +if 1: pass +if 1: pass +else: pass +if 0: pass +elif 0: pass +if 0: pass +elif 0: pass +elif 0: pass +elif 0: pass +else: pass + +print 'while_stmt' # 'while' test ':' suite ['else' ':' suite] +while 0: pass +while 0: pass +else: pass + +print 'for_stmt' # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] +for i in 1, 2, 3: pass +for i, j, k in (): pass +else: pass +class Squares: + def __init__(self, max): + self.max = max + self.sofar = [] + def __len__(self): return len(self.sofar) + def __getitem__(self, i): + if not 0 <= i < self.max: raise IndexError + n = len(self.sofar) + while n <= i: + self.sofar.append(n*n) + n = n+1 + return self.sofar[i] +n = 0 +for x in Squares(10): n = n+x +if n != 285: print 'Test Failed -', 'for over growing sequence' + +print 'try_stmt' +### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] +### | 'try' ':' suite 'finally' ':' suite +### except_clause: 'except' [expr [',' expr]] +try: + 1/0 +except ZeroDivisionError: + pass +else: + pass +try: 1/0 +except EOFError: pass +except TypeError, msg: pass +except RuntimeError, msg: pass +except: pass +else: pass +try: 1/0 +except (EOFError, TypeError, ZeroDivisionError): pass +try: 1/0 +except (EOFError, TypeError, ZeroDivisionError), msg: pass +try: pass +finally: pass + +print 'suite' # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT +if 1: pass +if 1: + pass +if 1: + # + # + # + pass + pass + # + pass + # + +print 'test' +### and_test ('or' and_test)* +### and_test: not_test ('and' not_test)* +### not_test: 'not' not_test | comparison +if not 1: pass +if 1 and 1: pass +if 1 or 1: pass +if not not not 1: pass +if not 1 and 1 and 1: pass +if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass + +print 'comparison' +### comparison: expr (comp_op expr)* +### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +if 1: pass +x = (1 == 1) +if 1 == 1: pass +if 1 != 1: pass +if 1 <> 1: pass +if 1 < 1: pass +if 1 > 1: pass +if 1 <= 1: pass +if 1 >= 1: pass +if 1 is 1: pass +if 1 is not 1: pass +if 1 in (): pass +if 1 not in (): pass +if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass + +print 'binary mask ops' +x = 1 & 1 +x = 1 ^ 1 +x = 1 | 1 + +print 'shift ops' +x = 1 << 1 +x = 1 >> 1 +x = 1 << 1 >> 1 + +print 'additive ops' +x = 1 +x = 1 + 1 +x = 1 - 1 - 1 +x = 1 - 1 + 1 - 1 + 1 + +print 'multiplicative ops' +x = 1 * 1 +x = 1 / 1 +x = 1 % 1 +x = 1 / 1 * 1 % 1 + +print 'unary ops' +x = +1 +x = -1 +x = ~1 +x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 +x = -1*1/1 + 1*1 - ---1*1 + +print +import sys, time +c = sys.path[0] +x = time.time() +x = sys.modules['time'].time() +a = '01234' +c = a[0] +c = a[-1] +s = a[0:5] +s = a[:5] +s = a[0:] +s = a[:] +s = a[-5:] +s = a[:-1] +s = a[-4:-3] + +print 'atoms' +### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING +### dictmaker: test ':' test (',' test ':' test)* [','] + +x = (1) +x = (1 or 2 or 3) +x = (1 or 2 or 3, 2, 3) + +x = [] +x = [1] +x = [1 or 2 or 3] +x = [1 or 2 or 3, 2, 3] +x = [] + +x = {} +x = {'one': 1} +x = {'one': 1,} +x = {'one' or 'two': 1 or 2} +x = {'one': 1, 'two': 2} +x = {'one': 1, 'two': 2,} +x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} + +x = `x` +x = `1 or 2 or 3` +x = x +x = 'x' +x = 123 + +### exprlist: expr (',' expr)* [','] +### testlist: test (',' test)* [','] +# These have been exercised enough above + +print 'classdef' # 'class' NAME ['(' testlist ')'] ':' suite +class B: pass +class C1(B): pass +class C2(B): pass +class D(C1, C2, B): pass +class C: + def meth1(self): pass + def meth2(self, arg): pass + def meth3(self, a1, a2): pass + +print +##! Section list_comps + +# list comprehension tests +nums = [1, 2, 3, 4, 5] +strs = ["Apple", "Banana", "Coconut"] +spcs = [" Apple", " Banana ", "Coco nut "] + +print [s.strip() for s in spcs] +print [3 * x for x in nums] +print [x for x in nums if x > 2] +print [(i, s) for i in nums for s in strs] +print [(i, s) for i in nums for s in [f for f in strs if "n" in f]] +print [(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)] + +def test_in_func(l): + return [None < x < 3 for x in l if x > 2] + +print test_in_func(nums) + +def test_nested_front(): + print [[y for y in [x, x + 1]] for x in [1,3,5]] + +test_nested_front() + +check_syntax("[i, s for i in nums for s in strs]") +check_syntax("[x if y]") + +suppliers = [ + (1, "Boeing"), + (2, "Ford"), + (3, "Macdonalds") +] + +parts = [ + (10, "Airliner"), + (20, "Engine"), + (30, "Cheeseburger") +] + +suppart = [ + (1, 10), (1, 20), (2, 20), (3, 30) +] + +print [ + (sname, pname) + for (sno, sname) in suppliers + for (pno, pname) in parts + for (sp_sno, sp_pno) in suppart + if sno == sp_sno and pno == sp_pno +] Added: pypy/trunk/src/pypy/scripttest/grammar.txt ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/grammar.txt Sun Jun 27 22:53:28 2004 @@ -0,0 +1,86 @@ +##! Section 1. +1. Parser +1.1 Tokens +1.1.1 Backslashes +1.1.2 Numeric literals +1.1.2.1 Plain integers +1.1.2.2 Long integers +1.1.2.3 Floating point +1.1.3 String literals +1.2 Grammar +single_input +file_input +expr_input +eval_input +funcdef +selectors + +##! Section lambdef +lambdef + +##! Section simple_stmt +simple_stmt +expr_stmt +del_stmt +print_stmt +1 2 3 +1 2 3 +1 1 1 + +##! Section extended print_stmt +extended print_stmt +1 2 3 +1 2 3 +1 1 1 +hello world + +##! Section pass_stmt +pass_stmt +flow_stmt +break_stmt + +##! Section continue_stmt +continue_stmt +continue + try/except ok +continue + try/finally ok +testing continue and break in try/except in loop + +##! Section return_stmt +return_stmt +raise_stmt +import_stmt + +##! Section global_stmt +global_stmt + +##! Section exec_stmt +exec_stmt + +##! Section assert_stmt +assert_stmt +if_stmt +while_stmt +for_stmt +try_stmt +suite +test +comparison +binary mask ops +shift ops +additive ops +multiplicative ops +unary ops + +atoms +classdef + +##! Section list_comps +['Apple', 'Banana', 'Coco nut'] +[3, 6, 9, 12, 15] +[3, 4, 5] +[(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')] +[(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), (5, 'Banana'), (5, 'Coconut')] +[[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]] +[False, False, False] +[[1, 2], [3, 4], [5, 6]] +[('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')] \ No newline at end of file Added: pypy/trunk/src/pypy/scripttest/test/__init__.py ============================================================================== Added: pypy/trunk/src/pypy/scripttest/test/autopath.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/test/autopath.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1,80 @@ +""" +self cloning, automatic path configuration + +copy this into any subdirectory of pypy from which scripts need +to be run, typically all of the test subdirs. +The idea is that any such script simply issues + + import autopath + +and this will make sure that the parent directory containing "pypy" +is in sys.path. + +If you modify the master "autopath.py" version (in pypy/tool/autopath.py) +you can directly run it which will copy itself on all autopath.py files +it finds under the pypy root directory. + +This module always provides these attributes: + + pypydir pypy root directory path + this_dir directory where this autopath.py resides + +""" + + +def __dirinfo(part): + """ return (partdir, this_dir) and insert parent of partdir + into sys.path. If the parent directories dont have the part + an EnvironmentError is raised.""" + + import sys, os + try: + head = this_dir = os.path.abspath(os.path.dirname(__file__)) + except NameError: + head = this_dir = os.path.abspath(os.path.dirname(sys.argv[0])) + + while head: + partdir = head + head, tail = os.path.split(head) + if tail == part: + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) + return partdir, this_dir + + raise EnvironmentError, "'%s' missing in '%r'" % (pathpart,this_path) + +def __clone(): + """ clone master version of autopath.py into all subdirs """ + from os.path import join, walk + if not this_dir.endswith(join('pypy','tool')): + raise EnvironmentError("can only clone master version " + "'%s'" % join(pypydir, 'tool',_myname)) + + + def sync_walker(arg, dirname, fnames): + if _myname in fnames: + fn = join(dirname, _myname) + f = open(fn, 'rwb+') + try: + if f.read() == arg: + print "checkok", fn + else: + print "syncing", fn + f = open(fn, 'w') + f.write(arg) + finally: + f.close() + s = open(join(pypydir, 'tool', _myname), 'rb').read() + walk(pypydir, sync_walker, s) + +_myname = 'autopath.py' + +# set guaranteed attributes + +pypydir, this_dir = __dirinfo('pypy') + +if __name__ == '__main__': + __clone() Added: pypy/trunk/src/pypy/scripttest/test/test_grammar.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/test/test_grammar.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1,46 @@ +import autopath +import os, os.path +from pypy.tool import testit, app_level_diff + +filename = os.path.join(os.path.dirname(__file__), os.pardir, 'grammar.py') + +# Test the functionallity of the CPython test_grammar.py regression test + +class TestGrammar(testit.IntTestCase): + def setUp(self): + self.space = testit.objspace() + def _section_test(self, section): + diff = app_level_diff.compare(self.space, filename, section) + if diff: + raise AssertionError('Tutorial test failed - ' \ + "run test_grammar.details('%s')" % section) + def test_Section_1(self): + self._section_test('Section 1.') +## def xxx_test_Section_lambdef(self): +## self._section_test('Section lambdef') + def test_Section_simple_stmt(self): + self._section_test('Section simple_stmt') + def test_Section_extended_print_stmt(self): + self._section_test('Section extended print_stmt') + def test_Section_pass_stmt(self): + self._section_test('Section pass_stmt') + def test_Section_continue_stmt(self): + self._section_test('Section continue_stmt') + def test_Section_return_stmt(self): + self._section_test('Section return_stmt') + def test_Section_global_stmt(self): + self._section_test('Section global_stmt') +## def xxx_test_Section_exec_stmt(self): +## self._section_test('Section exec_stmt') + def test_Section_assert_stmt(self): + self._section_test('Section assert_stmt') +## def xxx_test_Section_list_comps(self): +## self._section_test('Section list_comps') + + +def details(section): + diff = app_level_diff.compare(testit.objspace(), filename, section) + print diff + +if __name__ == '__main__': + testit.main() Added: pypy/trunk/src/pypy/scripttest/test/test_tutorial.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/test/test_tutorial.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1,34 @@ +import autopath +import os, os.path +from pypy.tool import testit, app_level_diff + +filename = os.path.join(os.path.dirname(__file__), os.pardir, 'tutorial.py') + +# Test the functionallity of Guido's tutorial + +class TestTutorial(testit.IntTestCase): + def setUp(self): + self.space = testit.objspace() + def _section_test(self, section): + diff = app_level_diff.compare(self.space, filename, section) + if diff: + raise AssertionError('Tutorial test failed - ' \ + "run test_tutorial.details('%s')" % section) + def test_Section_2_1_2(self): + self._section_test('Section 2.1.2') + def test_Section_3_1_1a(self): + self._section_test('Section 3.1.1a') +## def xxx_test_Section_3_1_1b(self): +## self._section_test('Section 3.1.1b') +## def xxx_test_Section_3_1_1c(self): +## self._section_test('Section 3.1.1c') + def test_Section_3_1_2(self): + self._section_test('Section 3.1.2') + + +def details(section): + diff = app_level_diff.compare(testit.objspace(), filename, section) + print diff + +if __name__ == '__main__': + testit.main() Added: pypy/trunk/src/pypy/scripttest/tutorial.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/tutorial.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1,137 @@ +"""Run code from Guido's Tutorial, to make sure it works under PyPy. + +Note that as a script, we have to explicitly print stuff to see it. +""" + +##! Section 2.1.2 + +the_world_is_flat = 1 + +if the_world_is_flat: + print "Be careful not to fall off!" + +print +##! Section 3.1.1a + +print repr(2+2) +print repr((50-5*6)/4) +print repr(7/3) +print repr(7/-3) + +width = 20 +height = 5*9 +print repr(width * height) + +x = y = z = 0 # Zero x, y and z +print repr(x) +print repr(y) +print repr(z) + + +print repr(3 * 3.75 / 1.5) +print repr(7.0 / 2) + +print +##! Section 3.1.1b + +print repr(1j * 1J) + +print repr(1j * complex(0,1)) +print repr(3+1j*3) +print repr((3+1j)*3) +print repr((1+2j)/(1+1j)) + +a=1.5+0.5j +print repr(a.real) +print repr(a.imag) + +a=3.0+4.0j +try: + print repr(float(a)) +except TypeError: + print "Got TypeError for repr(float(a))" +print repr(a.real) +print repr(a.imag) +print repr(abs(a)) + +print +##! Section 3.1.1c + +#Mock up '_' variable use +tax = 12.5 / 100 +price = 100.50 +print repr(price * tax) +_ = price * tax +print repr(price + _) +_ = price + _ +print repr(round(_, 2)) + +print +##! Section 3.1.2 + +print repr('spam eggs') +print repr('doesn\'t') +print repr("doesn't") +print repr('"Yes," he said.') +print repr("\"Yes,\" he said.") +print repr('"Isn\'t," she said.') + +hello = "This is a rather long string containing\n\ +several lines of text just as you would do in C.\n\ + Note that whitespace at the beginning of the line is\ + significant." +print hello +hello = r"This is a rather long string containing\n\ +several lines of text much as you would do in C." +print hello +print """ +Usage: thingy [OPTIONS] + -h Display this usage message + -H hostname Hostname to connect to +""" + +word = 'Help' + 'A' +print repr(word) +print repr('<' + word*5 + '>') +print repr('str' 'ing') +print repr('str'.strip() + 'ing') +print repr(word[4]) +print repr(word[0:2]) +print repr(word[2:4]) +print repr(word[:2]) +print repr(word[2:]) + +try: + word[0] = 'x' +except TypeError: + print "Got a TypeError with word[0] = 'x'" +try: + word[:1] = 'Splat' +except TypeError: + print "Got a TypeError with word[:1] = 'Splat'" +print repr('x' + word[1:]) +print repr('Splat' + word[4]) +print repr(word[:2] + word[2:]) +print repr(word[:3] + word[3:]) + +print repr(word[1:100]) +print repr(word[10:]) +print repr(word[2:1]) +print repr(word[-1]) +print repr(word[-2]) +print repr(word[-2:]) +print repr(word[:-2]) +print repr(word[-0]) + +print repr(word[-100:]) +try: + print repr(word[-10]) +except IndexError: + print "Got IndexError with word[-10]" + +s = 'supercalifragilisticexpialidocious' +print repr(len(s)) + +print +##! Section 3.1.3 + Added: pypy/trunk/src/pypy/scripttest/tutorial.txt ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/scripttest/tutorial.txt Sun Jun 27 22:53:28 2004 @@ -0,0 +1,78 @@ +##! Section 2.1.2 +Be careful not to fall off! + +##! Section 3.1.1a +4 +5 +2 +-3 +900 +0 +0 +0 +7.5 +3.5 + +##! Section 3.1.1b +(-1+0j) +(-1+0j) +(3+3j) +(9+3j) +(1.5+0.5j) +1.5 +0.5 +Got TypeError for repr(float(a)) +3.0 +4.0 +5.0 + +##! Section 3.1.1c +12.5625 +113.0625 +113.06 + +##! Section 3.1.2 +'spam eggs' +"doesn't" +"doesn't" +'"Yes," he said.' +'"Yes," he said.' +'"Isn\'t," she said.' +This is a rather long string containing +several lines of text just as you would do in C. + Note that whitespace at the beginning of the line is significant. +This is a rather long string containing\n\ +several lines of text much as you would do in C. + +Usage: thingy [OPTIONS] + -h Display this usage message + -H hostname Hostname to connect to + +'HelpA' +'' +'string' +'string' +'A' +'He' +'lp' +'He' +'lpA' +Got a TypeError with word[0] = 'x' +Got a TypeError with word[:1] = 'Splat' +'xelpA' +'SplatA' +'HelpA' +'HelpA' +'elpA' +'' +'' +'A' +'p' +'pA' +'Hel' +'H' +'HelpA' +Got IndexError with word[-10] +34 + +##! Section 3.1.3 Added: pypy/trunk/src/pypy/tool/app_level_diff.py ============================================================================== --- (empty file) +++ pypy/trunk/src/pypy/tool/app_level_diff.py Sun Jun 27 22:53:28 2004 @@ -0,0 +1,123 @@ +import autopath +import difflib + +leadincode = """ +import sys + +class PseudoOut: + def __init__(self): + self.out = [] + def flush(self): + pass + def write(self, item): + self.out.append(str(item)) + def writelines(self, items): + for item in items: + self.out.append(str(item)) + def getoutput(self): + '''Not part of the output stream interface.''' + return ''.join(self.out) + +out = PseudoOut() + +oldout, sys.stdout = sys.stdout, out +olderr, sys.stderr = sys.stderr, out +""" + +cleanupcode = """ +sys.stdout = oldout +sys.stderr = olderr + +retval = out.getoutput() +""" + +def runcode(space, source, filename, w_glob): + w = space.wrap + w_compile = space.getitem(space.builtin.w_dict, w('compile')) + w_code = space.call_function(w_compile, w(source), w(filename), w('exec')) + pycode = space.unwrap(w_code) + pycode.exec_code(space, w_glob, w_glob) + +def getoutput(space, source, filename): + w_bookendglobals = space.newdict([]) + runcode(space, leadincode, '', 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 arigo at codespeak.net Mon Jun 28 14:46:19 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 28 Jun 2004 14:46:19 +0200 (MEST) Subject: [pypy-svn] r5380 - in pypy/trunk/src/pypy/objspace: flow/test std Message-ID: <20040628124619.A14695ABB4@thoth.codespeak.net> Author: arigo Date: Mon Jun 28 14:46:18 2004 New Revision: 5380 Modified: pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py pypy/trunk/src/pypy/objspace/std/dictobject.py Log: translate_pypy progress. * a test for using global constant data * removed checks in dictobject.py that confused FlowObjSpace We should figure out a way for the FlowObjSpace to optionally ignore the 'assert' statements. It's not obvious unless the whole process is run in -O but then we loose the interesting asserts in FlowObjSpace and annotation themselves... Modified: pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/trunk/src/pypy/objspace/flow/test/test_objspace.py Mon Jun 28 14:46:18 2004 @@ -257,6 +257,18 @@ x = self.codetest(self.dellocal) self.show(x) + #__________________________________________________________ + def globalconstdict(name): + x = DATA['x'] + z = DATA[name] + return x, z + + def test_globalconstdict(self): + x = self.codetest(self.globalconstdict) + self.show(x) + +DATA = {'x': 5, + 'y': 6} if __name__ == '__main__': testit.main() 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 Mon Jun 28 14:46:18 2004 @@ -73,16 +73,13 @@ freeslot = None perturb = lookup_hash - if __debug__: - c = len(self.data) + 99 + ##c = len(self.data) + 99 while 1: - if __debug__: - c -= 1 - if not c: - import sys, pdb - print >> sys.stderr, 'dict lookup lost in infinite loop' - pdb.set_trace() - + ##c -= 1 + ##if not c: + ## import sys, pdb + ## print >> sys.stderr, 'dict lookup lost in infinite loop' + ## pdb.set_trace() i = (i << 2) + i + perturb + 1 entry = self.data[i%len(self.data)] if entry[1] is None: From arigo at codespeak.net Mon Jun 28 14:49:18 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 28 Jun 2004 14:49:18 +0200 (MEST) Subject: [pypy-svn] r5381 - pypy/trunk/src/pypy/annotation Message-ID: <20040628124918.3B1FF5ABB4@thoth.codespeak.net> Author: arigo Date: Mon Jun 28 14:49:17 2004 New Revision: 5381 Modified: pypy/trunk/src/pypy/annotation/factory.py Log: progress for translate_pypy. Modified: pypy/trunk/src/pypy/annotation/factory.py ============================================================================== --- pypy/trunk/src/pypy/annotation/factory.py (original) +++ pypy/trunk/src/pypy/annotation/factory.py Mon Jun 28 14:49:17 2004 @@ -156,7 +156,9 @@ self.instancefactories = {} self.cls = cls self.subdefs = {} - assert len(cls.__bases__) <= 1, "single inheritance only right now" + assert (len(cls.__bases__) <= 1 or + cls.__bases__[1:] == (object,), # for baseobjspace.Wrappable + "single inheritance only right now: %r" % (cls,)) if cls.__bases__: base = cls.__bases__[0] else: From arigo at codespeak.net Mon Jun 28 17:53:50 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 28 Jun 2004 17:53:50 +0200 (MEST) Subject: [pypy-svn] r5384 - in pypy/trunk/src: goal goal/translate_pypy pypy/translator/tool/pygame Message-ID: <20040628155350.84AAE5ABB4@thoth.codespeak.net> Author: arigo Date: Mon Jun 28 17:53:49 2004 New Revision: 5384 Added: pypy/trunk/src/goal/translate_pypy/ (props changed) pypy/trunk/src/goal/translate_pypy/autopath.py - copied, changed from r5382, pypy/trunk/src/goal/autopath.py pypy/trunk/src/goal/translate_pypy/func.html pypy/trunk/src/goal/translate_pypy/graphserver.py (contents, props changed) pypy/trunk/src/goal/translate_pypy/httpserver.py (contents, props changed) pypy/trunk/src/goal/translate_pypy/index.html pypy/trunk/src/goal/translate_pypy/translate_pypy.py - copied, changed from r5382, pypy/trunk/src/goal/translate_pypy.py Removed: pypy/trunk/src/goal/translate_pypy.py Modified: pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py Log: A quick HTTP hack to view the graphs and annotations computed by translate_pypy.py. Deleted: /pypy/trunk/src/goal/translate_pypy.py ============================================================================== --- /pypy/trunk/src/goal/translate_pypy.py Mon Jun 28 17:53:49 2004 +++ (empty file) @@ -1,36 +0,0 @@ -# -# -# - -import autopath - -from pypy.objspace.std.objspace import StdObjSpace, W_Object -from pypy.objspace.std.intobject import W_IntObject -from pypy.translator.translator import Translator - - -# __________ Entry point __________ - -space = StdObjSpace() - -def entry_point(): - w_a = W_IntObject(space, -6) - w_b = W_IntObject(space, -7) - return space.mul(w_a, w_b) - - -# __________ Main __________ - -if __name__ == '__main__': - t = Translator(entry_point, verbose=True, simplifying=True) - try: - a = t.annotate([]) - #a.simplify() - except: - import sys, traceback - exc, val, tb = sys.exc_info() - print >> sys.stderr - traceback.print_exception(exc, val, tb) - print >> sys.stderr - import pdb - pdb.post_mortem(tb) Copied: pypy/trunk/src/goal/translate_pypy/autopath.py (from r5382, pypy/trunk/src/goal/autopath.py) ============================================================================== --- pypy/trunk/src/goal/autopath.py (original) +++ pypy/trunk/src/goal/translate_pypy/autopath.py Mon Jun 28 17:53:49 2004 @@ -1,2 +1,6 @@ import sys, os -sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +sys.path.insert(0, + os.path.dirname( + os.path.dirname( + os.path.dirname( + os.path.abspath(__file__))))) Added: pypy/trunk/src/goal/translate_pypy/func.html ============================================================================== --- (empty file) +++ pypy/trunk/src/goal/translate_pypy/func.html Mon Jun 28 17:53:49 2004 @@ -0,0 +1,24 @@ + + + + + + + +

Variables: +%( +for n, rect, text in zones: + print '' % s2 + print s1 + print '' +)s + +

+ + + Added: pypy/trunk/src/goal/translate_pypy/graphserver.py ============================================================================== --- (empty file) +++ pypy/trunk/src/goal/translate_pypy/graphserver.py Mon Jun 28 17:53:49 2004 @@ -0,0 +1,78 @@ +import BaseHTTPServer +from cStringIO import StringIO +import httpserver +from pypy.translator.tool.pygame.graphviewer import GraphViewer +from pypy.translator.tool.make_dot import make_dot_graphs + + +class Server: + + def __init__(self, translator): + self.translator = translator + self.viewercache = {} + self.binding_by_name = {} + for var, s_value in self.translator.annotator.bindings.items(): + self.binding_by_name[var.name] = '%s : %r' % (var.name, s_value) + + def getviewer(self, i): + t = self.translator + func = t.functions[i] + if func in self.viewercache: + return self.viewercache[func] + name = '%s_%d' % (func.__name__, i) + graph = t.getflowgraph(func) + graphs = [(graph.name, graph)] + xdotfile = str(make_dot_graphs(name, graphs, target='xdot')) + pngfile = str(make_dot_graphs(name, graphs, target='png')) + viewer = GraphViewer(xdotfile, pngfile) + zones = [] + for (x,y,w,h), name in viewer.getzones(): + if name in self.binding_by_name: + zones.append((name, (x,y,x+w,y+h), self.binding_by_name[name])) + result = zones, pngfile + self.viewercache[func] = result + return result + + def indexloader(self, **options): + t = self.translator + return httpserver.load('index.html', 'text/html', {'t': t}) + + def funcloader(self, i, **options): + i = int(i[0]) + zones, pngfile = self.getviewer(i) + t = self.translator + return httpserver.load('func.html', 'text/html', + {'t': t, + 'zones': zones, + 'img': 'img?i=%d' % i, + }) + + def imgloader(self, i, **options): + i = int(i[0]) + zones, pngfile = self.getviewer(i) + return open(pngfile, 'rb'), 'image/png' + + def varloader(self, n, **options): + n = n[0] + import textwrap + data = textwrap.fill(self.binding_by_name[n]) + data = '=== %s ===\n\n%s' % (n, data) + return StringIO(data), 'text/plain' + + def serve(self): + httpserver.register('', self.indexloader) + httpserver.register('func', self.funcloader) + httpserver.register('img', self.imgloader) + httpserver.register('var', self.varloader) + BaseHTTPServer.test(HandlerClass=httpserver.MiniHandler) + +# ____________________________________________________________ + +if __name__ == '__main__': + from pypy.translator.translator import Translator + from pypy.translator.test import snippet + t = Translator(snippet.sieve_of_eratosthenes) + t.simplify() + a = t.annotate([]) + a.simplify() + Server(t).serve() Added: pypy/trunk/src/goal/translate_pypy/httpserver.py ============================================================================== --- (empty file) +++ pypy/trunk/src/goal/translate_pypy/httpserver.py Mon Jun 28 17:53:49 2004 @@ -0,0 +1,175 @@ +from __future__ import generators +from __future__ import nested_scopes +import BaseHTTPServer +from SimpleHTTPServer import SimpleHTTPRequestHandler +import urlparse, cgi, htmlentitydefs +import sys, os, time +from cStringIO import StringIO + + +class Translator: + """For use with format strings. + + 'formatstring % translator' will evaluate all %(xxx)s expressions + found in the format string in the given globals/locals. + + Multiline expressions are assumed to be one or several complete + statements; they are executed and whatever they print is inserted back + into the format string.""" + + def __init__(self, globals, locals): + self.globals = globals + self.locals = locals + + def __getitem__(self, expr): + if '\n' in expr: + if not expr.endswith('\n'): + expr += '\n' + prevstdout = sys.stdout + try: + sys.stdout = f = StringIO() + exec expr in self.globals, self.locals + finally: + sys.stdout = prevstdout + return f.getvalue() + else: + return eval(expr, self.globals, self.locals) + +class TranslatorIO: + "Lazy version of Translator." + + def __init__(self, fmt, d): + self.gen = self.generate(fmt, d) + + def read(self, ignored=None): + for text in self.gen: + if text: + return text + return '' + + def close(self): + self.gen = () + + def generate(self, fmt, d): + t = Translator(d, d) + for data in fmt.split('\x0c'): + yield data % t + + +# HTML quoting + +text_to_html = {} +for key, value in htmlentitydefs.entitydefs.items(): + text_to_html[value] = '&' + key + ';' + +def htmlquote(s): + return ''.join([text_to_html.get(c, c) for c in s]) + + +# HTTP Request Handler + +pathloaders = {} + +def canonicalpath(url): + if url.startswith('/'): + url = url[1:] + return url.lower() + +def register(url, loader): + pathloaders[canonicalpath(url)] = loader + +def is_registered(url): + return canonicalpath(url) in pathloaders + +def load(filename, mimetype=None, locals=None): + if mimetype and mimetype.startswith('text/'): + mode = 'r' + else: + mode = 'rb' + f = open(filename, mode) + if locals is not None: + data = f.read() + f.close() + #data = data.replace('%"', '%%"') + d = globals().copy() + d.update(locals) + f = TranslatorIO(data, d) + return f, mimetype + +def fileloader(filename, mimetype=None): + def loader(**options): + return load(filename, mimetype) + return loader + +class HTTPRequestError(Exception): + pass + +class MiniHandler(SimpleHTTPRequestHandler): + + def send_head(self, query=''): + addr, host, path, query1, fragment = urlparse.urlsplit(self.path) + path = canonicalpath(path) + if path not in pathloaders: + if path + '/' in pathloaders: + return self.redirect(path + '/') + self.send_error(404) + return None + kwds = {} + for q in [query1, query]: + if q: + kwds.update(cgi.parse_qs(q)) + loader = pathloaders[path] + try: + hdr = self.headers + hdr['remote host'] = self.client_address[0] + f, ctype = loader(headers=hdr, **kwds) + except IOError, e: + self.send_error(404, "I/O error: " + str(e)) + return None + except HTTPRequestError, e: + self.send_error(500, str(e)) + return None + except: + f = StringIO() + import traceback + traceback.print_exc(file=f) + data = htmlquote(f.getvalue()) + data = data.replace('\n', '
\n') + self.send_error(500) + return StringIO('

'+data+'

') + if ctype is None: + ctype = self.guess_type(self.translate_path(self.path)) + elif f is None: + return self.redirect(ctype) + + self.send_response(200) + self.send_header("Content-type", ctype) + self.end_headers() + return f + + def redirect(self, url): + self.send_response(302) + self.send_header("Content-type", 'text/html') + self.send_header("Location", url) + self.end_headers() + return StringIO(''' +Please click here to continue. + +''' % url) + + def do_POST(self): + try: + nbytes = int(self.headers.getheader('content-length')) + except: + nbytes = 0 + query = self.rfile.read(nbytes).strip() + f = self.send_head(query) + if f: + self.copyfile(f, self.wfile) + f.close() + + +def my_host(): + import gamesrv + port = gamesrv.socketports[gamesrv.openhttpsocket()] + return '127.0.0.1:%d' % port Added: pypy/trunk/src/goal/translate_pypy/index.html ============================================================================== --- (empty file) +++ pypy/trunk/src/goal/translate_pypy/index.html Mon Jun 28 17:53:49 2004 @@ -0,0 +1,16 @@ + +Functions +

Functions

+ +%( +for i, func in zip(range(len(t.functions)), t.functions): + print "" +)s +
 " + print "%s:%d" % (htmlquote(func.func_globals.get('__name__', '?')), + func.func_code.co_firstlineno) + print "  " % i + print htmlquote(func.__name__) + print " 
+ + Copied: pypy/trunk/src/goal/translate_pypy/translate_pypy.py (from r5382, pypy/trunk/src/goal/translate_pypy.py) ============================================================================== --- pypy/trunk/src/goal/translate_pypy.py (original) +++ pypy/trunk/src/goal/translate_pypy/translate_pypy.py Mon Jun 28 17:53:49 2004 @@ -1,7 +1,6 @@ # # # - import autopath from pypy.objspace.std.objspace import StdObjSpace, W_Object @@ -27,10 +26,14 @@ a = t.annotate([]) #a.simplify() except: - import sys, traceback + import sys, traceback, thread exc, val, tb = sys.exc_info() print >> sys.stderr traceback.print_exception(exc, val, tb) print >> sys.stderr + import graphserver + def bkgnd_server(): + graphserver.Server(t).serve() + thread.start_new_thread(bkgnd_server, ()) import pdb pdb.post_mortem(tb) Modified: pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py ============================================================================== --- pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py (original) +++ pypy/trunk/src/pypy/translator/tool/pygame/graphviewer.py Mon Jun 28 17:53:49 2004 @@ -1,3 +1,4 @@ +from __future__ import generators import autopath import sys, os, re import pygame @@ -91,6 +92,20 @@ return word, text, name return None, None, None + def getzones(self, re_nonword=re.compile(r'(\W+)')): + for (rx,ry,rw,rh), originalw, text, name in self.positions: + words = [s for s in re_nonword.split(text) if s] + segment = '' + dx1 = 0 + for word in words: + segment += word + img = self.font.render(segment, 1, (255, 0, 0)) + w, h = img.get_size() + dx2 = int(float(w) * originalw / rw) + if word.strip(): + yield (rx+dx1, ry, dx2-dx1, rh), word + dx1 = dx2 + def parse_xdot_output(self, lines): for i in range(len(lines)): if lines[i].endswith('\\\n'): From arigo at codespeak.net Tue Jun 29 14:37:07 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 29 Jun 2004 14:37:07 +0200 (MEST) Subject: [pypy-svn] r5388 - in pypy/trunk/src: goal/translate_pypy pypy/interpreter pypy/objspace/std Message-ID: <20040629123707.066855A8B6@thoth.codespeak.net> Author: arigo Date: Tue Jun 29 14:37:07 2004 New Revision: 5388 Modified: pypy/trunk/src/goal/translate_pypy/index.html pypy/trunk/src/goal/translate_pypy/translate_pypy.py pypy/trunk/src/pypy/interpreter/baseobjspace.py pypy/trunk/src/pypy/interpreter/typedef.py pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/std/objspace.py Log: More on translate_pypy.py. It no longer crashes -- though it doesn't translate PyPy yet: it only analyzes a small bit of it. Got rid of the placeholder class UserSubclass which was giving trouble as expected. Moved the equivalent functionality into a root class "W_Root", base of all wrapped objects in the StdObjSpace (both Wrappables and W_Objects). Debugging helper function: about(x) in translate_pypy.py. Modified: pypy/trunk/src/goal/translate_pypy/index.html ============================================================================== --- pypy/trunk/src/goal/translate_pypy/index.html (original) +++ pypy/trunk/src/goal/translate_pypy/index.html Tue Jun 29 14:37:07 2004 @@ -7,9 +7,10 @@ print " " print "%s:%d" % (htmlquote(func.func_globals.get('__name__', '?')), func.func_code.co_firstlineno) - print "  " % i - print htmlquote(func.__name__) - print " " + print "  " + print "%s" % (i, + htmlquote(func.__name__)) + print " " )s Modified: pypy/trunk/src/goal/translate_pypy/translate_pypy.py ============================================================================== --- pypy/trunk/src/goal/translate_pypy/translate_pypy.py (original) +++ pypy/trunk/src/goal/translate_pypy/translate_pypy.py Tue Jun 29 14:37:07 2004 @@ -21,19 +21,45 @@ # __________ Main __________ if __name__ == '__main__': + + def about(x): + """ interactive debugging helper """ + from pypy.objspace.flow.model import Block, flatten + if isinstance(x, Block): + for func, graph in t.flowgraphs.items(): + if x in flatten(graph): + print x + print 'is a block in the graph of' + print func + print 'at %s:%d' % (func.func_globals.get('__name__', '?'), + func.func_code.co_firstlineno) + break + else: + print x + print 'is a block at some unknown location' + print 'containing the following operations:' + for op in x.operations: + print op + print '--end--' + return + print "don't know about", x + + import graphserver + def run_server(): + graphserver.Server(t).serve() + t = Translator(entry_point, verbose=True, simplifying=True) try: a = t.annotate([]) - #a.simplify() + a.simplify() except: import sys, traceback, thread exc, val, tb = sys.exc_info() print >> sys.stderr traceback.print_exception(exc, val, tb) print >> sys.stderr - import graphserver - def bkgnd_server(): - graphserver.Server(t).serve() - thread.start_new_thread(bkgnd_server, ()) + thread.start_new_thread(run_server, ()) import pdb pdb.post_mortem(tb) + else: + run_server() Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/src/pypy/interpreter/baseobjspace.py Tue Jun 29 14:37:07 2004 @@ -3,14 +3,21 @@ from pypy.interpreter.miscutils import getthreadlocals from pypy.interpreter.argument import Arguments -__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable'] +__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable', + 'W_Root'] -class BaseWrappable: - """A subclass of BaseWrappable is an internal, interpreter-level class - that can nevertheless be exposed at application-level by space.wrap().""" +class W_Root: + """This is the abstract root class of all wrapped objects that live + in a 'normal' object space like StdObjSpace.""" def getdict(self): return None + def getclass(self, space): + return space.gettypeobject(self.typedef) + +class BaseWrappable(W_Root): + """A subclass of BaseWrappable is an internal, interpreter-level class + that can nevertheless be exposed at application-level by space.wrap().""" def __spacebind__(self, space): return self Modified: pypy/trunk/src/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/src/pypy/interpreter/typedef.py (original) +++ pypy/trunk/src/pypy/interpreter/typedef.py Tue Jun 29 14:37:07 2004 @@ -25,7 +25,7 @@ class User_InsertNameHere(object): - def getclass(self): + def getclass(self, space): return self.w__class__ def setclass(self, w_subtype): @@ -54,13 +54,10 @@ self.w__dict__ = space.newdict([]) body = dict(User_InsertNameHere.__dict__.items()) - subcls = type(name, (cls, UserSubclass), body) + subcls = type(name, (cls,), body) unique_interplevel_subclass_cache[cls] = subcls return subcls -class UserSubclass(object): - pass # XXX this should probably not exist - def instantiate(cls): "Create an empty instance of 'cls'." if isinstance(cls, type): Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Tue Jun 29 14:37:07 2004 @@ -41,6 +41,27 @@ """ representation for debugging purposes """ return "cpyobj(%r)" % (w_self.cpyobj,) + def getclass(w_self, space): + return space.wrap(w_self.cpyobj.__class__) + + 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) 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 Tue Jun 29 14:37:07 2004 @@ -1,14 +1,14 @@ from pypy.objspace.std.register_all import register_all from pypy.interpreter.baseobjspace import * from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.interpreter.typedef import instantiate, UserSubclass +from pypy.interpreter.typedef import instantiate from pypy.objspace.std.multimethod import * from pypy.objspace.descroperation import DescrOperation from pypy.objspace.std import stdtypedef import types -class W_Object(object): +class W_Object(W_Root, object): "Parent base class for wrapped objects." typedef = None @@ -25,9 +25,6 @@ s += ' instance of %s' % self.w__class__ return '<%s>' % s - def getdict(self): - return None - # delegation priorities PRIORITY_SAME_TYPE = 2 # converting between several impls of the same type PRIORITY_PARENT_TYPE = 1 # converting to a base type (e.g. bool -> int) @@ -290,26 +287,11 @@ return W_SeqIterObject(self, w_obj) def type(self, w_obj): - if isinstance(w_obj, UserSubclass): - return w_obj.getclass() - elif isinstance(w_obj, W_CPythonObject): - #raise TypeError, str(w_obj.cpyobj) - return self.wrap(type(w_obj.cpyobj)) - else: - assert w_obj.typedef, w_obj - return self.gettypeobject(w_obj.typedef) + return w_obj.getclass(self) def lookup(self, w_obj, name): - if not isinstance(w_obj, W_CPythonObject): - # usual case - w_type = self.type(w_obj) - return w_type.lookup(name) - else: - # hack - for cls in type(w_obj.cpyobj).__mro__: - if name in cls.__dict__: - return self.wrap(cls.__dict__[name]) - return None + w_type = w_obj.getclass(self) + return w_type.lookup(name) def allocate_instance(self, cls, w_subtype): """Allocate the memory needed for an instance of an internal or From arigo at codespeak.net Tue Jun 29 16:31:39 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 29 Jun 2004 16:31:39 +0200 (MEST) Subject: [pypy-svn] r5389 - pypy/trunk/src/pypy/objspace/std Message-ID: <20040629143139.474CB5A8B6@thoth.codespeak.net> Author: arigo Date: Tue Jun 29 16:31:38 2004 New Revision: 5389 Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py Log: not all CPython objects have a __class__ attribute. Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Tue Jun 29 16:31:38 2004 @@ -42,7 +42,10 @@ return "cpyobj(%r)" % (w_self.cpyobj,) def getclass(w_self, space): - return space.wrap(w_self.cpyobj.__class__) + try: + return space.wrap(w_self.cpyobj.__class__) + except AttributeError: # no __class__! + return space.wrap(type(w_self.cpyobj)) def lookup(w_self, name): # hack for wrapped CPython types From hpk at codespeak.net Tue Jun 29 19:03:41 2004 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 29 Jun 2004 19:03:41 +0200 (MEST) Subject: [pypy-svn] r5391 - pypy/trunk/src/pypy/objspace/std/test Message-ID: <20040629170341.E4F5C5A8B6@thoth.codespeak.net> Author: hpk Date: Tue Jun 29 19:03:34 2004 New Revision: 5391 Modified: pypy/trunk/src/pypy/objspace/std/test/test_restricted_int.py Log: fix masking with maxint-stuff for 64-bit machines Modified: pypy/trunk/src/pypy/objspace/std/test/test_restricted_int.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/test/test_restricted_int.py (original) +++ pypy/trunk/src/pypy/objspace/std/test/test_restricted_int.py Tue Jun 29 19:03:34 2004 @@ -2,6 +2,9 @@ import autopath from pypy.tool import testit from pypy.objspace.std.restricted_int import * +import sys + +maxint_mask = (sys.maxint*2 + 1) class Test_r_int(testit.TestCase): @@ -109,12 +112,12 @@ def unary_test(self, f): for arg in (0, 3, 12345): - res = f(arg) & 0xffffffffl + res = f(arg) & maxint_mask cmp = f(r_uint(arg)) self.assertEquals(res, cmp) def binary_test(self, f, rargs = None): - mask = 0xffffffffl + mask = maxint_mask if not rargs: rargs = (1, 3, 55) for larg in (0, 1, 2, 3, 1234): From arigo at codespeak.net Tue Jun 29 19:06:01 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 29 Jun 2004 19:06:01 +0200 (MEST) Subject: [pypy-svn] r5392 - pypy/trunk/src/pypy/objspace Message-ID: <20040629170601.0294B5A8B6@thoth.codespeak.net> Author: arigo Date: Tue Jun 29 19:05:59 2004 New Revision: 5392 Modified: pypy/trunk/src/pypy/objspace/trivial.py Log: Killed commented-out lines in trivial.py. Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Tue Jun 29 19:05:59 2004 @@ -208,7 +208,7 @@ return space.set(w_descr, w_obj, w_value) def fdel(w_obj, descr=descr, space=self): w_descr = space.wrap(descr) - return space.set(w_descr, w_obj) + return space.delete(w_descr, w_obj) descrdict[descrname] = property(fget, fset, fdel) cls = type('CPyWrapped '+typedef.name, bases, descrdict) typedef.trivialwrapperclass = cls @@ -302,119 +302,6 @@ else: return DescrOperation.iter(self, w_obj) -# for _name in ('id', 'type', 'iter', 'repr', 'str', 'len', -# 'pow', 'divmod', 'hash', 'setattr', 'delattr', 'hex', -# 'oct', 'ord', 'getattr'): -# _auto(_name, _name, locals()) -# - #for _name in ('pos', 'neg', 'not_', 'abs', 'invert', - # 'mul', 'truediv', 'floordiv', 'div', 'mod', - # 'add', 'sub', 'lshift', 'rshift', 'and_', 'xor', 'or_', - # 'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'contains'): - # _auto(_name, 'operator.' + _name, locals()) - - # in-place operators - #def inplace_pow(self, w1, w2): - # w1 **= w2 - # return self.wrap(w1) - #def inplace_mul(self, w1, w2): - # w1 *= w2 - # return self.wrap(w1) - #def inplace_truediv(self, w1, w2): - # w1 /= w2 # XXX depends on compiler flags - # return self.wrap(w1) - #def inplace_floordiv(self, w1, w2): - # w1 //= w2 - # return self.wrap(w1) - #def inplace_div(self, w1, w2): - # w1 /= w2 # XXX depends on compiler flags - # return self.wrap(w1) - #def inplace_mod(self, w1, w2): - # w1 %= w2 - # return self.wrap(w1) - - #def inplace_add(self, w1, w2): - # w1 += w2 - # return self.wrap(w1) - #def inplace_sub(self, w1, w2): - # w1 -= w2 - # return self.wrap(w1) - #def inplace_lshift(self, w1, w2): - # w1 <<= w2 - # return self.wrap(w1) - #def inplace_rshift(self, w1, w2): - # w1 >>= w2 - # return self.wrap(w1) - #def inplace_and(self, w1, w2): - # w1 &= w2 - # return self.wrap(w1) - #def inplace_or(self, w1, w2): - # w1 |= w2 - # return self.wrap(w1) - #def inplace_xor(self, w1, w2): - # w1 ^= w2 - # return self.wrap(w1) - - - # slicing - def old_slice(self, 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(self, w_obj, w_index): -## obj = self.unwrap(w_obj) -## index = self.unwrap(w_index) -## sindex = self.old_slice(index) -## try: -## if sindex is None: -## return self.wrap(obj[index]) -## else: -## return self.wrap(operator.getslice(obj, sindex[0], sindex[1])) -## except: -## self.reraise() - -## def setitem(self, w_obj, w_index, w_value): -## obj = self.unwrap(w_obj) -## index = self.unwrap(w_index) -## value = self.unwrap(w_value) -## sindex = self.old_slice(index) -## try: -## if sindex is None: -## obj[index] = value -## else: -## operator.setslice(obj, sindex[0], sindex[1], value) -## except: -## self.reraise() - -## def delitem(self, w_obj, w_index): -## obj = self.unwrap(w_obj) -## index = self.unwrap(w_index) -## sindex = self.old_slice(index) -## try: -## if sindex is None: -## del obj[index] -## else: -## operator.delslice(obj, sindex[0], sindex[1]) -## except: -## self.reraise() - - # misc - #def next(self, w): - # if hasattr(w, 'pypy_next'): - # return w.pypy_next() - # try: - # return self.wrap(w.next()) - # except StopIteration: - # raise NoValue - def newstring(self, asciilist): try: return ''.join([chr(ascii) for ascii in asciilist]) @@ -427,65 +314,6 @@ except: self.reraise() - #def call(self, callable, args, kwds): - # if isinstance(callable, types.ClassType): - # import new - # try: - # r = new.instance(callable) - # except: - # self.reraise() - # if hasattr(r, '__init__'): - # self.call(r.__init__, args, kwds) - # return self.wrap(r) - # #if (isinstance(callable, types.MethodType) - # and callable.im_self is not None): - # args = (callable.im_self,) + args - # callable = callable.im_func - # assert not isinstance(callable, gateway.Gateway), ( - # "trivial object space is detecting an object that has not " - # "been wrapped") - # if hasattr(callable, 'pypy_call'): - # return callable.pypy_call(args, kwds) - # try: - # return self.wrap(callable(*args, **(kwds or {}))) - # except OperationError: - # raise - # except: - # #print "got exception in", callable.__name__ - # #print "len args", len(args) - # #print "kwds", kwds - # self.reraise() - # - #def get(self, descr, ob, cls): - # try: - # return self.wrap(descr.__get__(ob, cls)) - # except: - # self.reraise() - - def new(self, type, args, kw): - return self.wrap(type(args, kw)) - - def init(self, type, args, kw): - pass - - #def set(self, descr, ob, val): - # descr.__set__(ob, val) - - #def delete(self, descr, ob): - # descr.__delete__(ob) - - #def nonzero(self, ob): - # return not not ob - - #def float(self, ob): - # return float(ob) - - #def int(self, ob): - # return int(ob) - - #def round(self, *args): - # return round(*args) - def lookup(space, w_obj, name): assert not isinstance(w_obj, BaseWrappable) if isinstance(w_obj, CPyWrapper): From arigo at codespeak.net Wed Jun 30 13:01:52 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 30 Jun 2004 13:01:52 +0200 (MEST) Subject: [pypy-svn] r5407 - pypy/trunk/src/pypy/appspace Message-ID: <20040630110152.0D1A05B260@thoth.codespeak.net> Author: arigo Date: Wed Jun 30 13:01:51 2004 New Revision: 5407 Modified: pypy/trunk/src/pypy/appspace/operator.py Log: Removed the staticmethod hack. People should not use built-in functions as never-bound methods. Modified: pypy/trunk/src/pypy/appspace/operator.py ============================================================================== --- pypy/trunk/src/pypy/appspace/operator.py (original) +++ pypy/trunk/src/pypy/appspace/operator.py Wed Jun 30 13:01:51 2004 @@ -161,10 +161,3 @@ 'xor(a, b) -- Same as a ^ b.' return a ^ b __xor__ = xor - -# ugh: -import types as _types -for n in globals(): - v = globals()[n] - if isinstance(v, _types.FunctionType): - globals()[n] = staticmethod(v) From arigo at codespeak.net Wed Jun 30 14:20:09 2004 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 30 Jun 2004 14:20:09 +0200 (MEST) Subject: [pypy-svn] r5408 - in pypy/trunk/src/pypy/objspace: . std Message-ID: <20040630122009.A61405B260@thoth.codespeak.net> Author: arigo Date: Wed Jun 30 14:20:09 2004 New Revision: 5408 Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py pypy/trunk/src/pypy/objspace/trivial.py Log: * Quick caching hack for cpythonobject. * Keywords arguments missing in trivial.py. Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py ============================================================================== --- pypy/trunk/src/pypy/objspace/std/cpythonobject.py (original) +++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py Wed Jun 30 14:20:09 2004 @@ -36,16 +36,19 @@ 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): - try: - return space.wrap(w_self.cpyobj.__class__) - except AttributeError: # no __class__! - return space.wrap(type(w_self.cpyobj)) + 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 Modified: pypy/trunk/src/pypy/objspace/trivial.py ============================================================================== --- pypy/trunk/src/pypy/objspace/trivial.py (original) +++ pypy/trunk/src/pypy/objspace/trivial.py Wed Jun 30 14:20:09 2004 @@ -7,6 +7,7 @@ from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import * from pypy.objspace.descroperation import DescrOperation, Object +from pypy.interpreter.argument import Arguments import types, sys import __builtin__ as cpy_builtin @@ -185,11 +186,12 @@ for descrname, descr in typedef.rawdict.items(): if isinstance(descr, interp2app): def make_stuff(descr=descr, descrname=descrname, space=self): - def stuff(w_obj, *args): + def stuff(w_obj, *args, **kwds): fn = descr.get_function(space) + args = Arguments(space, list(args), kwds) try: - return space.call_function(space.wrap(fn), - w_obj, *args) + return space.call_args(space.wrap(fn), + args.prepend(w_obj)) except OperationError, e: if not hasattr(e.w_type, 'originalex'): raise # XXX